Changeset 27920 in vbox
- Timestamp:
- Mar 31, 2010 7:02:48 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 59612
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/pdmasynccompletion.h
r27738 r27920 64 64 * @param pDevIns The device instance. 65 65 * @param pvUser User argument. 66 */ 67 typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEDEV(PPDMDEVINS pDevIns, void *pvUser); 66 * @param rc The status code of the completed request. 67 */ 68 typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEDEV(PPDMDEVINS pDevIns, void *pvUser, int rc); 68 69 /** Pointer to a FNPDMASYNCCOMPLETEDEV(). */ 69 70 typedef FNPDMASYNCCOMPLETEDEV *PFNPDMASYNCCOMPLETEDEV; … … 76 77 * @param pvTemplateUser User argument given when creating the template. 77 78 * @param pvUser User argument given during request initiation. 78 */ 79 typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEDRV(PPDMDRVINS pDrvIns, void *pvTemplateUser, void *pvUser); 79 * @param rc The status code of the completed request. 80 */ 81 typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEDRV(PPDMDRVINS pDrvIns, void *pvTemplateUser, void *pvUser, int rc); 80 82 /** Pointer to a FNPDMASYNCCOMPLETEDRV(). */ 81 83 typedef FNPDMASYNCCOMPLETEDRV *PFNPDMASYNCCOMPLETEDRV; … … 87 89 * @param pUsbIns The USB device instance. 88 90 * @param pvUser User argument. 89 */ 90 typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEUSB(PPDMUSBINS pUsbIns, void *pvUser); 91 * @param rc The status code of the completed request. 92 */ 93 typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEUSB(PPDMUSBINS pUsbIns, void *pvUser, int rc); 91 94 /** Pointer to a FNPDMASYNCCOMPLETEUSB(). */ 92 95 typedef FNPDMASYNCCOMPLETEUSB *PFNPDMASYNCCOMPLETEUSB; … … 99 102 * @param pvUser User argument for the task. 100 103 * @param pvUser2 User argument for the template. 101 */ 102 typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEINT(PVM pVM, void *pvUser, void *pvUser2); 104 * @param rc The status code of the completed request. 105 */ 106 typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEINT(PVM pVM, void *pvUser, void *pvUser2, int rc); 103 107 /** Pointer to a FNPDMASYNCCOMPLETEINT(). */ 104 108 typedef FNPDMASYNCCOMPLETEINT *PFNPDMASYNCCOMPLETEINT; -
trunk/src/VBox/Devices/Storage/DrvVD.cpp
r27810 r27920 285 285 #ifdef VBOX_WITH_PDM_ASYNC_COMPLETION 286 286 287 static DECLCALLBACK(void) drvvdAsyncTaskCompleted(PPDMDRVINS pDrvIns, void *pvTemplateUser, void *pvUser )287 static DECLCALLBACK(void) drvvdAsyncTaskCompleted(PPDMDRVINS pDrvIns, void *pvTemplateUser, void *pvUser, int rcReq) 288 288 { 289 289 PVBOXDISK pThis = PDMINS_2_DATA(pDrvIns, PVBOXDISK); -
trunk/src/VBox/VMM/PDMAsyncCompletion.cpp
r27883 r27920 545 545 } 546 546 547 void pdmR3AsyncCompletionCompleteTask(PPDMASYNCCOMPLETIONTASK pTask, bool fCallCompletionHandler)547 void pdmR3AsyncCompletionCompleteTask(PPDMASYNCCOMPLETIONTASK pTask, int rc, bool fCallCompletionHandler) 548 548 { 549 549 LogFlow(("%s: pTask=%#p fCallCompletionHandler=%RTbool\n", __FUNCTION__, pTask, fCallCompletionHandler)); … … 557 557 case PDMASYNCCOMPLETIONTEMPLATETYPE_DEV: 558 558 { 559 pTemplate->u.Dev.pfnCompleted(pTemplate->u.Dev.pDevIns, pTask->pvUser );559 pTemplate->u.Dev.pfnCompleted(pTemplate->u.Dev.pDevIns, pTask->pvUser, rc); 560 560 break; 561 561 } 562 562 case PDMASYNCCOMPLETIONTEMPLATETYPE_DRV: 563 563 { 564 pTemplate->u.Drv.pfnCompleted(pTemplate->u.Drv.pDrvIns, pTemplate->u.Drv.pvTemplateUser, pTask->pvUser );564 pTemplate->u.Drv.pfnCompleted(pTemplate->u.Drv.pDrvIns, pTemplate->u.Drv.pvTemplateUser, pTask->pvUser, rc); 565 565 break; 566 566 } 567 567 case PDMASYNCCOMPLETIONTEMPLATETYPE_USB: 568 568 { 569 pTemplate->u.Usb.pfnCompleted(pTemplate->u.Usb.pUsbIns, pTask->pvUser );569 pTemplate->u.Usb.pfnCompleted(pTemplate->u.Usb.pUsbIns, pTask->pvUser, rc); 570 570 break; 571 571 } 572 572 case PDMASYNCCOMPLETIONTEMPLATETYPE_INTERNAL: 573 573 { 574 pTemplate->u.Int.pfnCompleted(pTemplate->pVM, pTask->pvUser, pTemplate->u.Int.pvUser );574 pTemplate->u.Int.pfnCompleted(pTemplate->pVM, pTask->pvUser, pTemplate->u.Int.pvUser, rc); 575 575 break; 576 576 } -
trunk/src/VBox/VMM/PDMAsyncCompletionFile.cpp
r27738 r27920 315 315 } 316 316 317 void pdmacFileEpTaskCompleted(PPDMACTASKFILE pTask, void *pvUser )317 void pdmacFileEpTaskCompleted(PPDMACTASKFILE pTask, void *pvUser, int rc) 318 318 { 319 319 PPDMASYNCCOMPLETIONTASKFILE pTaskFile = (PPDMASYNCCOMPLETIONTASKFILE)pvUser; … … 321 321 if (pTask->enmTransferType == PDMACTASKFILETRANSFER_FLUSH) 322 322 { 323 pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, true);323 pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, rc, true); 324 324 } 325 325 else … … 328 328 uint32_t uOld = ASMAtomicSubS32(&pTaskFile->cbTransferLeft, (int32_t)pTask->DataSeg.cbSeg); 329 329 330 /* The first error will be returned. */ 331 if (RT_FAILURE(rc)) 332 ASMAtomicCmpXchgS32(&pTaskFile->rc, rc, VINF_SUCCESS); 333 330 334 if (!(uOld - pTask->DataSeg.cbSeg) 331 335 && !ASMAtomicXchgBool(&pTaskFile->fCompleted, true)) 332 pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, true);336 pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, pTaskFile->rc, true); 333 337 } 334 338 } … … 350 354 ASMAtomicWriteS32(&pTaskFile->cbTransferLeft, (int32_t)cbTransfer); 351 355 ASMAtomicWriteBool(&pTaskFile->fCompleted, false); 356 ASMAtomicWriteS32(&pTaskFile->rc, VINF_SUCCESS); 352 357 353 358 for (unsigned i = 0; i < cSegments; i++) … … 374 379 if (ASMAtomicReadS32(&pTaskFile->cbTransferLeft) == 0 375 380 && !ASMAtomicXchgBool(&pTaskFile->fCompleted, true)) 376 pdmR3AsyncCompletionCompleteTask(pTask, false);381 pdmR3AsyncCompletionCompleteTask(pTask, pTaskFile->rc, false); 377 382 else 378 383 rc = VINF_AIO_TASK_PENDING; … … 1080 1085 1081 1086 pTaskFile->cbTransferLeft = 0; 1087 pTaskFile->rc = VINF_SUCCESS; 1082 1088 1083 1089 if (pEpFile->fCaching) -
trunk/src/VBox/VMM/PDMAsyncCompletionFileCache.cpp
r27563 r27920 85 85 * Internal Functions * 86 86 *******************************************************************************/ 87 static void pdmacFileCacheTaskCompleted(PPDMACTASKFILE pTask, void *pvUser );87 static void pdmacFileCacheTaskCompleted(PPDMACTASKFILE pTask, void *pvUser, int rc); 88 88 89 89 /** … … 760 760 * @param pEndpointCache The endpoint cache. 761 761 * @param pTaskSeg Task segment to complete. 762 */ 763 static PPDMACFILETASKSEG pdmacFileCacheTaskComplete(PPDMACFILEENDPOINTCACHE pEndpointCache, PPDMACFILETASKSEG pTaskSeg) 762 * @param rc Status code to set. 763 */ 764 static PPDMACFILETASKSEG pdmacFileCacheTaskComplete(PPDMACFILEENDPOINTCACHE pEndpointCache, PPDMACFILETASKSEG pTaskSeg, int rc) 764 765 { 765 766 PPDMACFILETASKSEG pNext = pTaskSeg->pNext; 766 767 uint32_t uOld = ASMAtomicSubS32(&pTaskSeg->pTask->cbTransferLeft, pTaskSeg->cbTransfer); 767 PPDMASYNCCOMPLETIONTASKFILE pTaskFile = pTaskSeg->pTask; 768 769 if (RT_FAILURE(rc)) 770 ASMAtomicCmpXchgS32(&pTaskFile->rc, rc, VINF_SUCCESS); 771 772 uint32_t uOld = ASMAtomicSubS32(&pTaskFile->cbTransferLeft, pTaskSeg->cbTransfer); 768 773 AssertMsg(uOld >= pTaskSeg->cbTransfer, ("New value would overflow\n")); 769 774 if (!(uOld - pTaskSeg->cbTransfer) 770 && !ASMAtomicXchgBool(&pTask Seg->pTask->fCompleted, true))771 pdmR3AsyncCompletionCompleteTask(&pTask Seg->pTask->Core, true);775 && !ASMAtomicXchgBool(&pTaskFile->fCompleted, true)) 776 pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, pTaskFile->rc, true); 772 777 773 778 RTMemFree(pTaskSeg); … … 782 787 * @param pTask The completed task. 783 788 * @param pvUser Opaque user data. 784 */ 785 static void pdmacFileCacheTaskCompleted(PPDMACTASKFILE pTask, void *pvUser) 789 * @param rc Status code of the completed request. 790 */ 791 static void pdmacFileCacheTaskCompleted(PPDMACTASKFILE pTask, void *pvUser, int rc) 786 792 { 787 793 PPDMACFILECACHEENTRY pEntry = (PPDMACFILECACHEENTRY)pvUser; … … 811 817 ASMAtomicDecU32(&pEndpointCache->cWritesOutstanding); 812 818 813 pEntry->fFlags &= ~PDMACFILECACHE_ENTRY_IS_DIRTY; 814 815 while (pCurr) 819 /* 820 * An error here is difficult to handle as the original request completed already. 821 * The error is logged for now and the VM is paused. 822 * If the user continues the entry is written again in the hope 823 * the user fixed the problem and the next write succeeds. 824 */ 825 /** @todo r=aeichner: This solution doesn't work 826 * The user will get the message but the VM will hang afterwards 827 * VMR3Suspend() returns when the VM is suspended but suspending 828 * the VM will reopen the images readonly in DrvVD. They are closed first 829 * which will close the endpoints. This will block EMT while the 830 * I/O manager processes the close request but the IO manager is stuck 831 * in the VMR3Suspend call and can't process the request. 832 * Another problem is that closing the VM means flushing the cache 833 * but the entry failed and will probably fail again. 834 * No idea so far how to solve this problem... but the user gets informed 835 * at least. 836 */ 837 if (RT_FAILURE(rc)) 816 838 { 817 AssertMsg(pCurr->fWrite, ("Completed write entries should never have read tasks attached\n")); 818 819 memcpy(pEntry->pbData + pCurr->uBufOffset, pCurr->pvBuf, pCurr->cbTransfer); 820 fDirty = true; 821 822 pCurr = pdmacFileCacheTaskComplete(pEndpointCache, pCurr); 839 LogRel(("I/O cache: Error while writing entry at offset %RTfoff (%u bytes) to file \"%s\"\n", 840 pEntry->Core.Key, pEntry->cbData, pEndpoint->Core.pszUri)); 841 842 rc = VMSetRuntimeError(pEndpoint->Core.pEpClass->pVM, 0, "CACHE_IOERR", 843 N_("The I/O cache encountered an error while updating data in file \"%s\" (rc=%Rrc). Make sure there is enough free space on the disk and that the disk is working properly. Operation can be resumed afterwards."), pEndpoint->Core.pszUri, rc); 844 AssertRC(rc); 845 rc = VMR3Suspend(pEndpoint->Core.pEpClass->pVM); 846 } 847 else 848 { 849 pEntry->fFlags &= ~PDMACFILECACHE_ENTRY_IS_DIRTY; 850 851 while (pCurr) 852 { 853 AssertMsg(pCurr->fWrite, ("Completed write entries should never have read tasks attached\n")); 854 855 memcpy(pEntry->pbData + pCurr->uBufOffset, pCurr->pvBuf, pCurr->cbTransfer); 856 fDirty = true; 857 858 pCurr = pdmacFileCacheTaskComplete(pEndpointCache, pCurr, VINF_SUCCESS); 859 } 823 860 } 824 861 } … … 839 876 memcpy(pCurr->pvBuf, pEntry->pbData + pCurr->uBufOffset, pCurr->cbTransfer); 840 877 841 pCurr = pdmacFileCacheTaskComplete(pEndpointCache, pCurr );878 pCurr = pdmacFileCacheTaskComplete(pEndpointCache, pCurr, rc); 842 879 } 843 880 } … … 852 889 PPDMASYNCCOMPLETIONTASKFILE pTaskFlush = (PPDMASYNCCOMPLETIONTASKFILE)ASMAtomicXchgPtr((void * volatile *)&pEndpointCache->pTaskFlush, NULL); 853 890 if (pTaskFlush) 854 pdmR3AsyncCompletionCompleteTask(&pTaskFlush->Core, true);891 pdmR3AsyncCompletionCompleteTask(&pTaskFlush->Core, VINF_SUCCESS, true); 855 892 } 856 893 … … 1886 1923 if (ASMAtomicReadS32(&pTask->cbTransferLeft) == 0 1887 1924 && !ASMAtomicXchgBool(&pTask->fCompleted, true)) 1888 pdmR3AsyncCompletionCompleteTask(&pTask->Core, false);1925 pdmR3AsyncCompletionCompleteTask(&pTask->Core, VINF_SUCCESS, false); 1889 1926 else 1890 1927 rc = VINF_AIO_TASK_PENDING; … … 2143 2180 if (ASMAtomicReadS32(&pTask->cbTransferLeft) == 0 2144 2181 && !ASMAtomicXchgBool(&pTask->fCompleted, true)) 2145 pdmR3AsyncCompletionCompleteTask(&pTask->Core, false);2182 pdmR3AsyncCompletionCompleteTask(&pTask->Core, VINF_SUCCESS, false); 2146 2183 else 2147 2184 rc = VINF_AIO_TASK_PENDING; … … 2171 2208 } 2172 2209 else 2173 pdmR3AsyncCompletionCompleteTask(&pTask->Core, false);2210 pdmR3AsyncCompletionCompleteTask(&pTask->Core, VINF_SUCCESS, false); 2174 2211 } 2175 2212 -
trunk/src/VBox/VMM/PDMAsyncCompletionFileFailsafe.cpp
r27299 r27920 75 75 } 76 76 77 AssertRC(rc); 78 79 pCurr->pfnCompleted(pCurr, pCurr->pvUser); 77 pCurr->pfnCompleted(pCurr, pCurr->pvUser, rc); 80 78 pdmacFileTaskFree(pEndpoint, pCurr); 81 79 } 82 80 83 return rc;81 return VINF_SUCCESS; 84 82 } 85 83 -
trunk/src/VBox/VMM/PDMAsyncCompletionFileInternal.h
r27563 r27920 605 605 606 606 /** Request completion function */ 607 typedef DECLCALLBACK(void) FNPDMACTASKCOMPLETED(PPDMACTASKFILE pTask, void *pvUser );607 typedef DECLCALLBACK(void) FNPDMACTASKCOMPLETED(PPDMACTASKFILE pTask, void *pvUser, int rc); 608 608 /** Pointer to a request completion function. */ 609 609 typedef FNPDMACTASKCOMPLETED *PFNPDMACTASKCOMPLETED; … … 667 667 /** Flag whether the task completed. */ 668 668 volatile bool fCompleted; 669 /** Return code. */ 670 volatile int rc; 669 671 } PDMASYNCCOMPLETIONTASKFILE; 670 672 … … 686 688 int pdmacFileEpAddTask(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMACTASKFILE pTask); 687 689 688 void pdmacFileEpTaskCompleted(PPDMACTASKFILE pTask, void *pvUser );690 void pdmacFileEpTaskCompleted(PPDMACTASKFILE pTask, void *pvUser, int rc); 689 691 690 692 bool pdmacFileBwMgrIsTransferAllowed(PPDMACFILEBWMGR pBwMgr, uint32_t cbTransfer); -
trunk/src/VBox/VMM/PDMAsyncCompletionFileNormal.cpp
r27336 r27920 817 817 if (!pEndpoint->AioMgr.cRequestsActive) 818 818 { 819 pCurr->pfnCompleted(pCurr, pCurr->pvUser );819 pCurr->pfnCompleted(pCurr, pCurr->pvUser, VINF_SUCCESS); 820 820 pdmacFileTaskFree(pEndpoint, pCurr); 821 821 } … … 1163 1163 else 1164 1164 { 1165 AssertMsg(( (cbTransfered == pTask->DataSeg.cbSeg) 1166 || (pTask->fBounceBuffer && (cbTransfered >= pTask->DataSeg.cbSeg))), 1167 ("Task didn't completed successfully (rc=%Rrc) or was incomplete (cbTransfered=%u)\n", rcReq, cbTransfered)); 1165 AssertMsg( RT_FAILURE(rcReq) 1166 || ( (cbTransfered == pTask->DataSeg.cbSeg) 1167 || (pTask->fBounceBuffer && (cbTransfered >= pTask->DataSeg.cbSeg))), 1168 ("Task didn't completed successfully (rc=%Rrc) or was incomplete (cbTransfered=%u)\n", rcReq, cbTransfered)); 1168 1169 1169 1170 if (pTask->fPrefetch) … … 1196 1197 else 1197 1198 { 1198 if ( pTask->fBounceBuffer)1199 if (RT_SUCCESS(rc) && pTask->fBounceBuffer) 1199 1200 { 1200 1201 if (pTask->enmTransferType == PDMACTASKFILETRANSFER_READ) … … 1218 1219 1219 1220 /* Call completion callback */ 1220 pTask->pfnCompleted(pTask, pTask->pvUser );1221 pTask->pfnCompleted(pTask, pTask->pvUser, rcReq); 1221 1222 pdmacFileTaskFree(pEndpoint, pTask); 1222 1223 … … 1234 1235 AssertMsg(pTask->pEndpoint == pEndpoint, ("Endpoint of the flush request does not match assigned one\n")); 1235 1236 1236 pTask->pfnCompleted(pTask, pTask->pvUser );1237 pTask->pfnCompleted(pTask, pTask->pvUser, VINF_SUCCESS); 1237 1238 pdmacFileTaskFree(pEndpoint, pTask); 1238 1239 } -
trunk/src/VBox/VMM/PDMAsyncCompletionInternal.h
r27884 r27920 263 263 * @returns nothing 264 264 * @param pTask Pointer to the finished task. 265 * @param rc Status code of the completed request. 265 266 * @param fCallCompletionHandler Flag whether the completion handler should be called to 266 267 * inform the owner of the task that it has completed. 267 268 */ 268 void pdmR3AsyncCompletionCompleteTask(PPDMASYNCCOMPLETIONTASK pTask, bool fCallCompletionHandler);269 void pdmR3AsyncCompletionCompleteTask(PPDMASYNCCOMPLETIONTASK pTask, int rc, bool fCallCompletionHandler); 269 270 270 271 RT_C_DECLS_END -
trunk/src/VBox/VMM/testcase/tstPDMAsyncCompletion.cpp
r27797 r27920 63 63 RTSEMEVENT g_FinishedEventSem; 64 64 65 void pfnAsyncTaskCompleted(PVM pVM, void *pvUser, void *pvUser2 )65 void pfnAsyncTaskCompleted(PVM pVM, void *pvUser, void *pvUser2, int rc) 66 66 { 67 67 LogFlow((TESTCASE ": %s: pVM=%p pvUser=%p pvUser2=%p\n", __FUNCTION__, pVM, pvUser, pvUser2)); -
trunk/src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp
r26338 r27920 160 160 PDMACTESTFILE g_aTestFiles[NR_OPEN_ENDPOINTS]; 161 161 162 static void tstPDMACStressTestFileTaskCompleted(PVM pVM, void *pvUser, void *pvUser2 );162 static void tstPDMACStressTestFileTaskCompleted(PVM pVM, void *pvUser, void *pvUser2, int rcReq); 163 163 164 164 static void tstPDMACStressTestFileVerify(PPDMACTESTFILE pTestFile, PPDMACTESTFILETASK pTestTask) … … 364 364 rc = tstPDMACStressTestFileRead(pTestFile, pTask); 365 365 366 AssertRC(rc);367 368 366 if (rc != VINF_AIO_TASK_PENDING) 369 tstPDMACStressTestFileTaskCompleted(pVM, pTask, pTestFile );367 tstPDMACStressTestFileTaskCompleted(pVM, pTask, pTestFile, rc); 370 368 371 369 cTasksStarted++; … … 394 392 } 395 393 396 static void tstPDMACStressTestFileTaskCompleted(PVM pVM, void *pvUser, void *pvUser2 )394 static void tstPDMACStressTestFileTaskCompleted(PVM pVM, void *pvUser, void *pvUser2, int rcReq) 397 395 { 398 396 PPDMACTESTFILE pTestFile = (PPDMACTESTFILE)pvUser2;
Note:
See TracChangeset
for help on using the changeset viewer.