VirtualBox

Ignore:
Timestamp:
Nov 12, 2010 2:21:59 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
67708
Message:

iprt/vfs/tar: more code.

Location:
trunk/src/VBox/Runtime/common/vfs
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp

    r34014 r34029  
    7171
    7272/** 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) \
    7474    do \
    7575    { \
    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); \
    8383    } while (0)
    8484
     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
    8597/** 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) \
    8799    do { \
    88         RTVFSOBJ_ASSERT_OPS(&(pIoStreamOps)->Obj, enmTypeArg); \
     100        RTVFSOBJ_ASSERT_OPS(&(pIoStreamOps)->Obj, a_enmType); \
    89101        Assert((pIoStreamOps)->uVersion == RTVFSIOSTREAMOPS_VERSION); \
    90102        Assert(!(pIoStreamOps)->fReserved); \
     
    99111    } while (0)
    100112
     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)
    101135
    102136
     
    105139*******************************************************************************/
    106140/** @todo Move all this stuff to internal/vfs.h */
     141
     142
     143/**
     144 * The VFS internal lock data.
     145 */
     146typedef 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
    107164
    108165/**
     
    122179    /** The vtable. */
    123180    PCRTVFSOBJOPS           pOps;
    124     /** Read-write semaphore protecting all access to the VFS
    125      * Only valid RTVFS_C_THREAD_SAFE is set, otherwise it is NIL_RTSEMRW. */
    126     RTSEMRW                 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;
    127184    /** Reference back to the VFS containing this object. */
    128185    RTVFS                   hVfs;
     
    279336
    280337
     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
     349RTDECL(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 */
     366static 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
     394RTDECL(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 */
     414static 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 */
     441static 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 */
     469static 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 */
     496RTDECL(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 */
     530RTDECL(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 */
     564RTDECL(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 */
     598RTDECL(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
    281627/*
    282628 *
     
    288634
    289635/**
     636 * Internal object retainer that asserts sanity in strict builds.
     637 *
     638 * @param   pThis               The base object handle data.
     639 */
     640DECLINLINE(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 */
     659static 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
     723RTDECL(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/**
    290762 * Write locks the object.
    291763 *
     
    294766DECLINLINE(void) rtVfsObjWriteLock(RTVFSOBJINTERNAL *pThis)
    295767{
    296     if (pThis->hSemRW != NIL_RTSEMRW)
    297     {
    298         int rc = RTSemRWRequestWrite(pThis->hSemRW, RT_INDEFINITE_WAIT);
    299         AssertRC(rc);
    300     }
     768    RTVfsLockAcquireWrite(pThis->hLock);
    301769}
    302770
     
    309777DECLINLINE(void) rtVfsObjWriteUnlock(RTVFSOBJINTERNAL *pThis)
    310778{
    311     if (pThis->hSemRW != NIL_RTSEMRW)
    312     {
    313         int rc = RTSemRWReleaseWrite(pThis->hSemRW);
    314         AssertRC(rc);
    315     }
     779    RTVfsLockReleaseWrite(pThis->hLock);
    316780}
    317781
     
    323787DECLINLINE(void) rtVfsObjReadLock(RTVFSOBJINTERNAL *pThis)
    324788{
    325     if (pThis->hSemRW != NIL_RTSEMRW)
    326     {
    327         int rc = RTSemRWRequestRead(pThis->hSemRW, RT_INDEFINITE_WAIT);
    328         AssertRC(rc);
    329     }
     789    RTVfsLockAcquireRead(pThis->hLock);
    330790}
    331791
     
    338798DECLINLINE(void) rtVfsObjReadUnlock(RTVFSOBJINTERNAL *pThis)
    339799{
    340     if (pThis->hSemRW != NIL_RTSEMRW)
    341     {
    342         int rc = RTSemRWReleaseRead(pThis->hSemRW);
    343         AssertRC(rc);
    344     }
     800    RTVfsLockReleaseRead(pThis->hLock);
    345801}
    346802
     
    359815              ("%#x %p ops=%p %s (%d)\n", cRefs, pThis, pThis->pOps, pThis->pOps->pszName, pThis->pOps->enmType));
    360816    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);
    375817}
    376818
     
    11221564
    11231565
    1124 RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RTSEMRW hSemRW,
     1566RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock,
    11251567                             PRTVFSFSSTREAM phVfsFss, void **ppvInstance)
    11261568{
     
    11371579    AssertPtr(ppvInstance);
    11381580    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);
    11471582
    11481583    /*
     
    11551590        return VERR_NO_MEMORY;
    11561591
    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;
    11711607    return VINF_SUCCESS;
    11721608}
     
    12561692 */
    12571693
     1694RTDECL(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
    12581736RTDECL(uint32_t)    RTVfsSymlinkRetain(RTVFSSYMLINK hVfsSym)
    12591737{
     
    12971775 */
    12981776
    1299 RTDECL(int) RTVfsNewIoStream(PCRTVFSIOSTREAMOPS pIoStreamOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTSEMRW hSemRW,
     1777RTDECL(int) RTVfsNewIoStream(PCRTVFSIOSTREAMOPS pIoStreamOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock,
    13001778                             PRTVFSIOSTREAM phVfsIos, void **ppvInstance)
    13011779{
     
    13121790    AssertPtr(ppvInstance);
    13131791    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);
    13221793
    13231794    /*
     
    13301801        return VERR_NO_MEMORY;
    13311802
    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;
    13461817    return VINF_SUCCESS;
    13471818}
     
    16042075 */
    16052076
    1606 RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs,
     2077RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock,
    16072078                         PRTVFSFILE phVfsFile, void **ppvInstance)
    16082079{
     
    16192090    AssertPtr(ppvInstance);
    16202091    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);
    16292093
    16302094    /*
     
    16372101        return VERR_NO_MEMORY;
    16382102
    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;
    16522117
    16532118    *phVfsFile   = pThis;
  • trunk/src/VBox/Runtime/common/vfs/vfsstdfile.cpp

    r34014 r34029  
    436436    PRTVFSSTDFILE   pThis;
    437437    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);
    439439    if (RT_FAILURE(rc))
    440440        return rc;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette