- Timestamp:
- Nov 24, 2009 12:30:13 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/ssm.h
r24874 r24895 965 965 966 966 /** 967 * Check if the stream is OK or not (cancelled). 968 * 969 * @returns VBox status code. 970 * @param pvUser The user argument. 971 * 972 * @remarks The method is expected to do a LogRel on failure. 973 */ 974 DECLCALLBACKMEMBER(int, pfnIsOk)(void *pvUser); 975 976 /** 967 977 * Close the stream. 968 978 * -
trunk/src/VBox/Main/ConsoleImplTeleporter.cpp
r24878 r24895 285 285 AssertReturn(pState->mfIsSource, VERR_INVALID_HANDLE); 286 286 287 /* Poll for incoming NACKs and errors from the other side */288 int rc = RTTcpSelectOne(pState->mhSocket, 0);289 if (rc != VERR_TIMEOUT)290 {291 if (RT_SUCCESS(rc))292 {293 LogRel(("Teleporter/TCP: Incoming data found before write, assuming it's a cancel.\n"));294 rc = VERR_SSM_CANCELLED;295 }296 else297 LogRel(("Teleporter/TCP: RTTcpSelectOne -> %Rrc before write.\n", rc));298 return rc;299 }300 301 287 for (;;) 302 288 { … … 305 291 Hdr.u32Magic = TELEPORTERTCPHDR_MAGIC; 306 292 Hdr.cb = RT_MIN((uint32_t)cbToWrite, TELEPORTERTCPHDR_MAX_SIZE); 307 rc = RTTcpWrite(pState->mhSocket, &Hdr, sizeof(Hdr));293 int rc = RTTcpWrite(pState->mhSocket, &Hdr, sizeof(Hdr)); 308 294 if (RT_FAILURE(rc)) 309 295 { … … 483 469 484 470 /** 471 * @copydoc SSMSTRMOPS::pfnIsOk 472 */ 473 static DECLCALLBACK(int) teleporterTcpOpIsOk(void *pvUser) 474 { 475 TeleporterState *pState = (TeleporterState *)pvUser; 476 477 if (pState->mfIsSource) 478 { 479 /* Poll for incoming NACKs and errors from the other side */ 480 int rc = RTTcpSelectOne(pState->mhSocket, 0); 481 if (rc != VERR_TIMEOUT) 482 { 483 if (RT_SUCCESS(rc)) 484 { 485 LogRel(("Teleporter/TCP: Incoming data detect by IsOk, assuming it's a cancel.\n")); 486 rc = VERR_SSM_CANCELLED; 487 } 488 else 489 LogRel(("Teleporter/TCP: RTTcpSelectOne -> %Rrc (IsOk).\n", rc)); 490 return rc; 491 } 492 } 493 494 return VINF_SUCCESS; 495 } 496 497 498 /** 485 499 * @copydoc SSMSTRMOPS::pfnClose 486 500 */ … … 522 536 teleporterTcpOpTell, 523 537 teleporterTcpOpSize, 538 teleporterTcpOpIsOk, 524 539 teleporterTcpOpClose, 525 540 SSMSTRMOPS_VERSION -
trunk/src/VBox/VMM/SSM.cpp
r24874 r24895 381 381 /** End of stream indicator (for read streams only). */ 382 382 bool fEndOfStream; 383 /** The nano timestamp set by ssmR3StrmGetFreeBuf. */ 384 uint64_t NanoTS; 383 385 /** Pointer to the next buffer in the chain. */ 384 386 PSSMSTRMBUF volatile pNext; … … 1780 1782 1781 1783 /** 1784 * @copydoc SSMSTRMOPS::pfnIsOk 1785 */ 1786 static DECLCALLBACK(int) ssmR3FileIsOk(void *pvUser) 1787 { 1788 /* 1789 * Check that there is still some space left on the disk. 1790 */ 1791 RTFOFF cbFree; 1792 int rc = RTFileQueryFsSizes((RTFILE)(uintptr_t)pvUser, NULL, &cbFree, NULL, NULL); 1793 #define SSM_MIN_DISK_FREE ((RTFOFF)( 10 * _1M )) 1794 if (RT_SUCCESS(rc)) 1795 { 1796 if (cbFree < SSM_MIN_DISK_FREE) 1797 { 1798 LogRel(("SSM: Giving up: Low on disk space. (cbFree=%RTfoff, SSM_MIN_DISK_FREE=%RTfoff).\n", 1799 cbFree, SSM_MIN_DISK_FREE)); 1800 rc = VERR_SSM_LOW_ON_DISK_SPACE; 1801 } 1802 } 1803 else if (rc == VERR_NOT_SUPPORTED) 1804 rc = VINF_SUCCESS; 1805 else 1806 AssertLogRelRC(rc); 1807 return rc; 1808 } 1809 1810 1811 /** 1782 1812 * @copydoc SSMSTRMOPS::pfnClose 1783 1813 */ … … 1799 1829 ssmR3FileTell, 1800 1830 ssmR3FileSize, 1831 ssmR3FileIsOk, 1801 1832 ssmR3FileClose, 1802 1833 SSMSTRMOPS_VERSION … … 1921 1952 pMine->pNext = NULL; 1922 1953 pMine->fEndOfStream = false; 1954 pMine->NanoTS = RTTimeNanoTS(); 1923 1955 return pMine; 1924 1956 } … … 2099 2131 2100 2132 /* flush */ 2101 int rc = pStrm->pOps->pfnWrite(pStrm->pvUser, pCur->offStream, &pCur->abData[0], pCur->cb); 2133 int rc = pStrm->pOps->pfnIsOk(pStrm->pvUser); 2134 if (RT_SUCCESS(rc)) 2135 rc = pStrm->pOps->pfnWrite(pStrm->pvUser, pCur->offStream, &pCur->abData[0], pCur->cb); 2102 2136 if ( RT_FAILURE(rc) 2103 2137 && ssmR3StrmSetError(pStrm, rc)) 2104 LogRel(("ssmR3StrmWriteBuffers: RTFileWriteAtfailed with rc=%Rrc at offStream=%#llx\n", rc, pCur->offStream));2138 LogRel(("ssmR3StrmWriteBuffers: Write failed with rc=%Rrc at offStream=%#llx\n", rc, pCur->offStream)); 2105 2139 2106 2140 /* free */ … … 2535 2569 } 2536 2570 return NULL; 2571 } 2572 2573 2574 /** 2575 * Check that the stream is OK and flush data that is getting old 2576 * 2577 * The checking is mainly for testing for cancellation and out of space 2578 * conditions. 2579 * 2580 * @returns VBox status code. 2581 * @param pStrm The stream handle. 2582 */ 2583 static int ssmR3StrmCheckAndFlush(PSSMSTRM pStrm) 2584 { 2585 int rc = pStrm->pOps->pfnIsOk(pStrm->pvUser); 2586 if (RT_FAILURE(rc)) 2587 return rc; 2588 2589 if ( pStrm->fWrite 2590 && pStrm->hIoThread != NIL_RTTHREAD 2591 && !pStrm->pHead /* the worker is probably idle */ 2592 && pStrm->pCur 2593 && RTTimeNanoTS() - pStrm->pCur->NanoTS > 500*1000*1000 /* 0.5s */ 2594 ) 2595 ssmR3StrmFlushCurBuf(pStrm); 2596 return VINF_SUCCESS; 2537 2597 } 2538 2598 … … 4964 5024 4965 5025 /* 4966 * Check that the re is still some space left on the disk.5026 * Check that the stream is still OK. 4967 5027 */ 4968 /** @todo move this to the stream flushing code? It's not perfect when done 4969 * here, it could be way better if we did it there. */ 4970 if (pSSM->pszFilename) 4971 { 4972 RTFOFF cbFree; 4973 rc = RTFsQuerySizes(pSSM->pszFilename, NULL, &cbFree, NULL, NULL); 4974 AssertRC(rc); 4975 #define SSM_MIN_DISK_FREE ((RTFOFF)( 10 * _1M )) 4976 if ( RT_SUCCESS(rc) 4977 && cbFree < SSM_MIN_DISK_FREE) 4978 { 4979 LogRel(("SSM: Giving up: Low on disk space. (cbFree=%RTfoff, SSM_MIN_DISK_FREE=%RTfoff).\n", 4980 cbFree, SSM_MIN_DISK_FREE)); 4981 return pSSM->rc = VERR_SSM_LOW_ON_DISK_SPACE; 4982 } 4983 } 5028 rc = ssmR3StrmCheckAndFlush(&pSSM->Strm); 5029 if (RT_FAILURE(rc)) 5030 return pSSM->rc = rc; 4984 5031 } 4985 5032
Note:
See TracChangeset
for help on using the changeset viewer.