VirtualBox

Changeset 25717 in vbox for trunk/src/VBox/Runtime/r0drv/os2


Ignore:
Timestamp:
Jan 11, 2010 1:24:09 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
56457
Message:

iprt: Added RTSemEventCreateEx and did some cleanups of the RTSemEventDestroy behavior wrt NIL handles.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/os2/semevent-r0drv-os2.cpp

    r8245 r25717  
    6565
    6666
    67 RTDECL(int)  RTSemEventCreate(PRTSEMEVENT pEventSem)
    68 {
    69     Assert(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *));
    70     AssertPtrReturn(pEventSem, VERR_INVALID_POINTER);
    71 
    72     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pEventInt));
    73     if (pEventInt)
    74     {
    75         pEventInt->u32Magic = RTSEMEVENT_MAGIC;
    76         pEventInt->cWaiters = 0;
    77         pEventInt->cWaking = 0;
    78         pEventInt->fSignaled = 0;
    79         KernAllocSpinLock(&pEventInt->Spinlock);
    80         *pEventSem = pEventInt;
     67RTDECL(int)  RTSemEventCreate(PRTSEMEVENT phEventSem)
     68{
     69    return RTSemEventCreateEx(phEventSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, NULL);
     70}
     71
     72
     73RTDECL(int)  RTSemEventCreateEx(PRTSEMEVENT phEventSem, uint32_t fFlags, RTLOCKVALCLASS hClass, const char *pszNameFmt, ...)
     74{
     75    AssertReturn(!(fFlags & ~RTSEMEVENT_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);
     76    AssertCompile(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *));
     77    AssertPtrReturn(phEventSem, VERR_INVALID_POINTER);
     78
     79    PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pThis));
     80    if (!pThis)
     81        return VERR_NO_MEMORY;
     82
     83    pThis->u32Magic = RTSEMEVENT_MAGIC;
     84    pThis->cWaiters = 0;
     85    pThis->cWaking = 0;
     86    pThis->fSignaled = 0;
     87    KernAllocSpinLock(&pThis->Spinlock);
     88
     89    *phEventSem = pThis;
     90    return VINF_SUCCESS;
     91}
     92
     93
     94RTDECL(int)  RTSemEventDestroy(RTSEMEVENT hEventSem)
     95{
     96    PRTSEMEVENTINTERNAL pThis = hEventSem;
     97    if (pThis == NIL_RTSEMEVENT)
    8198        return VINF_SUCCESS;
    82     }
    83     return VERR_NO_MEMORY;
    84 }
    85 
    86 
    87 RTDECL(int)  RTSemEventDestroy(RTSEMEVENT EventSem)
    88 {
    89     if (EventSem == NIL_RTSEMEVENT)     /* don't bitch */
    90         return VERR_INVALID_HANDLE;
    91     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    92     AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE);
    93     AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC,
    94                     ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic),
    95                     VERR_INVALID_HANDLE);
    96 
    97     KernAcquireSpinLock(&pEventInt->Spinlock);
    98     ASMAtomicIncU32(&pEventInt->u32Magic); /* make the handle invalid */
    99     if (pEventInt->cWaiters > 0)
     99    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     100    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
     101
     102    KernAcquireSpinLock(&pThis->Spinlock);
     103    ASMAtomicIncU32(&pThis->u32Magic); /* make the handle invalid */
     104    if (pThis->cWaiters > 0)
    100105    {
    101106        /* abort waiting thread, last man cleans up. */
    102         ASMAtomicXchgU32(&pEventInt->cWaking, pEventInt->cWaking + pEventInt->cWaiters);
     107        ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters);
    103108        ULONG cThreads;
    104         KernWakeup((ULONG)pEventInt, WAKEUP_DATA | WAKEUP_BOOST, &cThreads, (ULONG)VERR_SEM_DESTROYED);
    105         KernReleaseSpinLock(&pEventInt->Spinlock);
    106     }
    107     else if (pEventInt->cWaking)
     109        KernWakeup((ULONG)pThis, WAKEUP_DATA | WAKEUP_BOOST, &cThreads, (ULONG)VERR_SEM_DESTROYED);
     110        KernReleaseSpinLock(&pThis->Spinlock);
     111    }
     112    else if (pThis->cWaking)
    108113        /* the last waking thread is gonna do the cleanup */
    109         KernReleaseSpinLock(&pEventInt->Spinlock);
     114        KernReleaseSpinLock(&pThis->Spinlock);
    110115    else
    111116    {
    112         KernReleaseSpinLock(&pEventInt->Spinlock);
    113         KernFreeSpinLock(&pEventInt->Spinlock);
    114         RTMemFree(pEventInt);
     117        KernReleaseSpinLock(&pThis->Spinlock);
     118        KernFreeSpinLock(&pThis->Spinlock);
     119        RTMemFree(pThis);
    115120    }
    116121
     
    119124
    120125
    121 RTDECL(int)  RTSemEventSignal(RTSEMEVENT EventSem)
    122 {
    123     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    124     AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE);
    125     AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC,
    126                     ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic),
    127                     VERR_INVALID_HANDLE);
    128 
    129     KernAcquireSpinLock(&pEventInt->Spinlock);
    130 
    131     if (pEventInt->cWaiters > 0)
    132     {
    133         ASMAtomicDecU32(&pEventInt->cWaiters);
    134         ASMAtomicIncU32(&pEventInt->cWaking);
     126RTDECL(int)  RTSemEventSignal(RTSEMEVENT hEventSem)
     127{
     128    PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem;
     129    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     130    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
     131
     132    KernAcquireSpinLock(&pThis->Spinlock);
     133
     134    if (pThis->cWaiters > 0)
     135    {
     136        ASMAtomicDecU32(&pThis->cWaiters);
     137        ASMAtomicIncU32(&pThis->cWaking);
    135138        ULONG cThreads;
    136         KernWakeup((ULONG)pEventInt, WAKEUP_DATA | WAKEUP_ONE, &cThreads, VINF_SUCCESS);
     139        KernWakeup((ULONG)pThis, WAKEUP_DATA | WAKEUP_ONE, &cThreads, VINF_SUCCESS);
    137140        if (RT_UNLIKELY(!cThreads))
    138141        {
    139142            /* shouldn't ever happen on OS/2 */
    140             ASMAtomicXchgU8(&pEventInt->fSignaled, true);
    141             ASMAtomicDecU32(&pEventInt->cWaking);
    142             ASMAtomicIncU32(&pEventInt->cWaiters);
     143            ASMAtomicXchgU8(&pThis->fSignaled, true);
     144            ASMAtomicDecU32(&pThis->cWaking);
     145            ASMAtomicIncU32(&pThis->cWaiters);
    143146        }
    144147    }
    145148    else
    146         ASMAtomicXchgU8(&pEventInt->fSignaled, true);
    147 
    148     KernReleaseSpinLock(&pEventInt->Spinlock);
     149        ASMAtomicXchgU8(&pThis->fSignaled, true);
     150
     151    KernReleaseSpinLock(&pThis->Spinlock);
    149152    return VINF_SUCCESS;
    150153}
    151154
    152155
    153 static int rtSemEventWait(RTSEMEVENT EventSem, unsigned cMillies, bool fInterruptible)
    154 {
    155     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    156     AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE);
    157     AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC,
    158                     ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic),
    159                     VERR_INVALID_HANDLE);
    160 
    161     KernAcquireSpinLock(&pEventInt->Spinlock);
     156static int rtSemEventWait(RTSEMEVENT hEventSem, unsigned cMillies, bool fInterruptible)
     157{
     158    PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem;
     159    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     160    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
     161
     162    KernAcquireSpinLock(&pThis->Spinlock);
    162163
    163164    int rc;
    164     if (pEventInt->fSignaled)
    165     {
    166         Assert(!pEventInt->cWaiters);
    167         ASMAtomicXchgU8(&pEventInt->fSignaled, false);
     165    if (pThis->fSignaled)
     166    {
     167        Assert(!pThis->cWaiters);
     168        ASMAtomicXchgU8(&pThis->fSignaled, false);
    168169        rc = VINF_SUCCESS;
    169170    }
    170171    else
    171172    {
    172         ASMAtomicIncU32(&pEventInt->cWaiters);
     173        ASMAtomicIncU32(&pThis->cWaiters);
    173174
    174175        ULONG ulData = (ULONG)VERR_INTERNAL_ERROR;
    175         rc = KernBlock((ULONG)pEventInt,
     176        rc = KernBlock((ULONG)pThis,
    176177                       cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : cMillies,
    177178                       BLOCK_SPINLOCK | (!fInterruptible ? BLOCK_UNINTERRUPTABLE : 0),
    178                        &pEventInt->Spinlock,
     179                       &pThis->Spinlock,
    179180                       &ulData);
    180181        switch (rc)
     
    183184                rc = (int)ulData;
    184185                Assert(rc == VINF_SUCCESS || rc == VERR_SEM_DESTROYED);
    185                 Assert(pEventInt->cWaking > 0);
    186                 if (    !ASMAtomicDecU32(&pEventInt->cWaking)
    187                     &&  pEventInt->u32Magic != RTSEMEVENT_MAGIC)
     186                Assert(pThis->cWaking > 0);
     187                if (    !ASMAtomicDecU32(&pThis->cWaking)
     188                    &&  pThis->u32Magic != RTSEMEVENT_MAGIC)
    188189                {
    189190                    /* The event was destroyed (ulData == VINF_SUCCESS if it was after we awoke), as
    190191                       the last thread do the cleanup. */
    191                     KernReleaseSpinLock(&pEventInt->Spinlock);
    192                     KernFreeSpinLock(&pEventInt->Spinlock);
    193                     RTMemFree(pEventInt);
     192                    KernReleaseSpinLock(&pThis->Spinlock);
     193                    KernFreeSpinLock(&pThis->Spinlock);
     194                    RTMemFree(pThis);
    194195                    return rc;
    195196                }
     
    198199            case ERROR_TIMEOUT:
    199200                Assert(cMillies != RT_INDEFINITE_WAIT);
    200                 ASMAtomicDecU32(&pEventInt->cWaiters);
     201                ASMAtomicDecU32(&pThis->cWaiters);
    201202                rc = VERR_TIMEOUT;
    202203                break;
     
    204205            case ERROR_INTERRUPT:
    205206                Assert(fInterruptible);
    206                 ASMAtomicDecU32(&pEventInt->cWaiters);
     207                ASMAtomicDecU32(&pThis->cWaiters);
    207208                rc = VERR_INTERRUPTED;
    208209                break;
     
    215216    }
    216217
    217     KernReleaseSpinLock(&pEventInt->Spinlock);
     218    KernReleaseSpinLock(&pThis->Spinlock);
    218219    return rc;
    219220}
    220221
    221222
    222 RTDECL(int)  RTSemEventWait(RTSEMEVENT EventSem, unsigned cMillies)
    223 {
    224     return rtSemEventWait(EventSem, cMillies, false /* not interruptible */);
    225 }
    226 
    227 
    228 RTDECL(int)  RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies)
    229 {
    230     return rtSemEventWait(EventSem, cMillies, true /* interruptible */);
    231 }
    232 
     223RTDECL(int)  RTSemEventWait(RTSEMEVENT hEventSem, unsigned cMillies)
     224{
     225    return rtSemEventWait(hEventSem, cMillies, false /* not interruptible */);
     226}
     227
     228
     229RTDECL(int)  RTSemEventWaitNoResume(RTSEMEVENT hEventSem, unsigned cMillies)
     230{
     231    return rtSemEventWait(hEventSem, cMillies, true /* interruptible */);
     232}
     233
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