Changeset 10580 for trunk/src


Ignore:
Timestamp:
Apr 14, 2004, 10:45:45 AM (21 years ago)
Author:
sandervl
Message:

backed out changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/odincrt/critsect.cpp

    r10533 r10580  
    1 /* $Id: critsect.cpp,v 1.11 2004-03-16 17:24:53 sandervl Exp $ */
     1/* $Id: critsect.cpp,v 1.12 2004-04-14 08:45:45 sandervl Exp $ */
    22/*
    33 * Critical sections in the Win32 sense
     
    66 *
    77 */
    8 #define INCL_DOS
    98#define INCL_DOSPROCESS
    109#define INCL_DOSERRORS
    1110#define INCL_DOSSEMAPHORES
    12 #include <os2.h>
    13 
    14 #include "dbglog.h"
     11#include <os2wrap.h>
     12#include <win32type.h>
     13#include <win32api.h>
     14#include <FastInfoBlocks.h>
     15
     16#include <assert.h>
     17#include <stdio.h>
    1518
    1619#include <odincrt.h>
    17 #include <FastInfoBlocks.h>
     20
    1821
    1922#undef fibGetPid
     
    2427#define dprintf(a)
    2528#define DebugInt3()
     29
     30
     31ULONG WIN32API DosValidateCriticalSection (CRITICAL_SECTION_OS2 *crit)
     32{
     33    if (crit->hevLock != NULLHANDLE)
     34    {
     35        return NO_ERROR;
     36    }
     37   
     38    return ERROR_INVALID_PARAMETER;
     39}
    2640
    2741//******************************************************************************
     
    6579//******************************************************************************
    6680//******************************************************************************
    67 ULONG WIN32API DosInitializeCriticalSection(CRITICAL_SECTION_OS2 *crit, char *pszSemName, BOOL fShared)
    68 {
     81inline ULONG GetCurrentProcessId()
     82{
     83#ifdef fibGetPid
     84    return fibGetPid();
     85#else
     86    PTIB   ptib;
     87    PPIB   ppib;
    6988    APIRET rc;
    7089
    71     rc = DosCreateEventSem(pszSemName, &crit->hevLock, (pszSemName || fShared)? DC_SEM_SHARED: 0, 0);
    72    
    73     if(rc != NO_ERROR)
    74     {
    75         crit->hevLock = 0;
    76         return rc;
    77     }
    78    
     90    rc = DosGetInfoBlocks(&ptib, &ppib);
     91    if(rc == NO_ERROR) {
     92        return ppib->pib_ulpid;
     93    }
     94    DebugInt3();
     95    return 0;
     96#endif
     97}
     98
     99/***********************************************************************
     100 *           DosInitializeCriticalSection
     101 */
     102ULONG WIN32API DosInitializeCriticalSection(CRITICAL_SECTION_OS2 *crit,
     103                                            PSZ pszSemName, BOOL fShared)
     104{
     105    APIRET rc;
     106
    79107    // initialize lock count with special value -1, meaning noone posesses it
    80108    crit->LockCount      = -1;
     
    82110    crit->OwningThread   = 0;
    83111
     112    rc = DosCreateEventSem(pszSemName, &crit->hevLock, (pszSemName || fShared) ? DC_SEM_SHARED : 0, 0);
     113    if(rc != NO_ERROR) {
     114        DebugInt3();
     115        crit->hevLock = 0;
     116        return rc;
     117    }
    84118    crit->CreationCount  = 1;
    85     crit->Reserved       = 0;
    86    
    87     return NO_ERROR;
    88 }
    89 
    90 ULONG WIN32API DosValidateCriticalSection (CRITICAL_SECTION_OS2 *crit)
    91 {
    92     if (crit->hevLock != NULLHANDLE)
    93     {
    94         return NO_ERROR;
    95     }
    96    
    97     return ERROR_INVALID_PARAMETER;
    98 }
    99 
    100 // Initializes or opens a critical section
    101 ULONG WIN32API DosAccessCriticalSection(CRITICAL_SECTION_OS2 *crit, char *pszSemName)
     119    crit->Reserved       = GetCurrentProcessId();
     120    return NO_ERROR;
     121}
     122
     123
     124/***********************************************************************
     125 *           DosAccessCriticalSection
     126 */
     127ULONG WIN32API DosAccessCriticalSection(CRITICAL_SECTION_OS2 *crit, PSZ pszSemName)
    102128{
    103129    APIRET rc = NO_ERROR;
     
    132158    return NO_ERROR;
    133159}
    134 
     160/***********************************************************************
     161 *           DosDeleteCriticalSection
     162 */
    135163ULONG WIN32API DosDeleteCriticalSection( CRITICAL_SECTION_OS2 *crit )
    136164{
    137     if (DosValidateCriticalSection (crit))
    138     {
    139         DosCloseEventSem (crit->hevLock);
    140        
     165    if (crit->hevLock)
     166    {
     167#ifdef DEBUG
     168        if (  (crit->LockCount != -1 && crit->CreationCount == 1)
     169            || crit->OwningThread
     170            || crit->RecursionCount)  /* Should not happen */
     171        {
     172           DebugInt3();
     173        }
     174#endif
     175        DosCloseEventSem(crit->hevLock);
    141176        if(DosInterlockedDecrement(&crit->CreationCount) == 0)
    142177        {
     
    144179            crit->RecursionCount = 0;
    145180            crit->OwningThread   = 0;
    146             crit->hevLock        = 0;
    147             crit->Reserved       = 0;
    148         }
    149     }
    150     return NO_ERROR;
    151 }
    152 
    153 
     181            crit->hevLock       = 0;
     182            crit->Reserved       = (DWORD)-1;
     183        }
     184    }
     185    return NO_ERROR;
     186}
     187
     188
     189/***********************************************************************
     190 *           DosEnterCriticalSection
     191 */
    154192ULONG WIN32API DosEnterCriticalSection( CRITICAL_SECTION_OS2 *crit, ULONG ulTimeout )
    155193{
    156     APIRET rc = NO_ERROR;
    157            
    158     ULONG threadid = GetCurrentThreadId();
    159            
     194    DWORD res;
     195    DWORD threadid = GetCurrentThreadId();
     196
     197    // create crit sect just in time...
    160198    if (!crit->hevLock)
    161199    {
    162         rc = DosInitializeCriticalSection (crit, NULL, FALSE);
    163         if (rc != NO_ERROR)
    164         {
     200        DosInitializeCriticalSection(crit, NULL);
     201    }
     202    // if the same thread is requesting it again, memorize it
     203    if (crit->OwningThread == threadid)
     204    {
     205        crit->RecursionCount++;
     206        return NO_ERROR;
     207    }
     208
     209    // do an atomic increase of the lockcounter
     210    DosInterlockedIncrement(&crit->LockCount);
     211
     212    // do an atomic operation where we compare the owning thread id with 0
     213    // and if this is true, exchange it with the id of the current thread.
     214testenter:
     215    if(DosInterlockedCompareExchange((PLONG)&crit->OwningThread, threadid, 0))
     216    {
     217        // the crit sect is in use
     218        ULONG ulnrposts;
     219
     220        // now wait for it
     221        APIRET rc = DosWaitEventSem(crit->hevLock, ulTimeout);
     222        if(rc != NO_ERROR) {
     223            DebugInt3();
    165224            return rc;
    166225        }
    167     }
    168 
    169     dprintf(("Entering the section: owner = %8.8X\n", crit->OwningThread));
    170 
    171     // We want to acquire the section, count the entering
    172     DosInterlockedIncrement (&crit->LockCount);
    173    
    174     // try to acquire the section
    175     for (;;)
    176     {
    177         // try to assign owning thread id atomically
    178         if (DosInterlockedCompareExchange((PLONG)&crit->OwningThread, threadid, 0) == 0)
    179         {
    180             ULONG ulnrposts = 0;
    181 
    182             dprintf(("Acquired the section: owner = %8.8X\n", crit->OwningThread));
    183             DosResetEventSem (crit->hevLock, &ulnrposts);
    184             break;
    185         }
    186        
    187         if (crit->OwningThread == threadid)
    188         {
    189             // This thread already owns the section
    190             crit->RecursionCount++;
    191             dprintf(("Recursion: %d\n", crit->RecursionCount));
    192             return NO_ERROR;
    193         }
    194 
    195         // Arise any timing problems and let others to run
    196         DosSleep (0);
    197 
    198         dprintf(("Waiting on sem: owner = %8.8X\n", crit->OwningThread));
    199         rc = DosWaitEventSem (crit->hevLock, ulTimeout);
    200         dprintf(("Returned from wait: owner = %8.8X, rc = %d\n", crit->OwningThread, rc));
    201        
    202         if (rc != NO_ERROR)
    203         {
    204             dprintf(("Returned from wait: FAILED!!!\n"));
    205             // We fail, deregister itself
    206             DosInterlockedDecrement (&crit->LockCount);
    207             return rc;
    208         }
    209     }
    210    
    211     // the section was successfully aquired
     226        DosResetEventSem(crit->hevLock, &ulnrposts);
     227        // multiple waiters could be running now. Repeat the logic so that
     228        // only one actually can get the critical section
     229        goto testenter;
     230    }
    212231    crit->RecursionCount = 1;
    213    
    214     if (crit->Reserved != 0)
    215     {
    216         // the section already entered!!!!
    217         DosBeep (2000, 200);
    218     }
    219    
    220     crit->Reserved = 1;
    221    
    222     return NO_ERROR;
    223 }
    224 
    225 
     232    return NO_ERROR;
     233}
     234
     235
     236/***********************************************************************
     237 *           DosLeaveCriticalSection
     238 */
    226239ULONG WIN32API DosLeaveCriticalSection( CRITICAL_SECTION_OS2 *crit )
    227240{
    228     dprintf(("Leaving the section\n"));
    229241    if (crit->OwningThread != GetCurrentThreadId()) {
    230         dprintf(("WRONG THREAD ID!!! owner is %8.8X\n", crit->OwningThread));
     242        DebugInt3();
    231243        return ERROR_INVALID_PARAMETER;
    232244    }
     
    234246    if (--crit->RecursionCount)
    235247    {
    236         dprintf(("Recursion exit: %d\n", crit->RecursionCount));
    237         DosInterlockedDecrement( &crit->LockCount );
     248        //just return
    238249        return NO_ERROR;
    239250    }
    240    
    241     crit->Reserved = 0;
    242251    crit->OwningThread = 0;
    243 
    244     dprintf(("Released the section\n"));
    245 
    246252    if (DosInterlockedDecrement( &crit->LockCount ) >= 0)
    247253    {
    248         dprintf(("Posted the semaphore\n"));
     254        /* Someone is waiting */
    249255        DosPostEventSem(crit->hevLock);
    250256    }
    251    
    252     return NO_ERROR;
    253 }
    254 
    255 
    256 /**
    257  * Checks if the current thread is in the critical section or now.
    258  *
    259  * @returns NO_ERROR if in the critical section.
    260  * @returns ERROR_NOT_OWNER if not in the critical section.
    261  * @param   pCrit   Pointer to the critical section.
    262  */
    263 ULONG WIN32API DosIsInCriticalSection( CRITICAL_SECTION_OS2 *pCrit )
    264 {
    265     return  (pCrit->hevLock && pCrit->OwningThread == GetCurrentThreadId() ? NO_ERROR : ERROR_NOT_OWNER);
    266 }
    267 
     257    return NO_ERROR;
     258}
Note: See TracChangeset for help on using the changeset viewer.