Changeset 21900 in vbox
- Timestamp:
- Jul 30, 2009 5:31:36 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/SSM-new.cpp
r21897 r21900 324 324 /** The handle of the I/O thread. This is set to nil when not active. */ 325 325 RTTHREAD hIoThread; 326 /** Where to seek to. */ 327 uint64_t offNeedSeekTo; 326 328 327 329 /** The head of the consumer queue. … … 750 752 static int ssmR3Register(PVM pVM, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess, const char *pszBefore, PSSMUNIT *ppUnit); 751 753 static int ssmR3StrmWriteBuffers(PSSMSTRM pStrm); 754 static int ssmR3StrmReadMore(PSSMSTRM pStrm); 752 755 static int ssmR3CalcChecksum(RTFILE File, uint64_t cbFile, uint32_t *pu32CRC); 753 756 static void ssmR3Progress(PSSMHANDLE pSSM, uint64_t cbAdvance); … … 1369 1372 pStrm->rc = VINF_SUCCESS; 1370 1373 pStrm->hIoThread = NIL_RTTHREAD; 1374 pStrm->offNeedSeekTo= UINT64_MAX; 1371 1375 1372 1376 pStrm->pHead = NULL; … … 1655 1659 if (RT_FAILURE(pStrm->rc)) 1656 1660 return NULL; 1661 if ( !pStrm->fWrite 1662 && pStrm->hIoThread == NIL_RTTHREAD) 1663 { 1664 int rc = ssmR3StrmReadMore(pStrm); 1665 if (RT_FAILURE(rc)) 1666 return NULL; 1667 continue; 1668 } 1669 1657 1670 int rc = RTSemEventWaitNoResume(pStrm->hEvtHead, 30000); 1658 1671 if ( rc == VERR_SEM_DESTROYED … … 1687 1700 cb - pStrm->offStreamCRC); 1688 1701 pStrm->offCurStream += cb; 1689 pStrm->off = 0;1690 pStrm->offStreamCRC = 0;1702 pStrm->off = 0; 1703 pStrm->offStreamCRC = 0; 1691 1704 1692 1705 ssmR3StrmPutBuf(pStrm, pBuf); … … 1701 1714 cb - pStrm->offStreamCRC); 1702 1715 pStrm->offCurStream += cb; 1703 pStrm->off = 0;1704 pStrm->offStreamCRC = 0;1716 pStrm->off = 0; 1717 pStrm->offStreamCRC = 0; 1705 1718 1706 1719 ssmR3StrmPutFreeBuf(pStrm, pBuf); … … 1767 1780 { 1768 1781 /* 1769 * Flush and close the stream.1782 * Flush, terminate the I/O thread, and close the stream. 1770 1783 */ 1771 1784 if (pStrm->fWrite) 1772 1785 { 1773 1786 ssmR3StrmFlushCurBuf(pStrm); 1774 ssmR3StrmWriteBuffers(pStrm); 1775 } 1787 if (pStrm->hIoThread == NIL_RTTHREAD) 1788 ssmR3StrmWriteBuffers(pStrm); 1789 } 1790 1791 if (pStrm->hIoThread != NIL_RTTHREAD) 1792 { 1793 ASMAtomicWriteBool(&pStrm->fTerminating, true); 1794 int rc2 = RTSemEventSignal(pStrm->fWrite ? pStrm->hEvtHead : pStrm->hEvtFree); AssertLogRelRC(rc2); 1795 int rc3 = RTThreadWait(pStrm->hIoThread, RT_INDEFINITE_WAIT, NULL); AssertLogRelRC(rc3); 1796 pStrm->hIoThread = NIL_RTTHREAD; 1797 } 1798 1776 1799 int rc = RTFileClose(pStrm->hFile); 1777 1800 if (RT_FAILURE(rc)) … … 1922 1945 * Read more from the stream. 1923 1946 * 1924 * @returns VBox status code. VERR_EOF is passed up.1947 * @returns VBox status code. VERR_EOF gets translated into VINF_EOF. 1925 1948 * @param pStrm The stream handle. 1926 1949 * 1927 * @thread The I/O thread when we g et one.1950 * @thread The I/O thread when we got one, otherwise the stream user. 1928 1951 */ 1929 1952 static int ssmR3StrmReadMore(PSSMSTRM pStrm) 1930 1953 { 1931 1954 int rc; 1955 Log6(("ssmR3StrmReadMore:\n")); 1932 1956 1933 1957 /* … … 1936 1960 if (pStrm->fNeedSeek) 1937 1961 { 1938 rc = RTFileSeek(pStrm->hFile, pStrm->off CurStream + pStrm->off, RTFILE_SEEK_BEGIN, NULL);1962 rc = RTFileSeek(pStrm->hFile, pStrm->offNeedSeekTo, RTFILE_SEEK_BEGIN, NULL); 1939 1963 if (RT_FAILURE(rc)) 1940 1964 { 1941 1965 if (ssmR3StrmSetError(pStrm, rc)) 1942 LogRel(("ssmR3StrmReadMore: RTFileSeek(,%#llx,) failed with rc=%Rrc\n", pStrm->off CurStream + pStrm->off, rc));1966 LogRel(("ssmR3StrmReadMore: RTFileSeek(,%#llx,) failed with rc=%Rrc\n", pStrm->offNeedSeekTo, rc)); 1943 1967 return rc; 1944 1968 } 1945 1969 pStrm->fNeedSeek = false; 1970 pStrm->offNeedSeekTo = UINT64_MAX; 1946 1971 } 1947 1972 … … 1953 1978 return pStrm->rc; 1954 1979 1955 pBuf->offStream = pStrm->offCurStream + pStrm->off; 1956 Assert(pBuf->offStream == RTFileTell(pStrm->hFile)); 1980 pBuf->offStream = RTFileTell(pStrm->hFile); 1957 1981 size_t cbRead = sizeof(pBuf->abData); 1958 1982 rc = RTFileRead(pStrm->hFile, &pBuf->abData[0], cbRead, &cbRead); 1959 if (RT_SUCCESS(rc)) 1983 if ( RT_SUCCESS(rc) 1984 && cbRead > 0) 1960 1985 { 1961 1986 pBuf->cb = (uint32_t)cbRead; 1962 pBuf->fEndOfStream = cbRead == 0; /** @todo Check out this EOF mess... */ 1987 pBuf->fEndOfStream = false; 1988 Log6(("ssmR3StrmReadMore: %#010llx %#x\n", pBuf->offStream, pBuf->cb)); 1963 1989 ssmR3StrmPutBuf(pStrm, pBuf); 1964 1990 } 1965 else if (rc == VERR_EOF) 1991 else if ( ( RT_SUCCESS_NP(rc) 1992 && cbRead == 0) 1993 || rc == VERR_EOF) 1966 1994 { 1967 1995 pBuf->cb = 0; 1968 1996 pBuf->fEndOfStream = true; 1997 Log6(("ssmR3StrmReadMore: %#010llx 0 EOF!\n", pBuf->offStream)); 1969 1998 ssmR3StrmPutBuf(pStrm, pBuf); 1999 rc = VINF_EOF; 1970 2000 } 1971 2001 else 1972 2002 { 2003 Log6(("ssmR3StrmReadMore: %#010llx rc=%Rrc!\n", pBuf->offStream, rc)); 1973 2004 if (ssmR3StrmSetError(pStrm, rc)) 1974 2005 LogRel(("ssmR3StrmReadMore: RTFileRead(,,%#x,) -> %Rrc at offset %#llx\n", … … 2037 2068 */ 2038 2069 ssmR3StrmFlushCurBuf(pStrm); 2039 if (pStrm->hIoThread == NIL_RTTHREAD)2040 {2041 rc = ssmR3StrmReadMore(pStrm);2042 if (RT_FAILURE(rc))2043 break;2044 }2045 2070 PSSMSTRMBUF pBuf = ssmR3StrmGetBuf(pStrm); 2046 2071 if (!pBuf) … … 2195 2220 { 2196 2221 pStrm->fNeedSeek = false; 2222 pStrm->offNeedSeekTo= UINT64_MAX; 2197 2223 pStrm->offCurStream = offStream; 2198 2224 pStrm->off = 0; … … 2288 2314 AssertReturn(pStrm->hIoThread == NIL_RTTHREAD, VERR_WRONG_ORDER); 2289 2315 2290 pStrm->fNeedSeek = true; 2316 if (!pStrm->fNeedSeek) 2317 { 2318 pStrm->fNeedSeek = true; 2319 pStrm->offNeedSeekTo = pStrm->offCurStream + (pStrm->pCur ? pStrm->pCur->cb : 0); 2320 } 2321 2291 2322 int rc = RTFileSeek(pStrm->hFile, off, off >= 0 ? RTFILE_SEEK_BEGIN : RTFILE_SEEK_END, poff); 2292 2323 if (RT_SUCCESS(rc)) … … 2294 2325 2295 2326 return rc; 2327 } 2328 2329 2330 /** 2331 * The I/O thread. 2332 * 2333 * @returns VINF_SUCCESS (ignored). 2334 * @param hSelf The thread handle. 2335 * @param pvStrm The stream handle. 2336 */ 2337 static DECLCALLBACK(int) ssmR3StrmIoThread(RTTHREAD hSelf, void *pvStrm) 2338 { 2339 PSSMSTRM pStrm = (PSSMSTRM)pvStrm; 2340 ASMAtomicWriteHandle(&pStrm->hIoThread, hSelf); /* paranoia */ 2341 2342 Log(("ssmR3StrmIoThread: starts working\n")); 2343 if (pStrm->fWrite) 2344 { 2345 /* 2346 * Write until error or terminated. 2347 */ 2348 for (;;) 2349 { 2350 2351 } 2352 } 2353 else 2354 { 2355 /* 2356 * Read until end of file, error or termination. 2357 */ 2358 for (;;) 2359 { 2360 if (ASMAtomicReadBool(&pStrm->fTerminating)) 2361 { 2362 Log(("ssmR3StrmIoThread: quitting reading because of pending termination.\n")); 2363 break; 2364 } 2365 2366 int rc = ssmR3StrmReadMore(pStrm); 2367 if ( RT_FAILURE(rc) 2368 || rc == VINF_EOF) 2369 { 2370 Log(("ssmR3StrmIoThread: quitting reading with rc=%Rrc\n", rc)); 2371 break; 2372 } 2373 if (RT_FAILURE(pStrm->rc)) 2374 { 2375 Log(("ssmR3StrmIoThread: quitting reading with stream rc=%Rrc\n", pStrm->rc)); 2376 break; 2377 } 2378 } 2379 } 2380 2381 return VINF_SUCCESS; 2382 } 2383 2384 2385 /** 2386 * Starts the I/O thread for the specified stream. 2387 * 2388 * @param pStrm The stream handle. 2389 */ 2390 static void ssmR3StrmStartIoThread(PSSMSTRM pStrm) 2391 { 2392 Assert(pStrm->hIoThread == NIL_RTTHREAD); 2393 2394 RTTHREAD hThread; 2395 int rc = RTThreadCreate(&hThread, ssmR3StrmIoThread, pStrm, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SSM-IO"); 2396 AssertRCReturnVoid(rc); 2397 ASMAtomicWriteHandle(&pStrm->hIoThread, hThread); /* paranoia */ 2296 2398 } 2297 2399 … … 3575 3677 if (RT_SUCCESS(rc)) 3576 3678 { 3679 ssmR3StrmStartIoThread(&Handle.Strm); 3680 3577 3681 Handle.enmAfter = enmAfter; 3578 3682 Handle.pfnProgress = pfnProgress;
Note:
See TracChangeset
for help on using the changeset viewer.