VirtualBox

Changeset 33945 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Nov 10, 2010 5:49:56 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
67606
Message:

More vfs code, new iprt error range..

Location:
trunk/src/VBox/Runtime
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r33887 r33945  
    370370        common/time/timesup.cpp \
    371371        common/vfs/vfsbase.cpp \
     372        common/vfs/vfschain.cpp \
    372373        common/vfs/vfsstdfile.cpp \
    373374        common/zip/zipgzip.cpp \
  • trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp

    r33911 r33945  
    4848*   Defined Constants And Macros                                               *
    4949*******************************************************************************/
    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)
    5153#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)
    5357#define RTVFSDIR_MAGIC_DEAD         (~RTVFSDIR_MAGIC)
    54 #define RTVFSFILE_MAGIC             UINT32_C(0x55556666)
     58#define RTVFSFILE_MAGIC             UINT32_C(0x20109905)
    5559#define RTVFSFILE_MAGIC_DEAD        (~RTVFSFILE_MAGIC)
    56 #define RTVFSIOSTREAM_MAGIC         UINT32_C(0x33334444)
     60#define RTVFSIOSTREAM_MAGIC         UINT32_C(0x20109906)
    5761#define RTVFSIOSTREAM_MAGIC_DEAD    (~RTVFSIOSTREAM_MAGIC)
    58 #define RTVFSSYMLINK_MAGIC          UINT32_C(0x9999aaaa)
     62#define RTVFSSYMLINK_MAGIC          UINT32_C(0x20109907)
    5963#define RTVFSSYMLINK_MAGIC_DEAD     (~RTVFSSYMLINK_MAGIC)
    6064
     
    6569#define RTVFS_MAX_LINKS             20U
    6670
    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)
    10771
    10872
     
    11377
    11478/**
     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 */
     84typedef 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 */
     107typedef 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/**
    115121 * The VFS handle data.
     122 *
     123 * @extends RTVFSOBJINTERNAL
    116124 */
    117125typedef struct RTVFSINTERNAL
     
    121129    /** Creation flags (RTVFS_C_XXX). */
    122130    uint32_t                fFlags;
    123     /** Pointer to the instance data. */
    124     void                   *pvThis;
    125131    /** The vtable. */
    126132    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;
    134135} RTVFSINTERNAL;
    135136
     
    137138/**
    138139 * The VFS directory handle data.
     140 *
     141 * @extends RTVFSOBJINTERNAL
    139142 */
    140143typedef struct RTVFSDIRINTERNAL
     
    144147    /** Reserved for flags or something. */
    145148    uint32_t                fReserved;
    146     /** Pointer to the instance data. */
    147     void                   *pvThis;
    148149    /** The vtable. */
    149150    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;
    157153} RTVFSDIRINTERNAL;
    158154
     
    160156/**
    161157 * The VFS symbolic link handle data.
     158 *
     159 * @extends RTVFSOBJINTERNAL
    162160 */
    163161typedef struct RTVFSSYMLINKINTERNAL
     
    167165    /** Reserved for flags or something. */
    168166    uint32_t                fReserved;
    169     /** Pointer to the instance data. */
    170     void                   *pvThis;
    171167    /** The vtable. */
    172168    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;
    179171} RTVFSSYMLINKINTERNAL;
    180172
     
    183175 * The VFS I/O stream handle data.
    184176 *
    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
    186180 */
    187181typedef struct RTVFSIOSTREAMINTERNAL
     
    191185    /** File open flags, at a minimum the access mask. */
    192186    uint32_t                fFlags;
    193     /** Pointer to the instance data. */
    194     void                   *pvThis;
    195187    /** The vtable. */
    196188    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;
    203191} RTVFSIOSTREAMINTERNAL;
    204192
     
    221209} RTVFSFILEINTERNAL;
    222210
     211#if 0 /* later */
     212
     213/**
     214 * The VFS pipe handle data.
     215 *
     216 * @extends RTVFSIOSTREAMINTERNAL
     217 */
     218typedef 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 */
     236typedef 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 */
     264DECLINLINE(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 */
     279DECLINLINE(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 */
     293DECLINLINE(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 */
     308DECLINLINE(void) rtVfsObjReadUnlock(RTVFSOBJINTERNAL *pThis)
     309{
     310    if (pThis->hSemRW != NIL_RTSEMRW)
     311    {
     312        int rc = RTSemRWReleaseRead(pThis->hSemRW);
     313        AssertRC(rc);
     314    }
     315}
     316
    223317
    224318
    225319/**
    226320 * 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 */
     325DECLINLINE(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 */
     339DECLINLINE(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
     348RTDECL(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 */
     363static 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.
    227422 *
    228423 * @returns The new reference count.
    229424 * @param   pcRefs              The reference counter.
    230425 */
    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));
     426DECLINLINE(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);
    235432    return cRefs;
    236433}
    237434
    238435
    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 }
     436RTDECL(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
    262444
    263445
     
    527709    AssertPtr(pThis);
    528710    Assert(pThis->uMagic == RTVFS_MAGIC);
    529     Assert(pThis->cRefs > 0);
     711    Assert(pThis->Base.cRefs > 0);
    530712    AssertPtr(pPath);
    531713    AssertPtr(ppVfsParentDir);
     
    538720    /** @todo Union mounts, traversal optimization methods, races, ++ */
    539721    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);
    543725    if (RT_FAILURE(rc))
    544726        return rc;
     
    573755        if (fFinal)
    574756        {
    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);
    578760            *pszEntryEnd = '\0';
    579761            if (rc == VERR_PATH_NOT_FOUND)
     
    590772        else
    591773        {
    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);
    595777            *pszEntryEnd = '/';
    596778            if (RT_FAILURE(rc))
     
    641823                /* Must restart from the root (optimize this). */
    642824                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);
    646828                if (RT_FAILURE(rc))
    647829                {
     
    658840             */
    659841            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);
    663845            if (RT_FAILURE(rc))
    664846            {
     
    692874    AssertPtrReturn(pThis, UINT32_MAX);
    693875    AssertReturn(pThis->uMagic == RTVFSDIR_MAGIC, UINT32_MAX);
    694     return rtVfsRetain(&pThis->cRefs);
     876    return rtVfsObjRetain(&pThis->Base);
    695877}
    696878
     
    701883    AssertPtrReturn(pThis, UINT32_MAX);
    702884    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);
    715886}
    716887
     
    730901    AssertPtrReturn(pThis, UINT32_MAX);
    731902    AssertReturn(pThis->uMagic == RTVFSSYMLINK_MAGIC, UINT32_MAX);
    732     return rtVfsRetain(&pThis->cRefs);
     903    return rtVfsObjRetain(&pThis->Base);
    733904}
    734905
     
    739910    AssertPtrReturn(pThis, UINT32_MAX);
    740911    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);
    753913}
    754914
     
    760920    AssertReturn(pThis->uMagic == RTVFSSYMLINK_MAGIC, VERR_INVALID_HANDLE);
    761921
    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);
    765925
    766926    return rc;
     
    809969        return VERR_NO_MEMORY;
    810970
    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;
    818979    if (hVfs != NIL_RTVFS)
    819         rtVfsRetainVoid(&pVfs->cRefs);
     980        rtVfsObjRetainVoid(&pVfs->Base);
    820981
    821982    *phVfsIos    = pThis;
    822     *ppvInstance = pThis->pvThis;
     983    *ppvInstance = pThis->Base.pvThis;
    823984    return VINF_SUCCESS;
    824985}
     
    830991    AssertPtrReturn(pThis, UINT32_MAX);
    831992    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, UINT32_MAX);
    832     return rtVfsRetain(&pThis->cRefs);
     993    return rtVfsObjRetain(&pThis->Base);
    833994}
    834995
     
    8391000    AssertPtrReturn(pThis, UINT32_MAX);
    8401001    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);
    8811003}
    8821004
     
    8901012    if (pThis->pOps->Obj.enmType == RTVFSOBJTYPE_FILE)
    8911013    {
    892         rtVfsRetainVoid(&pThis->cRefs);
     1014        rtVfsObjRetainVoid(&pThis->Base);
    8931015        return RT_FROM_MEMBER(pThis, RTVFSFILEINTERNAL, Stream);
    8941016    }
     
    9051027    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
    9061028
    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);
    9101032    return rc;
    9111033}
     
    9251047    RTSgBufInit(&SgBuf, &Seg, 1);
    9261048
    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);
    9301052    return rc;
    9311053}
     
    9451067    RTSgBufInit(&SgBuf, &Seg, 1);
    9461068
    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);
    9501072    return rc;
    9511073}
     
    9631085    AssertReturn(fBlocking || pcbRead, VERR_INVALID_PARAMETER);
    9641086
    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);
    9681090    return rc;
    9691091}
     
    9811103    AssertReturn(fBlocking || pcbWritten, VERR_INVALID_PARAMETER);
    9821104
    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);
    9861108    return rc;
    9871109}
     
    9941116    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
    9951117
    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);
    9991121    return rc;
    10001122}
     
    10081130    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
    10091131
    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);
    10131135    return rc;
    10141136}
     
    10221144
    10231145    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);
    10271149    if (RT_FAILURE(rc))
    10281150        off = rc;
     
    10411163    if (pThis->pOps->pfnSkip)
    10421164    {
    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);
    10461168    }
    10471169    else
     
    10541176            {
    10551177                size_t cbToRead = RT_MIN(cb, _64K);
    1056                 RTVFS_WRITE_LOCK(pThis->hSemRW);
     1178                rtVfsObjWriteLock(&pThis->Base);
    10571179                rc = RTVfsIoStrmRead(hVfsIos, pvBuf, cbToRead, NULL);
    1058                 RTVFS_WRITE_UNLOCK(pThis->hSemRW);
     1180                rtVfsObjWriteUnlock(&pThis->Base);
    10591181                if (RT_FAILURE(rc))
    10601182                    break;
     
    10801202    if (pThis->pOps->pfnSkip)
    10811203    {
    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);
    10851207    }
    10861208    else
     
    10931215            {
    10941216                size_t cbToWrite = RT_MIN(cb, _64K);
    1095                 RTVFS_WRITE_LOCK(pThis->hSemRW);
     1217                rtVfsObjWriteLock(&pThis->Base);
    10961218                rc = RTVfsIoStrmWrite(hVfsIos, pvBuf, cbToWrite, NULL);
    1097                 RTVFS_WRITE_UNLOCK(pThis->hSemRW);
     1219                rtVfsObjWriteUnlock(&pThis->Base);
    10981220                if (RT_FAILURE(rc))
    10991221                    break;
     
    11541276        return VERR_NO_MEMORY;
    11551277
    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.pvThis    = (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;
    11661288    if (hVfs != NIL_RTVFS)
    1167         rtVfsRetainVoid(&pVfs->cRefs);
     1289        rtVfsObjRetainVoid(&pVfs->Base);
    11681290
    11691291    *phVfsFile   = pThis;
    1170     *ppvInstance = pThis->Stream.pvThis;
     1292    *ppvInstance = pThis->Stream.Base.pvThis;
    11711293    return VINF_SUCCESS;
    11721294}
     
    12091331
    12101332                /** @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);
    12141336
    12151337                RTVfsDirRelease(pVfsParentDir);
     
    12351357    AssertPtrReturn(pThis, UINT32_MAX);
    12361358    AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, UINT32_MAX);
    1237     return rtVfsRetain(&pThis->Stream.cRefs);
     1359    return rtVfsObjRetain(&pThis->Stream.Base);
    12381360}
    12391361
     
    12441366    AssertPtrReturn(pThis, UINT32_MAX);
    12451367    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);
    12601369}
    12611370
     
    12671376    AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, NIL_RTVFSIOSTREAM);
    12681377
    1269     rtVfsRetainVoid(&pThis->Stream.cRefs);
     1378    rtVfsObjRetainVoid(&pThis->Stream.Base);
    12701379    return &pThis->Stream;
    12711380}
    12721381
    12731382
    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 s
    1280  *  V F S   c h a i n   s p e c i f i c a t i o n s
    1281  *  V F S   c h a i n   s p e c i f i c a t i o n s
    1282  *
    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 RTVFSPARSEDSPEC
    1292 {
    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  * @returns
    1303  * @param   pInfo       The output.
    1304  * @param   pszSpec     The input.  This needs some more work but the basic
    1305  *                      are that anything that does not start with ":iprtvfs:"
    1306  *                      will be treated like a file.  ":iprtvfs:" prefixed
    1307  *                      specifications will be understood as a VFS chain
    1308  *                      specification and parsed and constructured (by the
    1309  *                      caller).
    1310  * @param
    1311  */
    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 #endif
    1324 
  • trunk/src/VBox/Runtime/common/zip/zipgzip.cpp

    r33941 r33945  
    452452    { /* Obj */
    453453        RTVFSOBJOPS_VERSION,
    454         RTVFSOBJTYPE_IOSTREAM,
     454        RTVFSOBJTYPE_IO_STREAM,
    455455        "gzip",
    456456        rtZipGzip_Close,
Note: See TracChangeset for help on using the changeset viewer.

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