Changeset 22884 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Sep 9, 2009 9:55:47 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 52140
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/SSM.cpp
r22807 r22884 260 260 #define SSM_LOG_BYTES 16 261 261 262 /** SSMHANDLE::fCancelled value indicating that the operation has been 263 * cancelled. */ 264 #define SSMHANDLE_CANCELLED UINT32_C(0xdeadbeef) 265 /** SSMHANDLE::fCancelled value indicating no cancellation. */ 266 #define SSMHANDLE_OK UINT32_C(0x77777777) 267 262 268 263 269 /** Macro for checking the u32CRC field of a structure. … … 296 302 || pSSM->enmOp == SSMSTATE_OPEN_READ,\ 297 303 ("Invalid state %d\n", pSSM->enmOp), VERR_SSM_INVALID_STATE); 304 305 /** Checks for cancellation and returns if pending. 306 * Sets SSMHANDLE::rc to VERR_SSM_CANCELLED (if it still indicates success) and 307 * then returns SSMHANDLE::rc. (Debug logging only.) */ 308 #define SSM_CHECK_CANCELLED_RET(pSSM) \ 309 do \ 310 { \ 311 if (RT_UNLIKELY(ASMAtomicUoReadU32(&(pSSM)->fCancelled) == SSMHANDLE_CANCELLED)) \ 312 { \ 313 LogFlow(("%Rfn: Cancelled -> VERR_SSM_CANCELLED\n", __PRETTY_FUNCTION__)); \ 314 if (RT_SUCCESS((pSSM)->rc)) \ 315 (pSSM)->rc = VERR_SSM_CANCELLED; \ 316 return (pSSM)->rc; \ 317 } \ 318 } while (0) 298 319 299 320 … … 403 424 { 404 425 /** Stream/buffer manager. */ 405 SSMSTRM Strm;426 SSMSTRM Strm; 406 427 407 428 /** The VM handle. */ 408 PVM pVM;429 PVM pVM; 409 430 /** The current operation. */ 410 SSMSTATE enmOp;431 SSMSTATE enmOp; 411 432 /** What to do after save completes. (move the enum) */ 412 SSMAFTER enmAfter; 433 SSMAFTER enmAfter; 434 /** Flag indicating that the operation has been cancelled. */ 435 uint32_t volatile fCancelled; 413 436 /** The current rc of the save operation. */ 414 int rc;437 int32_t rc; 415 438 /** Number of compressed bytes left in the current data unit (V1). */ 416 uint64_t cbUnitLeftV1;439 uint64_t cbUnitLeftV1; 417 440 /** The current uncompressed offset into the data unit. */ 418 uint64_t offUnit;441 uint64_t offUnit; 419 442 420 443 /** Pointer to the progress callback function. */ 421 PFNVMPROGRESS pfnProgress;444 PFNVMPROGRESS pfnProgress; 422 445 /** User specified arguemnt to the callback function. */ 423 void *pvUser;446 void *pvUser; 424 447 /** Next completion percentage. (corresponds to offEstProgress) */ 425 unsigned uPercent;448 unsigned uPercent; 426 449 /** The position of the next progress callback in the estimated file. */ 427 uint64_t offEstProgress;450 uint64_t offEstProgress; 428 451 /** The estimated total byte count. 429 452 * (Only valid after the prep.) */ 430 uint64_t cbEstTotal;453 uint64_t cbEstTotal; 431 454 /** Current position in the estimated file. */ 432 uint64_t offEst;455 uint64_t offEst; 433 456 /** End of current unit in the estimated file. */ 434 uint64_t offEstUnitEnd;457 uint64_t offEstUnitEnd; 435 458 /** the amount of % we reserve for the 'prepare' phase */ 436 unsigned uPercentPrepare;459 unsigned uPercentPrepare; 437 460 /** the amount of % we reserve for the 'done' stage */ 438 unsigned uPercentDone;461 unsigned uPercentDone; 439 462 /** The filename, NULL if remote stream. */ 440 const char *pszFilename;463 const char *pszFilename; 441 464 442 465 union … … 801 824 802 825 /** 826 * Cleans up resources allocated by SSM on VM termination. 827 * 828 * @param pVM The VM handle. 829 */ 830 VMMR3_INT_DECL(void) SSMR3Term(PVM pVM) 831 { 832 if (pVM->ssm.s.fInitialized) 833 { 834 pVM->ssm.s.fInitialized = false; 835 RTCritSectDelete(&pVM->ssm.s.CancelCritSect); 836 } 837 } 838 839 840 /** 803 841 * Performs lazy initialization of the SSM. 804 842 * … … 817 855 NULL /*pfnSavePrep*/, ssmR3SelfSaveExec, NULL /*pfnSaveDone*/, 818 856 NULL /*pfnSavePrep*/, ssmR3SelfLoadExec, NULL /*pfnSaveDone*/); 857 858 /* 859 * Initialize the cancellation critsect now. 860 */ 861 if (RT_SUCCESS(rc)) 862 rc = RTCritSectInit(&pVM->ssm.s.CancelCritSect); 863 819 864 pVM->ssm.s.fInitialized = RT_SUCCESS(rc); 820 865 return rc; … … 2574 2619 / (100 - pSSM->uPercentDone - pSSM->uPercentPrepare); 2575 2620 } 2621 } 2622 2623 2624 /** 2625 * Makes the SSM operation cancellable or not (via SSMR3Cancel). 2626 * 2627 * @param pVM The VM handle. 2628 * @param pSSM The saved state handle. (SSMHANDLE::rc may be set.) 2629 * @param fCancellable The new state. 2630 */ 2631 static void ssmR3SetCancellable(PVM pVM, PSSMHANDLE pSSM, bool fCancellable) 2632 { 2633 RTCritSectEnter(&pVM->ssm.s.CancelCritSect); 2634 if (fCancellable) 2635 { 2636 Assert(!pVM->ssm.s.pSSM); 2637 pVM->ssm.s.pSSM = pSSM; 2638 } 2639 else 2640 { 2641 if (pVM->ssm.s.pSSM == pSSM) 2642 pVM->ssm.s.pSSM = NULL; 2643 2644 uint32_t fCancelled = ASMAtomicUoReadU32(&pSSM->fCancelled); 2645 if ( fCancelled == SSMHANDLE_CANCELLED 2646 && RT_SUCCESS(pSSM->rc)) 2647 pSSM->rc = VERR_SSM_CANCELLED; 2648 } 2649 2650 RTCritSectLeave(&pVM->ssm.s.CancelCritSect); 2576 2651 } 2577 2652 … … 2943 3018 { 2944 3019 SSM_ASSERT_WRITEABLE_RET(pSSM); 3020 SSM_CHECK_CANCELLED_RET(pSSM); 2945 3021 uint8_t u8 = fBool; /* enforce 1 byte size */ 2946 3022 return ssmR3DataWrite(pSSM, &u8, sizeof(u8)); … … 2958 3034 { 2959 3035 SSM_ASSERT_WRITEABLE_RET(pSSM); 3036 SSM_CHECK_CANCELLED_RET(pSSM); 2960 3037 return ssmR3DataWrite(pSSM, &u8, sizeof(u8)); 2961 3038 } … … 2972 3049 { 2973 3050 SSM_ASSERT_WRITEABLE_RET(pSSM); 3051 SSM_CHECK_CANCELLED_RET(pSSM); 2974 3052 return ssmR3DataWrite(pSSM, &i8, sizeof(i8)); 2975 3053 } … … 2986 3064 { 2987 3065 SSM_ASSERT_WRITEABLE_RET(pSSM); 3066 SSM_CHECK_CANCELLED_RET(pSSM); 2988 3067 return ssmR3DataWrite(pSSM, &u16, sizeof(u16)); 2989 3068 } … … 3000 3079 { 3001 3080 SSM_ASSERT_WRITEABLE_RET(pSSM); 3081 SSM_CHECK_CANCELLED_RET(pSSM); 3002 3082 return ssmR3DataWrite(pSSM, &i16, sizeof(i16)); 3003 3083 } … … 3014 3094 { 3015 3095 SSM_ASSERT_WRITEABLE_RET(pSSM); 3096 SSM_CHECK_CANCELLED_RET(pSSM); 3016 3097 return ssmR3DataWrite(pSSM, &u32, sizeof(u32)); 3017 3098 } … … 3028 3109 { 3029 3110 SSM_ASSERT_WRITEABLE_RET(pSSM); 3111 SSM_CHECK_CANCELLED_RET(pSSM); 3030 3112 return ssmR3DataWrite(pSSM, &i32, sizeof(i32)); 3031 3113 } … … 3042 3124 { 3043 3125 SSM_ASSERT_WRITEABLE_RET(pSSM); 3126 SSM_CHECK_CANCELLED_RET(pSSM); 3044 3127 return ssmR3DataWrite(pSSM, &u64, sizeof(u64)); 3045 3128 } … … 3056 3139 { 3057 3140 SSM_ASSERT_WRITEABLE_RET(pSSM); 3141 SSM_CHECK_CANCELLED_RET(pSSM); 3058 3142 return ssmR3DataWrite(pSSM, &i64, sizeof(i64)); 3059 3143 } … … 3070 3154 { 3071 3155 SSM_ASSERT_WRITEABLE_RET(pSSM); 3156 SSM_CHECK_CANCELLED_RET(pSSM); 3072 3157 return ssmR3DataWrite(pSSM, &u128, sizeof(u128)); 3073 3158 } … … 3084 3169 { 3085 3170 SSM_ASSERT_WRITEABLE_RET(pSSM); 3171 SSM_CHECK_CANCELLED_RET(pSSM); 3086 3172 return ssmR3DataWrite(pSSM, &i128, sizeof(i128)); 3087 3173 } … … 3098 3184 { 3099 3185 SSM_ASSERT_WRITEABLE_RET(pSSM); 3186 SSM_CHECK_CANCELLED_RET(pSSM); 3100 3187 return ssmR3DataWrite(pSSM, &u, sizeof(u)); 3101 3188 } … … 3112 3199 { 3113 3200 SSM_ASSERT_WRITEABLE_RET(pSSM); 3201 SSM_CHECK_CANCELLED_RET(pSSM); 3114 3202 return ssmR3DataWrite(pSSM, &i, sizeof(i)); 3115 3203 } … … 3128 3216 { 3129 3217 SSM_ASSERT_WRITEABLE_RET(pSSM); 3218 SSM_CHECK_CANCELLED_RET(pSSM); 3130 3219 return ssmR3DataWrite(pSSM, &u, sizeof(u)); 3131 3220 } … … 3142 3231 { 3143 3232 SSM_ASSERT_WRITEABLE_RET(pSSM); 3233 SSM_CHECK_CANCELLED_RET(pSSM); 3144 3234 return ssmR3DataWrite(pSSM, &u, sizeof(u)); 3145 3235 } … … 3156 3246 { 3157 3247 SSM_ASSERT_WRITEABLE_RET(pSSM); 3248 SSM_CHECK_CANCELLED_RET(pSSM); 3158 3249 return ssmR3DataWrite(pSSM, &GCPhys, sizeof(GCPhys)); 3159 3250 } … … 3170 3261 { 3171 3262 SSM_ASSERT_WRITEABLE_RET(pSSM); 3263 SSM_CHECK_CANCELLED_RET(pSSM); 3172 3264 return ssmR3DataWrite(pSSM, &GCPhys, sizeof(GCPhys)); 3173 3265 } … … 3184 3276 { 3185 3277 SSM_ASSERT_WRITEABLE_RET(pSSM); 3278 SSM_CHECK_CANCELLED_RET(pSSM); 3186 3279 return ssmR3DataWrite(pSSM, &GCPhys, sizeof(GCPhys)); 3187 3280 } … … 3198 3291 { 3199 3292 SSM_ASSERT_WRITEABLE_RET(pSSM); 3293 SSM_CHECK_CANCELLED_RET(pSSM); 3200 3294 return ssmR3DataWrite(pSSM, &GCPtr, sizeof(GCPtr)); 3201 3295 } … … 3212 3306 { 3213 3307 SSM_ASSERT_WRITEABLE_RET(pSSM); 3308 SSM_CHECK_CANCELLED_RET(pSSM); 3214 3309 return ssmR3DataWrite(pSSM, &RCPtr, sizeof(RCPtr)); 3215 3310 } … … 3226 3321 { 3227 3322 SSM_ASSERT_WRITEABLE_RET(pSSM); 3323 SSM_CHECK_CANCELLED_RET(pSSM); 3228 3324 return ssmR3DataWrite(pSSM, &GCPtr, sizeof(GCPtr)); 3229 3325 } … … 3240 3336 { 3241 3337 SSM_ASSERT_WRITEABLE_RET(pSSM); 3338 SSM_CHECK_CANCELLED_RET(pSSM); 3242 3339 return ssmR3DataWrite(pSSM, &IOPort, sizeof(IOPort)); 3243 3340 } … … 3254 3351 { 3255 3352 SSM_ASSERT_WRITEABLE_RET(pSSM); 3353 SSM_CHECK_CANCELLED_RET(pSSM); 3256 3354 return ssmR3DataWrite(pSSM, &Sel, sizeof(Sel)); 3257 3355 } … … 3269 3367 { 3270 3368 SSM_ASSERT_WRITEABLE_RET(pSSM); 3369 SSM_CHECK_CANCELLED_RET(pSSM); 3271 3370 return ssmR3DataWrite(pSSM, pv, cb); 3272 3371 } … … 3283 3382 { 3284 3383 SSM_ASSERT_WRITEABLE_RET(pSSM); 3384 SSM_CHECK_CANCELLED_RET(pSSM); 3285 3385 3286 3386 size_t cch = strlen(psz); … … 3311 3411 3312 3412 /* 3313 * Close the stream and delete the file on failure. 3314 */ 3413 * Make it non-cancellable, close the stream and delete the file on failure. 3414 */ 3415 ssmR3SetCancellable(pVM, pSSM, false); 3315 3416 int rc = ssmR3StrmClose(&pSSM->Strm); 3316 3417 if (RT_SUCCESS(rc)) … … 3343 3444 * Trash the handle before freeing it. 3344 3445 */ 3446 ASMAtomicWriteU32(&pSSM->fCancelled, 0); 3345 3447 pSSM->pVM = NULL; 3346 3448 pSSM->enmAfter = SSMAFTER_INVALID; … … 3595 3697 } 3596 3698 pUnit->offStream = ssmR3StrmTell(&pSSM->Strm); 3699 3700 /* 3701 * Check for cancellation. 3702 */ 3703 if (RT_UNLIKELY(ASMAtomicUoReadU32(&(pSSM)->fCancelled) == SSMHANDLE_CANCELLED)) 3704 { 3705 LogRel(("SSM: Cancelled!\n")); 3706 AssertRC(pSSM->rc); 3707 return pSSM->rc = VERR_SSM_CANCELLED; 3708 } 3597 3709 3598 3710 /* … … 3888 4000 pSSM->enmOp = SSMSTATE_INVALID; 3889 4001 pSSM->enmAfter = enmAfter; 4002 pSSM->fCancelled = SSMHANDLE_OK; 3890 4003 pSSM->rc = VINF_SUCCESS; 3891 4004 pSSM->cbUnitLeftV1 = 0; … … 3963 4076 rc = ssmR3WriteHeaderAndClearPerUnitData(pVM, pSSM); 3964 4077 if (RT_SUCCESS(rc)) 4078 { 4079 ssmR3SetCancellable(pVM, pSSM, true); 3965 4080 ssmR3SaveDoCommon(pVM, pSSM); 4081 } 4082 3966 4083 return ssmR3SaveDoClose(pVM, pSSM); 3967 4084 } … … 4059 4176 continue; 4060 4177 pUnit->offStream = ssmR3StrmTell(&pSSM->Strm); 4178 4179 /* 4180 * Check for cancellation. 4181 */ 4182 if (RT_UNLIKELY(ASMAtomicUoReadU32(&(pSSM)->fCancelled) == SSMHANDLE_CANCELLED)) 4183 { 4184 LogRel(("SSM: Cancelled!\n")); 4185 AssertRC(pSSM->rc); 4186 return pSSM->rc = VERR_SSM_CANCELLED; 4187 } 4061 4188 4062 4189 /* … … 4401 4528 */ 4402 4529 pSSM->enmOp = SSMSTATE_LIVE_STEP1; 4530 ssmR3SetCancellable(pVM, pSSM, true); 4403 4531 *ppSSM = pSSM; 4404 4532 return VINF_SUCCESS; … … 5194 5322 { 5195 5323 SSM_ASSERT_READABLE_RET(pSSM); 5324 SSM_CHECK_CANCELLED_RET(pSSM); 5196 5325 uint8_t u8; /* see SSMR3PutBool */ 5197 5326 int rc = ssmR3DataRead(pSSM, &u8, sizeof(u8)); … … 5215 5344 { 5216 5345 SSM_ASSERT_READABLE_RET(pSSM); 5346 SSM_CHECK_CANCELLED_RET(pSSM); 5217 5347 return ssmR3DataRead(pSSM, pu8, sizeof(*pu8)); 5218 5348 } … … 5229 5359 { 5230 5360 SSM_ASSERT_READABLE_RET(pSSM); 5361 SSM_CHECK_CANCELLED_RET(pSSM); 5231 5362 return ssmR3DataRead(pSSM, pi8, sizeof(*pi8)); 5232 5363 } … … 5243 5374 { 5244 5375 SSM_ASSERT_READABLE_RET(pSSM); 5376 SSM_CHECK_CANCELLED_RET(pSSM); 5245 5377 return ssmR3DataRead(pSSM, pu16, sizeof(*pu16)); 5246 5378 } … … 5257 5389 { 5258 5390 SSM_ASSERT_READABLE_RET(pSSM); 5391 SSM_CHECK_CANCELLED_RET(pSSM); 5259 5392 return ssmR3DataRead(pSSM, pi16, sizeof(*pi16)); 5260 5393 } … … 5271 5404 { 5272 5405 SSM_ASSERT_READABLE_RET(pSSM); 5406 SSM_CHECK_CANCELLED_RET(pSSM); 5273 5407 return ssmR3DataRead(pSSM, pu32, sizeof(*pu32)); 5274 5408 } … … 5285 5419 { 5286 5420 SSM_ASSERT_READABLE_RET(pSSM); 5421 SSM_CHECK_CANCELLED_RET(pSSM); 5287 5422 return ssmR3DataRead(pSSM, pi32, sizeof(*pi32)); 5288 5423 } … … 5299 5434 { 5300 5435 SSM_ASSERT_READABLE_RET(pSSM); 5436 SSM_CHECK_CANCELLED_RET(pSSM); 5301 5437 return ssmR3DataRead(pSSM, pu64, sizeof(*pu64)); 5302 5438 } … … 5313 5449 { 5314 5450 SSM_ASSERT_READABLE_RET(pSSM); 5451 SSM_CHECK_CANCELLED_RET(pSSM); 5315 5452 return ssmR3DataRead(pSSM, pi64, sizeof(*pi64)); 5316 5453 } … … 5327 5464 { 5328 5465 SSM_ASSERT_READABLE_RET(pSSM); 5466 SSM_CHECK_CANCELLED_RET(pSSM); 5329 5467 return ssmR3DataRead(pSSM, pu128, sizeof(*pu128)); 5330 5468 } … … 5341 5479 { 5342 5480 SSM_ASSERT_READABLE_RET(pSSM); 5481 SSM_CHECK_CANCELLED_RET(pSSM); 5343 5482 return ssmR3DataRead(pSSM, pi128, sizeof(*pi128)); 5344 5483 } … … 5355 5494 { 5356 5495 SSM_ASSERT_READABLE_RET(pSSM); 5496 SSM_CHECK_CANCELLED_RET(pSSM); 5357 5497 return ssmR3DataRead(pSSM, pu, sizeof(*pu)); 5358 5498 } … … 5369 5509 { 5370 5510 SSM_ASSERT_READABLE_RET(pSSM); 5511 SSM_CHECK_CANCELLED_RET(pSSM); 5371 5512 return ssmR3DataRead(pSSM, pi, sizeof(*pi)); 5372 5513 } … … 5413 5554 { 5414 5555 SSM_ASSERT_READABLE_RET(pSSM); 5556 SSM_CHECK_CANCELLED_RET(pSSM); 5415 5557 return ssmR3DataRead(pSSM, pGCPhys, sizeof(*pGCPhys)); 5416 5558 } … … 5427 5569 { 5428 5570 SSM_ASSERT_READABLE_RET(pSSM); 5571 SSM_CHECK_CANCELLED_RET(pSSM); 5429 5572 return ssmR3DataRead(pSSM, pGCPhys, sizeof(*pGCPhys)); 5430 5573 } … … 5441 5584 { 5442 5585 SSM_ASSERT_READABLE_RET(pSSM); 5586 SSM_CHECK_CANCELLED_RET(pSSM); 5443 5587 5444 5588 /* … … 5518 5662 { 5519 5663 SSM_ASSERT_READABLE_RET(pSSM); 5664 SSM_CHECK_CANCELLED_RET(pSSM); 5520 5665 5521 5666 /* … … 5573 5718 { 5574 5719 SSM_ASSERT_READABLE_RET(pSSM); 5720 SSM_CHECK_CANCELLED_RET(pSSM); 5575 5721 return ssmR3DataRead(pSSM, pRCPtr, sizeof(*pRCPtr)); 5576 5722 } … … 5587 5733 { 5588 5734 SSM_ASSERT_READABLE_RET(pSSM); 5735 SSM_CHECK_CANCELLED_RET(pSSM); 5589 5736 return ssmR3DataRead(pSSM, pIOPort, sizeof(*pIOPort)); 5590 5737 } … … 5601 5748 { 5602 5749 SSM_ASSERT_READABLE_RET(pSSM); 5750 SSM_CHECK_CANCELLED_RET(pSSM); 5603 5751 return ssmR3DataRead(pSSM, pSel, sizeof(*pSel)); 5604 5752 } … … 5616 5764 { 5617 5765 SSM_ASSERT_READABLE_RET(pSSM); 5766 SSM_CHECK_CANCELLED_RET(pSSM); 5618 5767 return ssmR3DataRead(pSSM, pv, cb); 5619 5768 } … … 5646 5795 { 5647 5796 SSM_ASSERT_READABLE_RET(pSSM); 5797 SSM_CHECK_CANCELLED_RET(pSSM); 5648 5798 5649 5799 /* read size prefix. */ … … 5676 5826 { 5677 5827 SSM_ASSERT_READABLE_RET(pSSM); 5828 SSM_CHECK_CANCELLED_RET(pSSM); 5678 5829 while (cb > 0) 5679 5830 { … … 5703 5854 { 5704 5855 SSM_ASSERT_READABLE_RET(pSSM); 5856 SSM_CHECK_CANCELLED_RET(pSSM); 5705 5857 if (pSSM->u.Read.uFmtVerMajor >= 2) 5706 5858 { … … 6168 6320 * Initialize the handle. 6169 6321 */ 6170 pSSM->pVM = pVM; 6171 pSSM->enmOp = SSMSTATE_INVALID; 6172 pSSM->enmAfter = SSMAFTER_INVALID; 6173 pSSM->rc = VINF_SUCCESS; 6174 pSSM->cbUnitLeftV1 = 0; 6175 pSSM->offUnit = UINT64_MAX; 6176 pSSM->pfnProgress = NULL; 6177 pSSM->pvUser = NULL; 6178 pSSM->uPercent = 0; 6179 pSSM->offEstProgress = 0; 6180 pSSM->cbEstTotal = 0; 6181 pSSM->offEst = 0; 6182 pSSM->offEstUnitEnd = 0; 6183 pSSM->uPercentPrepare = 5; 6184 pSSM->uPercentDone = 2; 6185 pSSM->pszFilename = pszFilename; 6322 pSSM->pVM = pVM; 6323 pSSM->enmOp = SSMSTATE_INVALID; 6324 pSSM->enmAfter = SSMAFTER_INVALID; 6325 pSSM->fCancelled = SSMHANDLE_OK; 6326 pSSM->rc = VINF_SUCCESS; 6327 pSSM->cbUnitLeftV1 = 0; 6328 pSSM->offUnit = UINT64_MAX; 6329 pSSM->pfnProgress = NULL; 6330 pSSM->pvUser = NULL; 6331 pSSM->uPercent = 0; 6332 pSSM->offEstProgress = 0; 6333 pSSM->cbEstTotal = 0; 6334 pSSM->offEst = 0; 6335 pSSM->offEstUnitEnd = 0; 6336 pSSM->uPercentPrepare = 5; 6337 pSSM->uPercentDone = 2; 6338 pSSM->pszFilename = pszFilename; 6186 6339 6187 6340 pSSM->u.Read.pZipDecompV1 = NULL; … … 6415 6568 { 6416 6569 LogRel(("SSM: I/O error. rc=%Rrc\n", rc)); 6570 break; 6571 } 6572 6573 /* 6574 * Check for cancellation. 6575 */ 6576 if (RT_UNLIKELY(ASMAtomicUoReadU32(&(pSSM)->fCancelled) == SSMHANDLE_CANCELLED)) 6577 { 6578 LogRel(("SSM: Cancelled!n")); 6579 rc = pSSM->rc; 6580 if (RT_SUCCESS(pSSM->rc)) 6581 pSSM->rc = rc = VERR_SSM_CANCELLED; 6417 6582 break; 6418 6583 } … … 6554 6719 ssmR3DataReadFinishV2(pSSM); 6555 6720 } 6721 6722 /* 6723 * Check for cancellation. 6724 */ 6725 if (RT_UNLIKELY(ASMAtomicUoReadU32(&(pSSM)->fCancelled) == SSMHANDLE_CANCELLED)) 6726 { 6727 LogRel(("SSM: Cancelled!\n")); 6728 if (RT_SUCCESS(pSSM->rc)) 6729 pSSM->rc = VERR_SSM_CANCELLED; 6730 return pSSM->rc; 6731 } 6556 6732 } 6557 6733 /* won't get here */ … … 6597 6773 { 6598 6774 ssmR3StrmStartIoThread(&Handle.Strm); 6775 ssmR3SetCancellable(pVM, &Handle, true); 6599 6776 6600 6777 Handle.enmAfter = enmAfter; … … 6714 6891 if (RT_SUCCESS(Handle.rc)) 6715 6892 Handle.rc = rc; 6893 break; 6716 6894 } 6717 6895 } … … 6723 6901 pfnProgress(pVM, 99, pvUser); 6724 6902 6903 ssmR3SetCancellable(pVM, &Handle, false); 6725 6904 ssmR3StrmClose(&Handle.Strm); 6726 6905 } … … 6838 7017 AssertMsgReturn(pSSM->enmAfter == SSMAFTER_OPENED, ("%d\n", pSSM->enmAfter),VERR_INVALID_PARAMETER); 6839 7018 AssertMsgReturn(pSSM->enmOp == SSMSTATE_OPEN_READ, ("%d\n", pSSM->enmOp), VERR_INVALID_PARAMETER); 7019 Assert(pSSM->fCancelled == SSMHANDLE_OK); 6840 7020 6841 7021 /* … … 7136 7316 * to SSM. 7137 7317 * 7318 * @returns VBox status code of the handle, or VERR_INVALID_PARAMETER. 7319 * @param pSSM SSM operation handle. 7320 * @param iStatus Failure status code. This MUST be a VERR_*. 7321 */ 7322 VMMR3DECL(int) SSMR3HandleSetStatus(PSSMHANDLE pSSM, int iStatus) 7323 { 7324 Assert(pSSM->enmOp != SSMSTATE_LIVE_VOTE); 7325 if (RT_FAILURE(iStatus)) 7326 { 7327 int rc = pSSM->rc; 7328 if (RT_SUCCESS(rc)) 7329 pSSM->rc = rc = iStatus; 7330 return rc; 7331 } 7332 AssertMsgFailed(("iStatus=%d %Rrc\n", iStatus, iStatus)); 7333 return VERR_INVALID_PARAMETER; 7334 } 7335 7336 7337 /** 7338 * Get what to do after this operation. 7339 * 7138 7340 * @returns SSMAFTER enum value. 7139 7341 * @param pSSM SSM operation handle. 7140 * @param iStatus Failure status code. This MUST be a VERR_*.7141 */7142 VMMR3DECL(int) SSMR3HandleSetStatus(PSSMHANDLE pSSM, int iStatus)7143 {7144 Assert(pSSM->enmOp != SSMSTATE_LIVE_VOTE);7145 if (RT_FAILURE(iStatus))7146 {7147 if (RT_SUCCESS(pSSM->rc))7148 pSSM->rc = iStatus;7149 return pSSM->rc = iStatus;7150 }7151 AssertMsgFailed(("iStatus=%d %Rrc\n", iStatus, iStatus));7152 return VERR_INVALID_PARAMETER;7153 }7154 7155 7156 /**7157 * Get what to do after this operation.7158 *7159 * @returns SSMAFTER enum value.7160 * @param pSSM SSM operation handle.7161 7342 */ 7162 7343 VMMR3DECL(SSMAFTER) SSMR3HandleGetAfter(PSSMHANDLE pSSM) … … 7178 7359 } 7179 7360 7361 7362 /** 7363 * Asynchronously cancels the current SSM operation ASAP. 7364 * 7365 * @returns VBox status code. 7366 * @retval VINF_SUCCESS on success. 7367 * @retval VERR_SSM_NO_PENDING_OPERATION if nothing around that can be 7368 * cancelled. 7369 * @retval VERR_SSM_ALREADY_CANCELLED if the operation as already been 7370 * cancelled. 7371 * 7372 * @param pVM The VM handle. 7373 * 7374 * @thread Any. 7375 */ 7376 VMMR3DECL(int) SSMR3Cancel(PVM pVM) 7377 { 7378 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 7379 7380 int rc = RTCritSectEnter(&pVM->ssm.s.CancelCritSect); 7381 AssertRCReturn(rc, rc); 7382 7383 PSSMHANDLE pSSM = pVM->ssm.s.pSSM; 7384 if (pSSM) 7385 { 7386 uint32_t u32Old; 7387 if (ASMAtomicCmpXchgExU32(&pSSM->fCancelled, SSMHANDLE_CANCELLED, SSMHANDLE_OK, &u32Old)) 7388 { 7389 LogRel(("SSM: Cancelled pending operation\n")); 7390 rc = VINF_SUCCESS; 7391 } 7392 else if (u32Old == SSMHANDLE_CANCELLED) 7393 rc = VERR_SSM_ALREADY_CANCELLED; 7394 else 7395 { 7396 AssertLogRelMsgFailed(("fCancelled=%RX32 enmOp=%d\n", u32Old, pSSM->enmOp)); 7397 rc = VERR_INTERNAL_ERROR_2; 7398 } 7399 } 7400 else 7401 rc = VERR_SSM_NO_PENDING_OPERATION; 7402 7403 RTCritSectLeave(&pVM->ssm.s.CancelCritSect); 7404 return rc; 7405 } 7406 -
trunk/src/VBox/VMM/SSMInternal.h
r22480 r22884 26 26 #include <VBox/types.h> 27 27 #include <VBox/ssm.h> 28 #include <iprt/critsect.h> 28 29 29 30 RT_C_DECLS_BEGIN … … 266 267 /** For lazy init. */ 267 268 bool fInitialized; 269 /** Critical section for serializing cancellation. */ 270 RTCRITSECT CancelCritSect; 271 /** The handle of the current save or load operation. 272 * This is used by SSMR3Cancel. */ 273 PSSMHANDLE volatile pSSM; 268 274 } SSM; 269 275 /** Pointer to SSM VM instance data. */
Note:
See TracChangeset
for help on using the changeset viewer.