Changeset 34029 in vbox for trunk/src/VBox/Runtime/common/vfs
- Timestamp:
- Nov 12, 2010 2:21:59 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 67708
- Location:
- trunk/src/VBox/Runtime/common/vfs
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
r34014 r34029 71 71 72 72 /** Asserts that the VFS base object vtable is valid. */ 73 #define RTVFSOBJ_ASSERT_OPS( pObj, enmTypeArg) \73 #define RTVFSOBJ_ASSERT_OPS(a_pObjOps, a_enmType) \ 74 74 do \ 75 75 { \ 76 Assert(( pObj)->uVersion == RTVFSOBJOPS_VERSION); \77 Assert(( pObj)->enmType == (enmTypeArg) || (enmTypeArg) == RTVFSOBJTYPE_INVALID); \78 AssertPtr(( pObj)->pszName); \79 Assert(*( pObj)->pszName); \80 AssertPtr(( pObj)->pfnClose); \81 AssertPtr(( pObj)->pfnQueryInfo); \82 Assert(( pObj)->uEndMarker == RTVFSOBJOPS_VERSION); \76 Assert((a_pObjOps)->uVersion == RTVFSOBJOPS_VERSION); \ 77 Assert((a_pObjOps)->enmType == (a_enmType) || (a_enmType) == RTVFSOBJTYPE_INVALID); \ 78 AssertPtr((a_pObjOps)->pszName); \ 79 Assert(*(a_pObjOps)->pszName); \ 80 AssertPtr((a_pObjOps)->pfnClose); \ 81 AssertPtr((a_pObjOps)->pfnQueryInfo); \ 82 Assert((a_pObjOps)->uEndMarker == RTVFSOBJOPS_VERSION); \ 83 83 } while (0) 84 84 85 /** Asserts that the VFS set object vtable is valid. */ 86 #define RTVFSOBJSET_ASSERT_OPS(a_pSetOps, a_offObjOps) \ 87 do \ 88 { \ 89 Assert((a_pSetOps)->uVersion == RTVFSOBJSETOPS_VERSION); \ 90 Assert((a_pSetOps)->offObjOps == (a_offObjOps)); \ 91 AssertPtr((a_pSetOps)->pfnSetMode); \ 92 AssertPtr((a_pSetOps)->pfnSetTimes); \ 93 AssertPtr((a_pSetOps)->pfnSetOwner); \ 94 Assert((a_pSetOps)->uEndMarker == RTVFSOBJSETOPS_VERSION); \ 95 } while (0) 96 85 97 /** Asserts that the VFS I/O stream vtable is valid. */ 86 #define RTVFSIOSTREAM_ASSERT_OPS(pIoStreamOps, enmTypeArg) \98 #define RTVFSIOSTREAM_ASSERT_OPS(pIoStreamOps, a_enmType) \ 87 99 do { \ 88 RTVFSOBJ_ASSERT_OPS(&(pIoStreamOps)->Obj, enmTypeArg); \100 RTVFSOBJ_ASSERT_OPS(&(pIoStreamOps)->Obj, a_enmType); \ 89 101 Assert((pIoStreamOps)->uVersion == RTVFSIOSTREAMOPS_VERSION); \ 90 102 Assert(!(pIoStreamOps)->fReserved); \ … … 99 111 } while (0) 100 112 113 /** Asserts that the VFS symlink vtable is valid. */ 114 #define RTVFSSYMLINK_ASSERT_OPS(pSymlinkOps, a_enmType) \ 115 do { \ 116 RTVFSOBJ_ASSERT_OPS(&(pSymlinkOps)->Obj, a_enmType); \ 117 RTVFSOBJSET_ASSERT_OPS(&(pSymlinkOps)->ObjSet, \ 118 RT_OFFSETOF(RTVFSSYMLINKOPS, Obj) - RT_OFFSETOF(RTVFSSYMLINKOPS, ObjSet)); \ 119 Assert((pSymlinkOps)->uVersion == RTVFSSYMLINKOPS_VERSION); \ 120 Assert(!(pSymlinkOps)->fReserved); \ 121 AssertPtr((pSymlinkOps)->pfnRead); \ 122 Assert((pSymlinkOps)->uEndMarker == RTVFSSYMLINKOPS_VERSION); \ 123 } while (0) 124 125 126 /** Validates a VFS handle and returns @a rcRet if it's invalid. */ 127 #define RTVFS_ASSERT_VALID_HANDLE_OR_NIL_RETURN(hVfs, rcRet) \ 128 do { \ 129 if ((hVfs) != NIL_RTVFS) \ 130 { \ 131 AssertPtrReturn((hVfs), (rcRet)); \ 132 AssertReturn((hVfs)->uMagic == RTVFS_MAGIC, (rcRet)); \ 133 } \ 134 } while (0) 101 135 102 136 … … 105 139 *******************************************************************************/ 106 140 /** @todo Move all this stuff to internal/vfs.h */ 141 142 143 /** 144 * The VFS internal lock data. 145 */ 146 typedef struct RTVFSLOCKINTERNAL 147 { 148 /** The number of references to the this lock. */ 149 uint32_t volatile cRefs; 150 /** The lock type. */ 151 RTVFSLOCKTYPE enmType; 152 /** Type specific data. */ 153 union 154 { 155 /** Read/Write semaphore handle. */ 156 RTSEMRW hSemRW; 157 /** Fast mutex semaphore handle. */ 158 RTSEMFASTMUTEX hFastMtx; 159 /** Regular mutex semaphore handle. */ 160 RTSEMMUTEX hMtx; 161 } u; 162 } RTVFSLOCKINTERNAL; 163 107 164 108 165 /** … … 122 179 /** The vtable. */ 123 180 PCRTVFSOBJOPS pOps; 124 /** Read-write semaphore protecting all access to the VFS125 * Only valid RTVFS_C_THREAD_SAFE is set, otherwise it is NIL_RT SEMRW. */126 RT SEMRW hSemRW;181 /** The lock protecting all access to the VFS. 182 * Only valid RTVFS_C_THREAD_SAFE is set, otherwise it is NIL_RTVFSLOCK. */ 183 RTVFSLOCK hLock; 127 184 /** Reference back to the VFS containing this object. */ 128 185 RTVFS hVfs; … … 279 336 280 337 338 339 /* 340 * 341 * V F S L o c k A b s t r a c t i o n 342 * V F S L o c k A b s t r a c t i o n 343 * V F S L o c k A b s t r a c t i o n 344 * 345 * 346 */ 347 348 349 RTDECL(uint32_t) RTVfsLockRetain(RTVFSLOCK hLock) 350 { 351 RTVFSLOCKINTERNAL *pThis = hLock; 352 AssertPtrReturn(pThis, UINT32_MAX); 353 AssertPtrReturn(pThis->enmType > RTVFSLOCKTYPE_INVALID && pThis->enmType < RTVFSLOCKTYPE_END, UINT32_MAX); 354 355 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs); 356 AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p %d\n", cRefs, pThis, pThis->enmType)); 357 return cRefs; 358 } 359 360 361 /** 362 * Destroys a VFS lock handle. 363 * 364 * @param pThis The lock to destroy. 365 */ 366 static void rtVfsLockDestroy(RTVFSLOCKINTERNAL *pThis) 367 { 368 switch (pThis->enmType) 369 { 370 case RTVFSLOCKTYPE_RW: 371 RTSemRWDestroy(pThis->u.hSemRW); 372 pThis->u.hSemRW = NIL_RTSEMRW; 373 break; 374 375 case RTVFSLOCKTYPE_FASTMUTEX: 376 RTSemFastMutexDestroy(pThis->u.hFastMtx); 377 pThis->u.hFastMtx = NIL_RTSEMFASTMUTEX; 378 break; 379 380 case RTVFSLOCKTYPE_MUTEX: 381 RTSemMutexDestroy(pThis->u.hMtx); 382 pThis->u.hFastMtx = NIL_RTSEMMUTEX; 383 break; 384 385 default: 386 AssertMsgFailedReturnVoid(("%p %d\n", pThis, pThis->enmType)); 387 } 388 389 pThis->enmType = RTVFSLOCKTYPE_INVALID; 390 RTMemFree(pThis); 391 } 392 393 394 RTDECL(uint32_t) RTVfsLockRelease(RTVFSLOCK hLock) 395 { 396 RTVFSLOCKINTERNAL *pThis = hLock; 397 AssertPtrReturn(pThis, UINT32_MAX); 398 AssertPtrReturn(pThis->enmType > RTVFSLOCKTYPE_INVALID && pThis->enmType < RTVFSLOCKTYPE_END, UINT32_MAX); 399 400 uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs); 401 AssertMsg(cRefs < _1M, ("%#x %p %d\n", cRefs, pThis, pThis->enmType)); 402 if (cRefs == 0) 403 rtVfsLockDestroy(pThis); 404 return cRefs; 405 } 406 407 408 /** 409 * Creates a read/write lock. 410 * 411 * @returns IPRT status code 412 * @param phLock Where to return the lock handle. 413 */ 414 static int rtVfsLockCreateRW(PRTVFSLOCK phLock) 415 { 416 RTVFSLOCKINTERNAL *pThis = (RTVFSLOCKINTERNAL *)RTMemAlloc(sizeof(*pThis)); 417 if (!pThis) 418 return VERR_NO_MEMORY; 419 420 pThis->cRefs = 1; 421 pThis->enmType = RTVFSLOCKTYPE_RW; 422 423 int rc = RTSemRWCreate(&pThis->u.hSemRW); 424 if (RT_FAILURE(rc)) 425 { 426 RTMemFree(pThis); 427 return rc; 428 } 429 430 *phLock = pThis; 431 return VINF_SUCCESS; 432 } 433 434 435 /** 436 * Creates a fast mutex lock. 437 * 438 * @returns IPRT status code 439 * @param phLock Where to return the lock handle. 440 */ 441 static int rtVfsLockCreateFastMutex(PRTVFSLOCK phLock) 442 { 443 RTVFSLOCKINTERNAL *pThis = (RTVFSLOCKINTERNAL *)RTMemAlloc(sizeof(*pThis)); 444 if (!pThis) 445 return VERR_NO_MEMORY; 446 447 pThis->cRefs = 1; 448 pThis->enmType = RTVFSLOCKTYPE_FASTMUTEX; 449 450 int rc = RTSemFastMutexCreate(&pThis->u.hFastMtx); 451 if (RT_FAILURE(rc)) 452 { 453 RTMemFree(pThis); 454 return rc; 455 } 456 457 *phLock = pThis; 458 return VINF_SUCCESS; 459 460 } 461 462 463 /** 464 * Creates a mutex lock. 465 * 466 * @returns IPRT status code 467 * @param phLock Where to return the lock handle. 468 */ 469 static int rtVfsLockCreateMutex(PRTVFSLOCK phLock) 470 { 471 RTVFSLOCKINTERNAL *pThis = (RTVFSLOCKINTERNAL *)RTMemAlloc(sizeof(*pThis)); 472 if (!pThis) 473 return VERR_NO_MEMORY; 474 475 pThis->cRefs = 1; 476 pThis->enmType = RTVFSLOCKTYPE_MUTEX; 477 478 int rc = RTSemMutexCreate(&pThis->u.hMtx); 479 if (RT_FAILURE(rc)) 480 { 481 RTMemFree(pThis); 482 return rc; 483 } 484 485 *phLock = pThis; 486 return VINF_SUCCESS; 487 } 488 489 490 /** 491 * Acquires the lock for reading. 492 * 493 * @param hLock Non-nil lock handle. 494 * @internal 495 */ 496 RTDECL(void) RTVfsLockAcquireReadSlow(RTVFSLOCK hLock) 497 { 498 RTVFSLOCKINTERNAL *pThis = hLock; 499 int rc; 500 501 AssertPtr(pThis); 502 switch (pThis->enmType) 503 { 504 case RTVFSLOCKTYPE_RW: 505 rc = RTSemRWRequestRead(pThis->u.hSemRW, RT_INDEFINITE_WAIT); 506 AssertRC(rc); 507 break; 508 509 case RTVFSLOCKTYPE_FASTMUTEX: 510 rc = RTSemFastMutexRequest(pThis->u.hFastMtx); 511 AssertRC(rc); 512 break; 513 514 case RTVFSLOCKTYPE_MUTEX: 515 rc = RTSemMutexRequest(pThis->u.hMtx, RT_INDEFINITE_WAIT); 516 AssertRC(rc); 517 break; 518 default: 519 AssertFailed(); 520 } 521 } 522 523 524 /** 525 * Release a lock held for reading. 526 * 527 * @param hLock Non-nil lock handle. 528 * @internal 529 */ 530 RTDECL(void) RTVfsLockReleaseReadSlow(RTVFSLOCK hLock) 531 { 532 RTVFSLOCKINTERNAL *pThis = hLock; 533 int rc; 534 535 AssertPtr(pThis); 536 switch (pThis->enmType) 537 { 538 case RTVFSLOCKTYPE_RW: 539 rc = RTSemRWReleaseRead(pThis->u.hSemRW); 540 AssertRC(rc); 541 break; 542 543 case RTVFSLOCKTYPE_FASTMUTEX: 544 rc = RTSemFastMutexRelease(pThis->u.hFastMtx); 545 AssertRC(rc); 546 break; 547 548 case RTVFSLOCKTYPE_MUTEX: 549 rc = RTSemMutexRelease(pThis->u.hMtx); 550 AssertRC(rc); 551 break; 552 default: 553 AssertFailed(); 554 } 555 } 556 557 558 /** 559 * Acquires the lock for writing. 560 * 561 * @param hLock Non-nil lock handle. 562 * @internal 563 */ 564 RTDECL(void) RTVfsLockAcquireWriteSlow(RTVFSLOCK hLock) 565 { 566 RTVFSLOCKINTERNAL *pThis = hLock; 567 int rc; 568 569 AssertPtr(pThis); 570 switch (pThis->enmType) 571 { 572 case RTVFSLOCKTYPE_RW: 573 rc = RTSemRWRequestWrite(pThis->u.hSemRW, RT_INDEFINITE_WAIT); 574 AssertRC(rc); 575 break; 576 577 case RTVFSLOCKTYPE_FASTMUTEX: 578 rc = RTSemFastMutexRequest(pThis->u.hFastMtx); 579 AssertRC(rc); 580 break; 581 582 case RTVFSLOCKTYPE_MUTEX: 583 rc = RTSemMutexRequest(pThis->u.hMtx, RT_INDEFINITE_WAIT); 584 AssertRC(rc); 585 break; 586 default: 587 AssertFailed(); 588 } 589 } 590 591 592 /** 593 * Release a lock held for writing. 594 * 595 * @param hLock Non-nil lock handle. 596 * @internal 597 */ 598 RTDECL(void) RTVfsLockReleaseWriteSlow(RTVFSLOCK hLock) 599 { 600 RTVFSLOCKINTERNAL *pThis = hLock; 601 int rc; 602 603 AssertPtr(pThis); 604 switch (pThis->enmType) 605 { 606 case RTVFSLOCKTYPE_RW: 607 rc = RTSemRWReleaseWrite(pThis->u.hSemRW); 608 AssertRC(rc); 609 break; 610 611 case RTVFSLOCKTYPE_FASTMUTEX: 612 rc = RTSemFastMutexRelease(pThis->u.hFastMtx); 613 AssertRC(rc); 614 break; 615 616 case RTVFSLOCKTYPE_MUTEX: 617 rc = RTSemMutexRelease(pThis->u.hMtx); 618 AssertRC(rc); 619 break; 620 default: 621 AssertFailed(); 622 } 623 } 624 625 626 281 627 /* 282 628 * … … 288 634 289 635 /** 636 * Internal object retainer that asserts sanity in strict builds. 637 * 638 * @param pThis The base object handle data. 639 */ 640 DECLINLINE(void) rtVfsObjRetainVoid(RTVFSOBJINTERNAL *pThis) 641 { 642 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs); 643 AssertMsg(cRefs > 1 && cRefs < _1M, 644 ("%#x %p ops=%p %s (%d)\n", cRefs, pThis, pThis->pOps, pThis->pOps->pszName, pThis->pOps->enmType)); 645 NOREF(cRefs); 646 } 647 648 649 /** 650 * Initializes the base object part of a new object. 651 * 652 * @returns IPRT status code. 653 * @param pThis Pointer to the base object part. 654 * @param pObjOps The base object vtable. 655 * @param hVfs The VFS handle to associate with. 656 * @param hLock The lock handle, pseudo handle or nil. 657 * @param pvThis Pointer to the private data. 658 */ 659 static int rtVfsObjInitNewObject(RTVFSOBJINTERNAL *pThis, PCRTVFSOBJOPS pObjOps, RTVFS hVfs, RTVFSLOCK hLock, void *pvThis) 660 { 661 /* 662 * Deal with the lock first as that's the most complicated matter. 663 */ 664 if (hLock != NIL_RTVFSLOCK) 665 { 666 int rc; 667 if (hLock == RTVFSLOCK_CREATE_RW) 668 { 669 rc = rtVfsLockCreateRW(&hLock); 670 AssertRCReturn(rc, rc); 671 } 672 else if (hLock == RTVFSLOCK_CREATE_FASTMUTEX) 673 { 674 rc = rtVfsLockCreateFastMutex(&hLock); 675 AssertRCReturn(rc, rc); 676 } 677 else if (hLock == RTVFSLOCK_CREATE_MUTEX) 678 { 679 rc = rtVfsLockCreateMutex(&hLock); 680 AssertRCReturn(rc, rc); 681 } 682 else 683 { 684 /* 685 * The caller specified a lock, we consume the this reference. 686 */ 687 AssertPtrReturn(hLock, VERR_INVALID_HANDLE); 688 AssertPtrReturn(hLock->enmType > RTVFSLOCKTYPE_INVALID && hLock->enmType < RTVFSLOCKTYPE_END, VERR_INVALID_HANDLE); 689 AssertPtrReturn(hLock->cRefs > 0, VERR_INVALID_HANDLE); 690 } 691 } 692 else if (hVfs != NIL_RTVFS) 693 { 694 /* 695 * Retain a reference to the VFS lock, if there is one. 696 */ 697 hLock = hVfs->Base.hLock; 698 if (hLock != NIL_RTVFSLOCK) 699 { 700 uint32_t cRefs = RTVfsLockRetain(hLock); 701 if (RT_UNLIKELY(cRefs == UINT32_MAX)) 702 return VERR_INVALID_HANDLE; 703 } 704 } 705 706 707 /* 708 * Do the actual initializing. 709 */ 710 pThis->uMagic = RTVFSOBJ_MAGIC; 711 pThis->pvThis = pvThis; 712 pThis->pOps = pObjOps; 713 pThis->cRefs = 1; 714 pThis->hVfs = hVfs; 715 pThis->hLock = hLock; 716 if (hVfs != NIL_RTVFS) 717 rtVfsObjRetainVoid(&hVfs->Base); 718 719 return VINF_SUCCESS; 720 } 721 722 723 RTDECL(int) RTVfsNewBaseObj(PCRTVFSOBJOPS pObjOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, 724 PRTVFSOBJ phVfsObj, void **ppvInstance) 725 { 726 /* 727 * Validate the input, be extra strict in strict builds. 728 */ 729 AssertPtr(pObjOps); 730 AssertReturn(pObjOps->uVersion == RTVFSOBJOPS_VERSION, VERR_VERSION_MISMATCH); 731 AssertReturn(pObjOps->uEndMarker == RTVFSOBJOPS_VERSION, VERR_VERSION_MISMATCH); 732 RTVFSOBJ_ASSERT_OPS(pObjOps, RTVFSOBJTYPE_BASE); 733 Assert(cbInstance > 0); 734 AssertPtr(ppvInstance); 735 AssertPtr(phVfsObj); 736 RTVFS_ASSERT_VALID_HANDLE_OR_NIL_RETURN(hVfs, VERR_INVALID_HANDLE); 737 738 /* 739 * Allocate the handle + instance data. 740 */ 741 size_t const cbThis = RT_ALIGN_Z(sizeof(RTVFSOBJINTERNAL), RTVFS_INST_ALIGNMENT) 742 + RT_ALIGN_Z(cbInstance, RTVFS_INST_ALIGNMENT); 743 RTVFSOBJINTERNAL *pThis = (RTVFSOBJINTERNAL *)RTMemAllocZ(cbThis); 744 if (!pThis) 745 return VERR_NO_MEMORY; 746 747 int rc = rtVfsObjInitNewObject(pThis, pObjOps, hVfs, hLock, 748 (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT)); 749 if (RT_FAILURE(rc)) 750 { 751 RTMemFree(pThis); 752 return rc; 753 } 754 755 *phVfsObj = pThis; 756 *ppvInstance = pThis->pvThis; 757 return VINF_SUCCESS; 758 } 759 760 761 /** 290 762 * Write locks the object. 291 763 * … … 294 766 DECLINLINE(void) rtVfsObjWriteLock(RTVFSOBJINTERNAL *pThis) 295 767 { 296 if (pThis->hSemRW != NIL_RTSEMRW) 297 { 298 int rc = RTSemRWRequestWrite(pThis->hSemRW, RT_INDEFINITE_WAIT); 299 AssertRC(rc); 300 } 768 RTVfsLockAcquireWrite(pThis->hLock); 301 769 } 302 770 … … 309 777 DECLINLINE(void) rtVfsObjWriteUnlock(RTVFSOBJINTERNAL *pThis) 310 778 { 311 if (pThis->hSemRW != NIL_RTSEMRW) 312 { 313 int rc = RTSemRWReleaseWrite(pThis->hSemRW); 314 AssertRC(rc); 315 } 779 RTVfsLockReleaseWrite(pThis->hLock); 316 780 } 317 781 … … 323 787 DECLINLINE(void) rtVfsObjReadLock(RTVFSOBJINTERNAL *pThis) 324 788 { 325 if (pThis->hSemRW != NIL_RTSEMRW) 326 { 327 int rc = RTSemRWRequestRead(pThis->hSemRW, RT_INDEFINITE_WAIT); 328 AssertRC(rc); 329 } 789 RTVfsLockAcquireRead(pThis->hLock); 330 790 } 331 791 … … 338 798 DECLINLINE(void) rtVfsObjReadUnlock(RTVFSOBJINTERNAL *pThis) 339 799 { 340 if (pThis->hSemRW != NIL_RTSEMRW) 341 { 342 int rc = RTSemRWReleaseRead(pThis->hSemRW); 343 AssertRC(rc); 344 } 800 RTVfsLockReleaseRead(pThis->hLock); 345 801 } 346 802 … … 359 815 ("%#x %p ops=%p %s (%d)\n", cRefs, pThis, pThis->pOps, pThis->pOps->pszName, pThis->pOps->enmType)); 360 816 return cRefs; 361 }362 363 364 /**365 * Internal object retainer that asserts sanity in strict builds.366 *367 * @param pThis The base object handle data.368 */369 DECLINLINE(void) rtVfsObjRetainVoid(RTVFSOBJINTERNAL *pThis)370 {371 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);372 AssertMsg(cRefs > 1 && cRefs < _1M,373 ("%#x %p ops=%p %s (%d)\n", cRefs, pThis, pThis->pOps, pThis->pOps->pszName, pThis->pOps->enmType));374 NOREF(cRefs);375 817 } 376 818 … … 1122 1564 1123 1565 1124 RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RT SEMRW hSemRW,1566 RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, 1125 1567 PRTVFSFSSTREAM phVfsFss, void **ppvInstance) 1126 1568 { … … 1137 1579 AssertPtr(ppvInstance); 1138 1580 AssertPtr(phVfsFss); 1139 1140 RTVFSINTERNAL *pVfs = NULL; 1141 if (hVfs != NIL_RTVFS) 1142 { 1143 pVfs = hVfs; 1144 AssertPtrReturn(pVfs, VERR_INVALID_HANDLE); 1145 AssertReturn(pVfs->uMagic == RTVFS_MAGIC, VERR_INVALID_HANDLE); 1146 } 1581 RTVFS_ASSERT_VALID_HANDLE_OR_NIL_RETURN(hVfs, VERR_INVALID_HANDLE); 1147 1582 1148 1583 /* … … 1155 1590 return VERR_NO_MEMORY; 1156 1591 1157 pThis->uMagic = RTVFSFSSTREAM_MAGIC; 1158 pThis->fFlags = RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE; 1159 pThis->pOps = pFsStreamOps; 1160 pThis->Base.uMagic = RTVFSOBJ_MAGIC; 1161 pThis->Base.pvThis = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT); 1162 pThis->Base.pOps = &pFsStreamOps->Obj; 1163 pThis->Base.hSemRW = hSemRW != NIL_RTSEMRW ? hSemRW : pVfs ? pVfs->Base.hSemRW : NIL_RTSEMRW; 1164 pThis->Base.hVfs = hVfs; 1165 pThis->Base.cRefs = 1; 1166 if (hVfs != NIL_RTVFS) 1167 rtVfsObjRetainVoid(&pVfs->Base); 1168 1169 *phVfsFss = pThis; 1170 *ppvInstance = pThis->Base.pvThis; 1592 int rc = rtVfsObjInitNewObject(&pThis->Base, &pFsStreamOps->Obj, hVfs, hLock, 1593 (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT)); 1594 1595 if (RT_FAILURE(rc)) 1596 { 1597 RTMemFree(pThis); 1598 return rc; 1599 } 1600 1601 pThis->uMagic = RTVFSFSSTREAM_MAGIC; 1602 pThis->fFlags = RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE; 1603 pThis->pOps = pFsStreamOps; 1604 1605 *phVfsFss = pThis; 1606 *ppvInstance = pThis->Base.pvThis; 1171 1607 return VINF_SUCCESS; 1172 1608 } … … 1256 1692 */ 1257 1693 1694 RTDECL(int) RTVfsNewSymlink(PCRTVFSSYMLINKOPS pSymlinkOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, 1695 PRTVFSSYMLINK phVfsSym, void **ppvInstance) 1696 { 1697 /* 1698 * Validate the input, be extra strict in strict builds. 1699 */ 1700 AssertPtr(pSymlinkOps); 1701 AssertReturn(pSymlinkOps->uVersion == RTVFSSYMLINKOPS_VERSION, VERR_VERSION_MISMATCH); 1702 AssertReturn(pSymlinkOps->uEndMarker == RTVFSSYMLINKOPS_VERSION, VERR_VERSION_MISMATCH); 1703 Assert(!pSymlinkOps->fReserved); 1704 RTVFSSYMLINK_ASSERT_OPS(pSymlinkOps, RTVFSOBJTYPE_SYMLINK); 1705 Assert(cbInstance > 0); 1706 AssertPtr(ppvInstance); 1707 AssertPtr(phVfsSym); 1708 RTVFS_ASSERT_VALID_HANDLE_OR_NIL_RETURN(hVfs, VERR_INVALID_HANDLE); 1709 1710 /* 1711 * Allocate the handle + instance data. 1712 */ 1713 size_t const cbThis = RT_ALIGN_Z(sizeof(RTVFSSYMLINKINTERNAL), RTVFS_INST_ALIGNMENT) 1714 + RT_ALIGN_Z(cbInstance, RTVFS_INST_ALIGNMENT); 1715 RTVFSSYMLINKINTERNAL *pThis = (RTVFSSYMLINKINTERNAL *)RTMemAllocZ(cbThis); 1716 if (!pThis) 1717 return VERR_NO_MEMORY; 1718 1719 int rc = rtVfsObjInitNewObject(&pThis->Base, &pSymlinkOps->Obj, hVfs, hLock, 1720 (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT)); 1721 if (RT_FAILURE(rc)) 1722 { 1723 RTMemFree(pThis); 1724 return rc; 1725 } 1726 1727 pThis->uMagic = RTVFSSYMLINK_MAGIC; 1728 pThis->pOps = pSymlinkOps; 1729 1730 *phVfsSym = pThis; 1731 *ppvInstance = pThis->Base.pvThis; 1732 return VINF_SUCCESS; 1733 } 1734 1735 1258 1736 RTDECL(uint32_t) RTVfsSymlinkRetain(RTVFSSYMLINK hVfsSym) 1259 1737 { … … 1297 1775 */ 1298 1776 1299 RTDECL(int) RTVfsNewIoStream(PCRTVFSIOSTREAMOPS pIoStreamOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RT SEMRW hSemRW,1777 RTDECL(int) RTVfsNewIoStream(PCRTVFSIOSTREAMOPS pIoStreamOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock, 1300 1778 PRTVFSIOSTREAM phVfsIos, void **ppvInstance) 1301 1779 { … … 1312 1790 AssertPtr(ppvInstance); 1313 1791 AssertPtr(phVfsIos); 1314 1315 RTVFSINTERNAL *pVfs = NULL; 1316 if (hVfs != NIL_RTVFS) 1317 { 1318 pVfs = hVfs; 1319 AssertPtrReturn(pVfs, VERR_INVALID_HANDLE); 1320 AssertReturn(pVfs->uMagic == RTVFS_MAGIC, VERR_INVALID_HANDLE); 1321 } 1792 RTVFS_ASSERT_VALID_HANDLE_OR_NIL_RETURN(hVfs, VERR_INVALID_HANDLE); 1322 1793 1323 1794 /* … … 1330 1801 return VERR_NO_MEMORY; 1331 1802 1332 pThis->uMagic = RTVFSIOSTREAM_MAGIC;1333 pThis->fFlags = fOpen;1334 pThis->pOps = pIoStreamOps;1335 pThis->Base.uMagic = RTVFSOBJ_MAGIC;1336 pThis->Base.pvThis = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT);1337 pThis->Base.pOps = &pIoStreamOps->Obj;1338 pThis->Base.hSemRW = hSemRW != NIL_RTSEMRW ? hSemRW : pVfs ? pVfs->Base.hSemRW : NIL_RTSEMRW;1339 pThis->Base.hVfs = hVfs; 1340 pThis-> Base.cRefs = 1;1341 if (hVfs != NIL_RTVFS)1342 rtVfsObjRetainVoid(&pVfs->Base);1343 1344 *phVfsIos = pThis;1345 *ppvInstance = pThis->Base.pvThis;1803 int rc = rtVfsObjInitNewObject(&pThis->Base, &pIoStreamOps->Obj, hVfs, hLock, 1804 (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT)); 1805 if (RT_FAILURE(rc)) 1806 { 1807 RTMemFree(pThis); 1808 return rc; 1809 } 1810 1811 pThis->uMagic = RTVFSIOSTREAM_MAGIC; 1812 pThis->fFlags = fOpen; 1813 pThis->pOps = pIoStreamOps; 1814 1815 *phVfsIos = pThis; 1816 *ppvInstance = pThis->Base.pvThis; 1346 1817 return VINF_SUCCESS; 1347 1818 } … … 1604 2075 */ 1605 2076 1606 RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, 2077 RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock, 1607 2078 PRTVFSFILE phVfsFile, void **ppvInstance) 1608 2079 { … … 1619 2090 AssertPtr(ppvInstance); 1620 2091 AssertPtr(phVfsFile); 1621 1622 RTVFSINTERNAL *pVfs = NULL; 1623 if (hVfs != NIL_RTVFS) 1624 { 1625 pVfs = hVfs; 1626 AssertPtrReturn(pVfs, VERR_INVALID_HANDLE); 1627 AssertReturn(pVfs->uMagic == RTVFS_MAGIC, VERR_INVALID_HANDLE); 1628 } 2092 RTVFS_ASSERT_VALID_HANDLE_OR_NIL_RETURN(hVfs, VERR_INVALID_HANDLE); 1629 2093 1630 2094 /* … … 1637 2101 return VERR_NO_MEMORY; 1638 2102 1639 pThis->uMagic = RTVFSFILE_MAGIC; 1640 pThis->fReserved = 0; 1641 pThis->pOps = pFileOps; 1642 pThis->Stream.uMagic = RTVFSIOSTREAM_MAGIC; 1643 pThis->Stream.fFlags = fOpen; 1644 pThis->Stream.pOps = &pFileOps->Stream; 1645 pThis->Stream.Base.pvThis = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT); 1646 pThis->Stream.Base.pOps = &pFileOps->Stream.Obj; 1647 pThis->Stream.Base.hSemRW = pVfs ? pVfs->Base.hSemRW : NIL_RTSEMRW; 1648 pThis->Stream.Base.hVfs = hVfs; 1649 pThis->Stream.Base.cRefs = 1; 1650 if (hVfs != NIL_RTVFS) 1651 rtVfsObjRetainVoid(&pVfs->Base); 2103 int rc = rtVfsObjInitNewObject(&pThis->Stream.Base, &pFileOps->Stream.Obj, hVfs, hLock, 2104 (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT)); 2105 if (RT_FAILURE(rc)) 2106 { 2107 RTMemFree(pThis); 2108 return rc; 2109 } 2110 2111 pThis->uMagic = RTVFSFILE_MAGIC; 2112 pThis->fReserved = 0; 2113 pThis->pOps = pFileOps; 2114 pThis->Stream.uMagic = RTVFSIOSTREAM_MAGIC; 2115 pThis->Stream.fFlags = fOpen; 2116 pThis->Stream.pOps = &pFileOps->Stream; 1652 2117 1653 2118 *phVfsFile = pThis; -
trunk/src/VBox/Runtime/common/vfs/vfsstdfile.cpp
r34014 r34029 436 436 PRTVFSSTDFILE pThis; 437 437 RTVFSFILE hVfsFile; 438 rc = RTVfsNewFile(&g_rtVfsStdFileOps, sizeof(RTVFSSTDFILE), fOpen, NIL_RTVFS, &hVfsFile, (void **)&pThis);438 rc = RTVfsNewFile(&g_rtVfsStdFileOps, sizeof(RTVFSSTDFILE), fOpen, NIL_RTVFS, NIL_RTVFSLOCK, &hVfsFile, (void **)&pThis); 439 439 if (RT_FAILURE(rc)) 440 440 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.