Changeset 33945 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Nov 10, 2010 5:49:56 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 67606
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/Makefile.kmk
r33887 r33945 370 370 common/time/timesup.cpp \ 371 371 common/vfs/vfsbase.cpp \ 372 common/vfs/vfschain.cpp \ 372 373 common/vfs/vfsstdfile.cpp \ 373 374 common/zip/zipgzip.cpp \ -
trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
r33911 r33945 48 48 * Defined Constants And Macros * 49 49 *******************************************************************************/ 50 #define RTVFS_MAGIC UINT32_C(0x11112222) 50 #define RTVFSOBJ_MAGIC UINT32_C(0x20109901) 51 #define RTVFSOBJ_MAGIC_DEAD (~RTVFSOBJ_MAGIC) 52 #define RTVFS_MAGIC UINT32_C(0x20109902) 51 53 #define RTVFS_MAGIC_DEAD (~RTVFS_MAGIC) 52 #define RTVFSDIR_MAGIC UINT32_C(0x77778888) 54 #define RTVFSFSSTREAM_MAGIC UINT32_C(0x20109903) 55 #define RTVFSFSSTREAM_MAGIC_DEAD (~RTVFSFSSTREAM_MAGIC) 56 #define RTVFSDIR_MAGIC UINT32_C(0x20109904) 53 57 #define RTVFSDIR_MAGIC_DEAD (~RTVFSDIR_MAGIC) 54 #define RTVFSFILE_MAGIC UINT32_C(0x 55556666)58 #define RTVFSFILE_MAGIC UINT32_C(0x20109905) 55 59 #define RTVFSFILE_MAGIC_DEAD (~RTVFSFILE_MAGIC) 56 #define RTVFSIOSTREAM_MAGIC UINT32_C(0x 33334444)60 #define RTVFSIOSTREAM_MAGIC UINT32_C(0x20109906) 57 61 #define RTVFSIOSTREAM_MAGIC_DEAD (~RTVFSIOSTREAM_MAGIC) 58 #define RTVFSSYMLINK_MAGIC UINT32_C(0x 9999aaaa)62 #define RTVFSSYMLINK_MAGIC UINT32_C(0x20109907) 59 63 #define RTVFSSYMLINK_MAGIC_DEAD (~RTVFSSYMLINK_MAGIC) 60 64 … … 65 69 #define RTVFS_MAX_LINKS 20U 66 70 67 68 /** Takes a write lock. */69 #define RTVFS_WRITE_LOCK(hSemRW) \70 do { \71 if ((hSemRW) != NIL_RTSEMRW) \72 { \73 int rcSemEnter = RTSemRWRequestWrite(hSemRW, RT_INDEFINITE_WAIT); \74 AssertRC(rcSemEnter); \75 } \76 } while (0)77 78 /** Releases a write lock. */79 #define RTVFS_WRITE_UNLOCK(hSemRW) \80 do { \81 if ((hSemRW) != NIL_RTSEMRW) \82 { \83 int rcSemLeave = RTSemRWReleaseWrite(hSemRW); \84 AssertRC(rcSemLeave); \85 } \86 } while (0)87 88 /** Takes a read lock. */89 #define RTVFS_READ_LOCK(hSemRW) \90 do { \91 if ((hSemRW) != NIL_RTSEMRW) \92 { \93 int rcSemEnter = RTSemRWRequestRead(hSemRW, RT_INDEFINITE_WAIT); \94 AssertRC(rcSemEnter); \95 } \96 } while (0)97 98 /** Releases a read lock. */99 #define RTVFS_READ_UNLOCK(hSemRW) \100 do { \101 if ((hSemRW) != NIL_RTSEMRW) \102 { \103 int rcSemLeave = RTSemRWReleaseRead(hSemRW); \104 AssertRC(rcSemLeave); \105 } \106 } while (0)107 71 108 72 … … 113 77 114 78 /** 79 * The VFS base object handle data. 80 * 81 * All other VFS handles are derived from this one. The final handle type is 82 * indicated by RTVFSOBJOPS::enmType via the RTVFSOBJINTERNAL::pOps member. 83 */ 84 typedef struct RTVFSOBJINTERNAL 85 { 86 /** The VFS magic (RTVFSOBJ_MAGIC). */ 87 uint32_t uMagic; 88 /** The number of references to this VFS object. */ 89 uint32_t volatile cRefs; 90 /** Pointer to the instance data. */ 91 void *pvThis; 92 /** The vtable. */ 93 PCRTVFSOBJOPS pOps; 94 /** Read-write semaphore protecting all access to the VFS 95 * Only valid RTVFS_C_THREAD_SAFE is set, otherwise it is NIL_RTSEMRW. */ 96 RTSEMRW hSemRW; 97 /** Reference back to the VFS containing this object. */ 98 RTVFS hVfs; 99 } RTVFSOBJINTERNAL; 100 101 102 /** 103 * The VFS filesystem stream handle data. 104 * 105 * @extends RTVFSOBJINTERNAL 106 */ 107 typedef struct RTVFSFSSTREAMINTERNAL 108 { 109 /** The VFS magic (RTVFSFSTREAM_MAGIC). */ 110 uint32_t uMagic; 111 /** File open flags, at a minimum the access mask. */ 112 uint32_t fFlags; 113 /** The vtable. */ 114 PCRTVFSFSSTREAMOPS pOps; 115 /** The base object handle data. */ 116 RTVFSOBJINTERNAL Base; 117 } RTVFSFSSTREAMINTERNAL; 118 119 120 /** 115 121 * The VFS handle data. 122 * 123 * @extends RTVFSOBJINTERNAL 116 124 */ 117 125 typedef struct RTVFSINTERNAL … … 121 129 /** Creation flags (RTVFS_C_XXX). */ 122 130 uint32_t fFlags; 123 /** Pointer to the instance data. */124 void *pvThis;125 131 /** The vtable. */ 126 132 PCRTVFSOPS pOps; 127 /** Read-write semaphore protecting all access to the VFS 128 * Only valid RTVFS_C_THREAD_SAFE is set, otherwise it is NIL_RTSEMRW. */ 129 RTSEMRW hSemRW; 130 /** The number of references to this VFS. 131 * This count includes objects within the file system, so that the VFS 132 * won't be destroyed before all objects are closed. */ 133 uint32_t volatile cRefs; 133 /** The base object handle data. */ 134 RTVFSOBJINTERNAL Base; 134 135 } RTVFSINTERNAL; 135 136 … … 137 138 /** 138 139 * The VFS directory handle data. 140 * 141 * @extends RTVFSOBJINTERNAL 139 142 */ 140 143 typedef struct RTVFSDIRINTERNAL … … 144 147 /** Reserved for flags or something. */ 145 148 uint32_t fReserved; 146 /** Pointer to the instance data. */147 void *pvThis;148 149 /** The vtable. */ 149 150 PCRTVFSDIROPS pOps; 150 /** The VFS RW sem if serialized. */ 151 RTSEMRW hSemRW; 152 /** Reference back to the VFS containing this directory. */ 153 RTVFS hVfs; 154 /** The number of references to this directory handle. This does not 155 * include files or anything. */ 156 uint32_t volatile cRefs; 151 /** The base object handle data. */ 152 RTVFSOBJINTERNAL Base; 157 153 } RTVFSDIRINTERNAL; 158 154 … … 160 156 /** 161 157 * The VFS symbolic link handle data. 158 * 159 * @extends RTVFSOBJINTERNAL 162 160 */ 163 161 typedef struct RTVFSSYMLINKINTERNAL … … 167 165 /** Reserved for flags or something. */ 168 166 uint32_t fReserved; 169 /** Pointer to the instance data. */170 void *pvThis;171 167 /** The vtable. */ 172 168 PCRTVFSSYMLINKOPS pOps; 173 /** The VFS RW sem if serialized. */ 174 RTSEMRW hSemRW; 175 /** Reference back to the VFS containing this symbolic link. */ 176 RTVFS hVfs; 177 /** The number of references to this symbolic link handle. */ 178 uint32_t volatile cRefs; 169 /** The base object handle data. */ 170 RTVFSOBJINTERNAL Base; 179 171 } RTVFSSYMLINKINTERNAL; 180 172 … … 183 175 * The VFS I/O stream handle data. 184 176 * 185 * This is normally part of a type specific handle, like a file or pipe. 177 * This is often part of a type specific handle, like a file or pipe. 178 * 179 * @extends RTVFSOBJINTERNAL 186 180 */ 187 181 typedef struct RTVFSIOSTREAMINTERNAL … … 191 185 /** File open flags, at a minimum the access mask. */ 192 186 uint32_t fFlags; 193 /** Pointer to the instance data. */194 void *pvThis;195 187 /** The vtable. */ 196 188 PCRTVFSIOSTREAMOPS pOps; 197 /** The VFS RW sem if serialized. */ 198 RTSEMRW hSemRW; 199 /** Reference back to the VFS containing this directory. */ 200 RTVFS hVfs; 201 /** The number of references to this file VFS. */ 202 uint32_t volatile cRefs; 189 /** The base object handle data. */ 190 RTVFSOBJINTERNAL Base; 203 191 } RTVFSIOSTREAMINTERNAL; 204 192 … … 221 209 } RTVFSFILEINTERNAL; 222 210 211 #if 0 /* later */ 212 213 /** 214 * The VFS pipe handle data. 215 * 216 * @extends RTVFSIOSTREAMINTERNAL 217 */ 218 typedef struct RTVFSPIPEINTERNAL 219 { 220 /** The VFS magic (RTVFSPIPE_MAGIC). */ 221 uint32_t uMagic; 222 /** Reserved for flags or something. */ 223 uint32_t fReserved; 224 /** The vtable. */ 225 PCRTVFSPIPEOPS pOps; 226 /** The stream handle data. */ 227 RTVFSIOSTREAMINTERNAL Stream; 228 } RTVFSPIPEINTERNAL; 229 230 231 /** 232 * The VFS socket handle data. 233 * 234 * @extends RTVFSIOSTREAMINTERNAL 235 */ 236 typedef struct RTVFSSOCKETINTERNAL 237 { 238 /** The VFS magic (RTVFSSOCKET_MAGIC). */ 239 uint32_t uMagic; 240 /** Reserved for flags or something. */ 241 uint32_t fReserved; 242 /** The vtable. */ 243 PCRTVFSSOCKETOPS pOps; 244 /** The stream handle data. */ 245 RTVFSIOSTREAMINTERNAL Stream; 246 } RTVFSSOCKETINTERNAL; 247 248 #endif /* later */ 249 250 251 /* 252 * 253 * B A S E O B J E C T 254 * B A S E O B J E C T 255 * B A S E O B J E C T 256 * 257 */ 258 259 /** 260 * Write locks the object. 261 * 262 * @param pThis The object to lock. 263 */ 264 DECLINLINE(void) rtVfsObjWriteLock(RTVFSOBJINTERNAL *pThis) 265 { 266 if (pThis->hSemRW != NIL_RTSEMRW) 267 { 268 int rc = RTSemRWRequestWrite(pThis->hSemRW, RT_INDEFINITE_WAIT); 269 AssertRC(rc); 270 } 271 } 272 273 274 /** 275 * Undoing the effects of rtVfsObjWriteLock. 276 * 277 * @param pThis The object to lock. 278 */ 279 DECLINLINE(void) rtVfsObjWriteUnlock(RTVFSOBJINTERNAL *pThis) 280 { 281 if (pThis->hSemRW != NIL_RTSEMRW) 282 { 283 int rc = RTSemRWReleaseWrite(pThis->hSemRW); 284 AssertRC(rc); 285 } 286 } 287 288 /** 289 * Read locks the object. 290 * 291 * @param pThis The object to lock. 292 */ 293 DECLINLINE(void) rtVfsObjReadLock(RTVFSOBJINTERNAL *pThis) 294 { 295 if (pThis->hSemRW != NIL_RTSEMRW) 296 { 297 int rc = RTSemRWRequestRead(pThis->hSemRW, RT_INDEFINITE_WAIT); 298 AssertRC(rc); 299 } 300 } 301 302 303 /** 304 * Undoing the effects of rtVfsObjReadLock. 305 * 306 * @param pThis The object to lock. 307 */ 308 DECLINLINE(void) rtVfsObjReadUnlock(RTVFSOBJINTERNAL *pThis) 309 { 310 if (pThis->hSemRW != NIL_RTSEMRW) 311 { 312 int rc = RTSemRWReleaseRead(pThis->hSemRW); 313 AssertRC(rc); 314 } 315 } 316 223 317 224 318 225 319 /** 226 320 * Internal object retainer that asserts sanity in strict builds. 321 * 322 * @returns The new reference count. 323 * @param pThis The base object handle data. 324 */ 325 DECLINLINE(uint32_t) rtVfsObjRetain(RTVFSOBJINTERNAL *pThis) 326 { 327 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs); 328 AssertMsg(cRefs > 1 && cRefs < _1M, 329 ("%#x %p ops=%p %s (%d)\n", cRefs, pThis, pThis->pOps, pThis->pOps->pszName, pThis->pOps->enmType)); 330 return cRefs; 331 } 332 333 334 /** 335 * Internal object retainer that asserts sanity in strict builds. 336 * 337 * @param pThis The base object handle data. 338 */ 339 DECLINLINE(void) rtVfsObjRetainVoid(RTVFSOBJINTERNAL *pThis) 340 { 341 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs); 342 AssertMsg(cRefs > 1 && cRefs < _1M, 343 ("%#x %p ops=%p %s (%d)\n", cRefs, pThis, pThis->pOps, pThis->pOps->pszName, pThis->pOps->enmType)); 344 NOREF(cRefs); 345 } 346 347 348 RTDECL(uint32_t) RTVfsObjRetain(RTVFSOBJ hVfsObj) 349 { 350 RTVFSOBJINTERNAL *pThis = hVfsObj; 351 AssertPtrReturn(pThis, UINT32_MAX); 352 AssertReturn(pThis->uMagic == RTVFSOBJ_MAGIC, UINT32_MAX); 353 354 return rtVfsObjRetain(pThis); 355 } 356 357 358 /** 359 * Does the actual object destruction for rtVfsObjRelease(). 360 * 361 * @param pThis The object to destroy. 362 */ 363 static void rtVfsObjDestroy(RTVFSOBJINTERNAL *pThis) 364 { 365 RTVFSOBJTYPE const enmType = pThis->pOps->enmType; 366 367 /* 368 * Invalidate the object. 369 */ 370 rtVfsObjWriteLock(pThis); /* paranoia */ 371 switch (enmType) 372 { 373 case RTVFSOBJTYPE_BASE: 374 break; 375 376 case RTVFSOBJTYPE_VFS: 377 ASMAtomicWriteU32(&RT_FROM_MEMBER(pThis, RTVFSINTERNAL, Base)->uMagic, RTVFS_MAGIC_DEAD); 378 break; 379 380 case RTVFSOBJTYPE_FS_STREAM: 381 ASMAtomicWriteU32(&RT_FROM_MEMBER(pThis, RTVFSFSSTREAMINTERNAL, Base)->uMagic, RTVFSFSSTREAM_MAGIC_DEAD); 382 break; 383 384 case RTVFSOBJTYPE_IO_STREAM: 385 ASMAtomicWriteU32(&RT_FROM_MEMBER(pThis, RTVFSIOSTREAMINTERNAL, Base)->uMagic, RTVFSIOSTREAM_MAGIC_DEAD); 386 break; 387 388 case RTVFSOBJTYPE_DIR: 389 ASMAtomicWriteU32(&RT_FROM_MEMBER(pThis, RTVFSDIRINTERNAL, Base)->uMagic, RTVFSDIR_MAGIC_DEAD); 390 break; 391 392 case RTVFSOBJTYPE_FILE: 393 ASMAtomicWriteU32(&RT_FROM_MEMBER(pThis, RTVFSIOSTREAMINTERNAL, Base)->uMagic, RTVFSIOSTREAM_MAGIC_DEAD); 394 ASMAtomicWriteU32(&RT_FROM_MEMBER(pThis, RTVFSFILEINTERNAL, Stream.Base)->uMagic, RTVFSFILE_MAGIC_DEAD); 395 break; 396 397 case RTVFSOBJTYPE_SYMLINK: 398 ASMAtomicWriteU32(&RT_FROM_MEMBER(pThis, RTVFSSYMLINKINTERNAL, Base)->uMagic, RTVFSSYMLINK_MAGIC_DEAD); 399 break; 400 401 case RTVFSOBJTYPE_INVALID: 402 case RTVFSOBJTYPE_END: 403 case RTVFSOBJTYPE_32BIT_HACK: 404 AssertMsgFailed(("enmType=%d ops=%p %s\n", enmType, pThis->pOps, pThis->pOps->pszName)); 405 break; 406 /* no default as we want gcc warnings. */ 407 } 408 ASMAtomicWriteU32(&pThis->uMagic, RTVFSOBJ_MAGIC_DEAD); 409 rtVfsObjWriteUnlock(pThis); 410 411 /* 412 * Close the object and free the handle. 413 */ 414 int rc = pThis->pOps->pfnClose(pThis->pvThis); 415 AssertRC(rc); 416 RTMemFree(pThis); 417 } 418 419 420 /** 421 * Internal object releaser that asserts sanity in strict builds. 227 422 * 228 423 * @returns The new reference count. 229 424 * @param pcRefs The reference counter. 230 425 */ 231 DECLINLINE(uint32_t) rtVfsRetain(uint32_t volatile *pcRefs) 232 { 233 uint32_t cRefs = ASMAtomicIncU32(pcRefs); 234 AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x\n", cRefs)); 426 DECLINLINE(uint32_t) rtVfsObjRelease(RTVFSOBJINTERNAL *pThis) 427 { 428 uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs); 429 AssertMsg(cRefs < _1M, ("%#x %p ops=%p %s (%d)\n", cRefs, pThis, pThis->pOps, pThis->pOps->pszName, pThis->pOps->enmType)); 430 if (cRefs == 0) 431 rtVfsObjDestroy(pThis); 235 432 return cRefs; 236 433 } 237 434 238 435 239 /** 240 * Internal object retainer that asserts sanity in strict builds. 241 * 242 * @param pcRefs The reference counter. 243 */ 244 DECLINLINE(void) rtVfsRetainVoid(uint32_t volatile *pcRefs) 245 { 246 (void)rtVfsRetain(pcRefs); 247 } 248 249 250 /** 251 * Internal object releaser that asserts sanity in strict builds. 252 * 253 * @returns The new reference count. 254 * @param pcRefs The reference counter. 255 */ 256 DECLINLINE(uint32_t) rtVfsRelease(uint32_t volatile *pcRefs) 257 { 258 uint32_t cRefs = ASMAtomicDecU32(pcRefs); 259 AssertMsg(cRefs < _1M, ("%#x\n", cRefs)); 260 return cRefs; 261 } 436 RTDECL(uint32_t) RTVfsObjRelease(RTVFSOBJ hVfsObj) 437 { 438 RTVFSOBJINTERNAL *pThis = hVfsObj; 439 AssertPtrReturn(pThis, UINT32_MAX); 440 AssertReturn(pThis->uMagic == RTVFSOBJ_MAGIC, UINT32_MAX); 441 return rtVfsObjRelease(pThis); 442 } 443 262 444 263 445 … … 527 709 AssertPtr(pThis); 528 710 Assert(pThis->uMagic == RTVFS_MAGIC); 529 Assert(pThis-> cRefs > 0);711 Assert(pThis->Base.cRefs > 0); 530 712 AssertPtr(pPath); 531 713 AssertPtr(ppVfsParentDir); … … 538 720 /** @todo Union mounts, traversal optimization methods, races, ++ */ 539 721 RTVFSDIRINTERNAL *pCurDir; 540 RTVFS_READ_LOCK(pThis->hSemRW);541 int rc = pThis->pOps->pfnOpenRoot(pThis-> pvThis, &pCurDir);542 RTVFS_READ_UNLOCK(pThis->hSemRW);722 rtVfsObjReadLock(&pThis->Base); 723 int rc = pThis->pOps->pfnOpenRoot(pThis->Base.pvThis, &pCurDir); 724 rtVfsObjReadUnlock(&pThis->Base); 543 725 if (RT_FAILURE(rc)) 544 726 return rc; … … 573 755 if (fFinal) 574 756 { 575 RTVFS_READ_LOCK(pCurDir->hSemRW);576 rc = pCurDir->pOps->pfnTraversalOpen(pCurDir-> pvThis, pszEntry, NULL, &hSymlink, NULL);577 RTVFS_READ_UNLOCK(pCurDir->hSemRW);757 rtVfsObjReadLock(&pCurDir->Base); 758 rc = pCurDir->pOps->pfnTraversalOpen(pCurDir->Base.pvThis, pszEntry, NULL, &hSymlink, NULL); 759 rtVfsObjReadUnlock(&pCurDir->Base); 578 760 *pszEntryEnd = '\0'; 579 761 if (rc == VERR_PATH_NOT_FOUND) … … 590 772 else 591 773 { 592 RTVFS_READ_LOCK(pCurDir->hSemRW);593 rc = pCurDir->pOps->pfnTraversalOpen(pCurDir-> pvThis, pszEntry, &hDir, &hSymlink, &hVfsMnt);594 RTVFS_READ_UNLOCK(pCurDir->hSemRW);774 rtVfsObjReadLock(&pCurDir->Base); 775 rc = pCurDir->pOps->pfnTraversalOpen(pCurDir->Base.pvThis, pszEntry, &hDir, &hSymlink, &hVfsMnt); 776 rtVfsObjReadUnlock(&pCurDir->Base); 595 777 *pszEntryEnd = '/'; 596 778 if (RT_FAILURE(rc)) … … 641 823 /* Must restart from the root (optimize this). */ 642 824 RTVfsDirRelease(pCurDir); 643 RTVFS_READ_LOCK(pThis->hSemRW);644 rc = pThis->pOps->pfnOpenRoot(pThis-> pvThis, &pCurDir);645 RTVFS_READ_UNLOCK(pThis->hSemRW);825 rtVfsObjReadLock(&pThis->Base); 826 rc = pThis->pOps->pfnOpenRoot(pThis->Base.pvThis, &pCurDir); 827 rtVfsObjReadUnlock(&pThis->Base); 646 828 if (RT_FAILURE(rc)) 647 829 { … … 658 840 */ 659 841 RTVfsDirRelease(pCurDir); 660 RTVFS_READ_LOCK(hVfsMnt->hSemRW);661 rc = pThis->pOps->pfnOpenRoot(hVfsMnt-> pvThis, &pCurDir);662 RTVFS_READ_UNLOCK(hVfsMnt->hSemRW);842 rtVfsObjReadLock(&hVfsMnt->Base); 843 rc = pThis->pOps->pfnOpenRoot(hVfsMnt->Base.pvThis, &pCurDir); 844 rtVfsObjReadUnlock(&hVfsMnt->Base); 663 845 if (RT_FAILURE(rc)) 664 846 { … … 692 874 AssertPtrReturn(pThis, UINT32_MAX); 693 875 AssertReturn(pThis->uMagic == RTVFSDIR_MAGIC, UINT32_MAX); 694 return rtVfs Retain(&pThis->cRefs);876 return rtVfsObjRetain(&pThis->Base); 695 877 } 696 878 … … 701 883 AssertPtrReturn(pThis, UINT32_MAX); 702 884 AssertReturn(pThis->uMagic == RTVFSDIR_MAGIC, UINT32_MAX); 703 704 uint32_t cRefs = rtVfsRelease(&pThis->cRefs); 705 if (!cRefs) 706 { 707 RTVFS_WRITE_LOCK(pThis->hSemRW); 708 ASMAtomicWriteU32(&pThis->uMagic, RTVFSDIR_MAGIC_DEAD); 709 RTVFS_WRITE_UNLOCK(pThis->hSemRW); 710 pThis->pOps->Obj.pfnClose(pThis->pvThis); 711 RTMemFree(pThis); 712 } 713 714 return cRefs; 885 return rtVfsObjRelease(&pThis->Base); 715 886 } 716 887 … … 730 901 AssertPtrReturn(pThis, UINT32_MAX); 731 902 AssertReturn(pThis->uMagic == RTVFSSYMLINK_MAGIC, UINT32_MAX); 732 return rtVfs Retain(&pThis->cRefs);903 return rtVfsObjRetain(&pThis->Base); 733 904 } 734 905 … … 739 910 AssertPtrReturn(pThis, UINT32_MAX); 740 911 AssertReturn(pThis->uMagic == RTVFSSYMLINK_MAGIC, UINT32_MAX); 741 742 uint32_t cRefs = rtVfsRelease(&pThis->cRefs); 743 if (!cRefs) 744 { 745 RTVFS_WRITE_LOCK(pThis->hSemRW); 746 ASMAtomicWriteU32(&pThis->uMagic, RTVFSSYMLINK_MAGIC_DEAD); 747 RTVFS_WRITE_UNLOCK(pThis->hSemRW); 748 pThis->pOps->Obj.pfnClose(pThis->pvThis); 749 RTMemFree(pThis); 750 } 751 752 return cRefs; 912 return rtVfsObjRelease(&pThis->Base); 753 913 } 754 914 … … 760 920 AssertReturn(pThis->uMagic == RTVFSSYMLINK_MAGIC, VERR_INVALID_HANDLE); 761 921 762 RTVFS_WRITE_LOCK(pThis->hSemRW);763 int rc = pThis->pOps->pfnRead(pThis-> pvThis, pszTarget, cbTarget);764 RTVFS_WRITE_UNLOCK(pThis->hSemRW);922 rtVfsObjWriteLock(&pThis->Base); 923 int rc = pThis->pOps->pfnRead(pThis->Base.pvThis, pszTarget, cbTarget); 924 rtVfsObjWriteUnlock(&pThis->Base); 765 925 766 926 return rc; … … 809 969 return VERR_NO_MEMORY; 810 970 811 pThis->uMagic = RTVFSIOSTREAM_MAGIC; 812 pThis->fFlags = fOpen; 813 pThis->pvThis = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT); 814 pThis->pOps = pIoStreamOps; 815 pThis->hSemRW = hSemRW != NIL_RTSEMRW ? hSemRW : pVfs ? pVfs->hSemRW : NIL_RTSEMRW; 816 pThis->hVfs = hVfs; 817 pThis->cRefs = 1; 971 pThis->uMagic = RTVFSIOSTREAM_MAGIC; 972 pThis->fFlags = fOpen; 973 pThis->pOps = pIoStreamOps; 974 pThis->Base.uMagic = RTVFSOBJ_MAGIC; 975 pThis->Base.pvThis = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT); 976 pThis->Base.hSemRW = hSemRW != NIL_RTSEMRW ? hSemRW : pVfs ? pVfs->Base.hSemRW : NIL_RTSEMRW; 977 pThis->Base.hVfs = hVfs; 978 pThis->Base.cRefs = 1; 818 979 if (hVfs != NIL_RTVFS) 819 rtVfs RetainVoid(&pVfs->cRefs);980 rtVfsObjRetainVoid(&pVfs->Base); 820 981 821 982 *phVfsIos = pThis; 822 *ppvInstance = pThis-> pvThis;983 *ppvInstance = pThis->Base.pvThis; 823 984 return VINF_SUCCESS; 824 985 } … … 830 991 AssertPtrReturn(pThis, UINT32_MAX); 831 992 AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, UINT32_MAX); 832 return rtVfs Retain(&pThis->cRefs);993 return rtVfsObjRetain(&pThis->Base); 833 994 } 834 995 … … 839 1000 AssertPtrReturn(pThis, UINT32_MAX); 840 1001 AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, UINT32_MAX); 841 842 uint32_t cRefs = rtVfsRelease(&pThis->cRefs); 843 if (!cRefs) 844 { 845 /* 846 * That was the last reference, close the stream. 847 * 848 * This is a little bit more complicated than when releasing a file or 849 * directory handle because the I/O stream can be a sub-object and we 850 * need to get to the real one before handing it to RTMemFree. 851 */ 852 RTVFS_WRITE_LOCK(pThis->hSemRW); 853 ASMAtomicWriteU32(&pThis->uMagic, RTVFSIOSTREAM_MAGIC_DEAD); 854 RTVFS_WRITE_UNLOCK(pThis->hSemRW); 855 pThis->pOps->Obj.pfnClose(pThis->pvThis); 856 857 switch (pThis->pOps->Obj.enmType) 858 { 859 case RTVFSOBJTYPE_IOSTREAM: 860 RTMemFree(pThis); 861 break; 862 863 case RTVFSOBJTYPE_FILE: 864 { 865 RTVFSFILEINTERNAL *pThisFile = RT_FROM_MEMBER(pThis, RTVFSFILEINTERNAL, Stream); 866 ASMAtomicWriteU32(&pThisFile->uMagic, RTVFSIOSTREAM_MAGIC_DEAD); 867 RTMemFree(pThisFile); 868 break; 869 } 870 871 /* Add new I/O stream compatible handle types here. */ 872 873 default: 874 AssertMsgFailed(("%d\n", pThis->pOps->Obj.enmType)); 875 break; 876 } 877 } 878 879 return cRefs; 880 1002 return rtVfsObjRelease(&pThis->Base); 881 1003 } 882 1004 … … 890 1012 if (pThis->pOps->Obj.enmType == RTVFSOBJTYPE_FILE) 891 1013 { 892 rtVfs RetainVoid(&pThis->cRefs);1014 rtVfsObjRetainVoid(&pThis->Base); 893 1015 return RT_FROM_MEMBER(pThis, RTVFSFILEINTERNAL, Stream); 894 1016 } … … 905 1027 AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE); 906 1028 907 RTVFS_READ_LOCK(pThis->hSemRW);908 int rc = pThis->pOps->Obj.pfnQueryInfo(pThis-> pvThis, pObjInfo, enmAddAttr);909 RTVFS_READ_UNLOCK(pThis->hSemRW);1029 rtVfsObjReadLock(&pThis->Base); 1030 int rc = pThis->pOps->Obj.pfnQueryInfo(pThis->Base.pvThis, pObjInfo, enmAddAttr); 1031 rtVfsObjReadUnlock(&pThis->Base); 910 1032 return rc; 911 1033 } … … 925 1047 RTSgBufInit(&SgBuf, &Seg, 1); 926 1048 927 RTVFS_WRITE_LOCK(pThis->hSemRW);928 int rc = pThis->pOps->pfnRead(pThis-> pvThis, -1 /*off*/, &SgBuf, pcbRead == NULL /*fBlocking*/, pcbRead);929 RTVFS_WRITE_UNLOCK(pThis->hSemRW);1049 rtVfsObjWriteLock(&pThis->Base); 1050 int rc = pThis->pOps->pfnRead(pThis->Base.pvThis, -1 /*off*/, &SgBuf, pcbRead == NULL /*fBlocking*/, pcbRead); 1051 rtVfsObjWriteUnlock(&pThis->Base); 930 1052 return rc; 931 1053 } … … 945 1067 RTSgBufInit(&SgBuf, &Seg, 1); 946 1068 947 RTVFS_WRITE_LOCK(pThis->hSemRW);948 int rc = pThis->pOps->pfnWrite(pThis-> pvThis, -1 /*off*/, &SgBuf, pcbWritten == NULL /*fBlocking*/, pcbWritten);949 RTVFS_WRITE_UNLOCK(pThis->hSemRW);1069 rtVfsObjWriteLock(&pThis->Base); 1070 int rc = pThis->pOps->pfnWrite(pThis->Base.pvThis, -1 /*off*/, &SgBuf, pcbWritten == NULL /*fBlocking*/, pcbWritten); 1071 rtVfsObjWriteUnlock(&pThis->Base); 950 1072 return rc; 951 1073 } … … 963 1085 AssertReturn(fBlocking || pcbRead, VERR_INVALID_PARAMETER); 964 1086 965 RTVFS_WRITE_LOCK(pThis->hSemRW);966 int rc = pThis->pOps->pfnRead(pThis-> pvThis, -1 /*off*/, pSgBuf, fBlocking, pcbRead);967 RTVFS_WRITE_UNLOCK(pThis->hSemRW);1087 rtVfsObjWriteLock(&pThis->Base); 1088 int rc = pThis->pOps->pfnRead(pThis->Base.pvThis, -1 /*off*/, pSgBuf, fBlocking, pcbRead); 1089 rtVfsObjWriteUnlock(&pThis->Base); 968 1090 return rc; 969 1091 } … … 981 1103 AssertReturn(fBlocking || pcbWritten, VERR_INVALID_PARAMETER); 982 1104 983 RTVFS_WRITE_LOCK(pThis->hSemRW);984 int rc = pThis->pOps->pfnWrite(pThis-> pvThis, -1 /*off*/, pSgBuf, fBlocking, pcbWritten);985 RTVFS_WRITE_UNLOCK(pThis->hSemRW);1105 rtVfsObjWriteLock(&pThis->Base); 1106 int rc = pThis->pOps->pfnWrite(pThis->Base.pvThis, -1 /*off*/, pSgBuf, fBlocking, pcbWritten); 1107 rtVfsObjWriteUnlock(&pThis->Base); 986 1108 return rc; 987 1109 } … … 994 1116 AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE); 995 1117 996 RTVFS_WRITE_LOCK(pThis->hSemRW);997 int rc = pThis->pOps->pfnFlush(pThis-> pvThis);998 RTVFS_WRITE_UNLOCK(pThis->hSemRW);1118 rtVfsObjWriteLock(&pThis->Base); 1119 int rc = pThis->pOps->pfnFlush(pThis->Base.pvThis); 1120 rtVfsObjWriteUnlock(&pThis->Base); 999 1121 return rc; 1000 1122 } … … 1008 1130 AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE); 1009 1131 1010 RTVFS_WRITE_LOCK(pThis->hSemRW);1011 int rc = pThis->pOps->pfnPollOne(pThis-> pvThis, fEvents, cMillies, fIntr, pfRetEvents);1012 RTVFS_WRITE_UNLOCK(pThis->hSemRW);1132 rtVfsObjWriteLock(&pThis->Base); 1133 int rc = pThis->pOps->pfnPollOne(pThis->Base.pvThis, fEvents, cMillies, fIntr, pfRetEvents); 1134 rtVfsObjWriteUnlock(&pThis->Base); 1013 1135 return rc; 1014 1136 } … … 1022 1144 1023 1145 RTFOFF off; 1024 RTVFS_READ_LOCK(pThis->hSemRW);1025 int rc = pThis->pOps->pfnTell(pThis-> pvThis, &off);1026 RTVFS_READ_UNLOCK(pThis->hSemRW);1146 rtVfsObjReadLock(&pThis->Base); 1147 int rc = pThis->pOps->pfnTell(pThis->Base.pvThis, &off); 1148 rtVfsObjReadUnlock(&pThis->Base); 1027 1149 if (RT_FAILURE(rc)) 1028 1150 off = rc; … … 1041 1163 if (pThis->pOps->pfnSkip) 1042 1164 { 1043 RTVFS_WRITE_LOCK(pThis->hSemRW);1044 rc = pThis->pOps->pfnSkip(pThis-> pvThis, cb);1045 RTVFS_WRITE_UNLOCK(pThis->hSemRW);1165 rtVfsObjWriteLock(&pThis->Base); 1166 rc = pThis->pOps->pfnSkip(pThis->Base.pvThis, cb); 1167 rtVfsObjWriteUnlock(&pThis->Base); 1046 1168 } 1047 1169 else … … 1054 1176 { 1055 1177 size_t cbToRead = RT_MIN(cb, _64K); 1056 RTVFS_WRITE_LOCK(pThis->hSemRW);1178 rtVfsObjWriteLock(&pThis->Base); 1057 1179 rc = RTVfsIoStrmRead(hVfsIos, pvBuf, cbToRead, NULL); 1058 RTVFS_WRITE_UNLOCK(pThis->hSemRW);1180 rtVfsObjWriteUnlock(&pThis->Base); 1059 1181 if (RT_FAILURE(rc)) 1060 1182 break; … … 1080 1202 if (pThis->pOps->pfnSkip) 1081 1203 { 1082 RTVFS_WRITE_LOCK(pThis->hSemRW);1083 rc = pThis->pOps->pfnZeroFill(pThis-> pvThis, cb);1084 RTVFS_WRITE_UNLOCK(pThis->hSemRW);1204 rtVfsObjWriteLock(&pThis->Base); 1205 rc = pThis->pOps->pfnZeroFill(pThis->Base.pvThis, cb); 1206 rtVfsObjWriteUnlock(&pThis->Base); 1085 1207 } 1086 1208 else … … 1093 1215 { 1094 1216 size_t cbToWrite = RT_MIN(cb, _64K); 1095 RTVFS_WRITE_LOCK(pThis->hSemRW);1217 rtVfsObjWriteLock(&pThis->Base); 1096 1218 rc = RTVfsIoStrmWrite(hVfsIos, pvBuf, cbToWrite, NULL); 1097 RTVFS_WRITE_UNLOCK(pThis->hSemRW);1219 rtVfsObjWriteUnlock(&pThis->Base); 1098 1220 if (RT_FAILURE(rc)) 1099 1221 break; … … 1154 1276 return VERR_NO_MEMORY; 1155 1277 1156 pThis->uMagic = RTVFSFILE_MAGIC;1157 pThis->fReserved = 0;1158 pThis->pOps = pFileOps;1159 pThis->Stream.uMagic = RTVFSIOSTREAM_MAGIC;1160 pThis->Stream.fFlags = fOpen;1161 pThis->Stream.p vThis = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT);1162 pThis->Stream. pOps = &pFileOps->Stream;1163 pThis->Stream. hSemRW = pVfs ? pVfs->hSemRW : NIL_RTSEMRW;1164 pThis->Stream. hVfs= hVfs;1165 pThis->Stream. cRefs= 1;1278 pThis->uMagic = RTVFSFILE_MAGIC; 1279 pThis->fReserved = 0; 1280 pThis->pOps = pFileOps; 1281 pThis->Stream.uMagic = RTVFSIOSTREAM_MAGIC; 1282 pThis->Stream.fFlags = fOpen; 1283 pThis->Stream.pOps = &pFileOps->Stream; 1284 pThis->Stream.Base.pvThis = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT); 1285 pThis->Stream.Base.hSemRW = pVfs ? pVfs->Base.hSemRW : NIL_RTSEMRW; 1286 pThis->Stream.Base.hVfs = hVfs; 1287 pThis->Stream.Base.cRefs = 1; 1166 1288 if (hVfs != NIL_RTVFS) 1167 rtVfs RetainVoid(&pVfs->cRefs);1289 rtVfsObjRetainVoid(&pVfs->Base); 1168 1290 1169 1291 *phVfsFile = pThis; 1170 *ppvInstance = pThis->Stream. pvThis;1292 *ppvInstance = pThis->Stream.Base.pvThis; 1171 1293 return VINF_SUCCESS; 1172 1294 } … … 1209 1331 1210 1332 /** @todo there is a symlink creation race here. */ 1211 RTVFS_WRITE_LOCK(pVfsParentDir->hSemRW);1212 rc = pVfsParentDir->pOps->pfnOpenFile(pVfsParentDir-> pvThis, pszEntryName, fOpen, phVfsFile);1213 RTVFS_WRITE_UNLOCK(pVfsParentDir->hSemRW);1333 rtVfsObjWriteLock(&pVfsParentDir->Base); 1334 rc = pVfsParentDir->pOps->pfnOpenFile(pVfsParentDir->Base.pvThis, pszEntryName, fOpen, phVfsFile); 1335 rtVfsObjWriteUnlock(&pVfsParentDir->Base); 1214 1336 1215 1337 RTVfsDirRelease(pVfsParentDir); … … 1235 1357 AssertPtrReturn(pThis, UINT32_MAX); 1236 1358 AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, UINT32_MAX); 1237 return rtVfs Retain(&pThis->Stream.cRefs);1359 return rtVfsObjRetain(&pThis->Stream.Base); 1238 1360 } 1239 1361 … … 1244 1366 AssertPtrReturn(pThis, UINT32_MAX); 1245 1367 AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, UINT32_MAX); 1246 1247 uint32_t cRefs = rtVfsRelease(&pThis->Stream.cRefs); 1248 if (!cRefs) 1249 { 1250 RTVFS_WRITE_LOCK(pThis->Stream.hSemRW); 1251 ASMAtomicWriteU32(&pThis->uMagic, RTVFSFILE_MAGIC_DEAD); 1252 ASMAtomicWriteU32(&pThis->Stream.uMagic, RTVFSIOSTREAM_MAGIC_DEAD); 1253 RTVFS_WRITE_UNLOCK(pThis->Stream.hSemRW); 1254 1255 pThis->pOps->Stream.Obj.pfnClose(pThis->Stream.pvThis); 1256 RTMemFree(pThis); 1257 } 1258 1259 return cRefs; 1368 return rtVfsObjRelease(&pThis->Stream.Base); 1260 1369 } 1261 1370 … … 1267 1376 AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, NIL_RTVFSIOSTREAM); 1268 1377 1269 rtVfs RetainVoid(&pThis->Stream.cRefs);1378 rtVfsObjRetainVoid(&pThis->Stream.Base); 1270 1379 return &pThis->Stream; 1271 1380 } 1272 1381 1273 1382 1274 1275 #if 0 /* unfinished code => laptop */1276 1277 /*1278 *1279 * V F S c h a i n s p e c i f i c a t i o n s1280 * V F S c h a i n s p e c i f i c a t i o n s1281 * V F S c h a i n s p e c i f i c a t i o n s1282 *1283 */1284 1285 /**1286 * A parsed VFS setup specficiation.1287 *1288 * Some specification examples.1289 * :iprtvfs:ios(stdfile="./foo.tgz")|ios(gzip)|vfs(tar)1290 */1291 typedef struct RTVFSPARSEDSPEC1292 {1293 uint32_t cElements;1294 } RTVFSPARSEDSPEC;1295 /** Pointer to a parse VFS setup specification. */1296 typedef RTVFSPARSEDSPEC *PRTVFSPARSEDSPEC;1297 1298 1299 /**1300 * Parses the VFS setup specficiation.1301 *1302 * @returns1303 * @param pInfo The output.1304 * @param pszSpec The input. This needs some more work but the basic1305 * are that anything that does not start with ":iprtvfs:"1306 * will be treated like a file. ":iprtvfs:" prefixed1307 * specifications will be understood as a VFS chain1308 * specification and parsed and constructured (by the1309 * caller).1310 * @param1311 */1312 static int rtVfsSpecParse(PRTVFSPARSEDSPEC pInfo, const char *pszSpec)1313 {1314 1315 }1316 1317 1318 RTDECL(int) RTVfsOpenIoStreamFromSpec(const char *pszSpec, uint32_t fOpen, RTVFSIOSTREAM hVfs)1319 {1320 1321 }1322 1323 #endif1324 -
trunk/src/VBox/Runtime/common/zip/zipgzip.cpp
r33941 r33945 452 452 { /* Obj */ 453 453 RTVFSOBJOPS_VERSION, 454 RTVFSOBJTYPE_IO STREAM,454 RTVFSOBJTYPE_IO_STREAM, 455 455 "gzip", 456 456 rtZipGzip_Close,
Note:
See TracChangeset
for help on using the changeset viewer.