Index: trunk/src/odincrt/critsect.cpp
===================================================================
--- trunk/src/odincrt/critsect.cpp	(revision 10530)
+++ trunk/src/odincrt/critsect.cpp	(revision 10533)
@@ -1,3 +1,3 @@
-/* $Id: critsect.cpp,v 1.10 2003-07-28 17:32:58 sandervl Exp $ */
+/* $Id: critsect.cpp,v 1.11 2004-03-16 17:24:53 sandervl Exp $ */
 /*
  * Critical sections in the Win32 sense
@@ -6,25 +6,22 @@
  *
  */
+#define INCL_DOS
 #define INCL_DOSPROCESS
 #define INCL_DOSERRORS
 #define INCL_DOSSEMAPHORES
-#include <os2wrap.h>
-#include <win32type.h>
-#include <win32api.h>
+#include <os2.h>
+
+#include "dbglog.h"
+
+#include <odincrt.h>
 #include <FastInfoBlocks.h>
 
 #undef fibGetPid
 
-#include <assert.h>
-#include <stdio.h>
-
-#include <odincrt.h>
-
-#ifdef DEBUG
-#define DebugInt3()	_interrupt(3)
-#else
+#undef dprintf
+#undef DebugInt3
+
+#define dprintf(a)
 #define DebugInt3()
-#endif
-
 
 //******************************************************************************
@@ -68,30 +65,16 @@
 //******************************************************************************
 //******************************************************************************
-inline ULONG GetCurrentProcessId()
-{
-#ifdef fibGetPid
-    return fibGetPid();
-#else
-    PTIB   ptib;
-    PPIB   ppib;
+ULONG WIN32API DosInitializeCriticalSection(CRITICAL_SECTION_OS2 *crit, char *pszSemName, BOOL fShared)
+{
     APIRET rc;
 
-    rc = DosGetInfoBlocks(&ptib, &ppib);
-    if(rc == NO_ERROR) {
-        return ppib->pib_ulpid;
-    }
-    DebugInt3();
-    return 0;
-#endif
-}
-
-/***********************************************************************
- *           DosInitializeCriticalSection
- */
-ULONG WIN32API DosInitializeCriticalSection(CRITICAL_SECTION_OS2 *crit,
-                                            PSZ pszSemName, BOOL fShared)
-{
-    APIRET rc;
-
+    rc = DosCreateEventSem(pszSemName, &crit->hevLock, (pszSemName || fShared)? DC_SEM_SHARED: 0, 0);
+    
+    if(rc != NO_ERROR) 
+    {
+        crit->hevLock = 0;
+        return rc;
+    }
+    
     // initialize lock count with special value -1, meaning noone posesses it
     crit->LockCount      = -1;
@@ -99,56 +82,61 @@
     crit->OwningThread   = 0;
 
-    rc = DosCreateEventSem(pszSemName, &crit->hmtxLock, (pszSemName || fShared) ? DC_SEM_SHARED : 0, 0);
-    if(rc != NO_ERROR) {
-        DebugInt3();
-        crit->hmtxLock = 0;
-        return rc;
-    }
     crit->CreationCount  = 1;
-    crit->Reserved       = GetCurrentProcessId();
-    return NO_ERROR;
-}
-
-
-/***********************************************************************
- *           DosAccessCriticalSection
- */
-ULONG WIN32API DosAccessCriticalSection(CRITICAL_SECTION_OS2 *crit, PSZ pszSemName)
-{
-    HMTX   hmtxLock = 0;
-    APIRET rc;
-
-    if(pszSemName == NULL && crit->hmtxLock == 0) {
-        DebugInt3();
-        return ERROR_INVALID_PARAMETER;
-    }
-    if(pszSemName == NULL) {
-        hmtxLock = crit->hmtxLock;
-    }
-
-    rc = DosOpenEventSem(pszSemName, &hmtxLock);
-    if(rc != NO_ERROR) {
-        DebugInt3();
-        return rc;
-    }
+    crit->Reserved       = 0;
+    
+    return NO_ERROR;
+}
+
+ULONG WIN32API DosValidateCriticalSection (CRITICAL_SECTION_OS2 *crit)
+{
+    if (crit->hevLock != NULLHANDLE)
+    {
+        return NO_ERROR;
+    }
+    
+    return ERROR_INVALID_PARAMETER;
+}
+
+// Initializes or opens a critical section
+ULONG WIN32API DosAccessCriticalSection(CRITICAL_SECTION_OS2 *crit, char *pszSemName)
+{
+    APIRET rc = NO_ERROR;
+    
+    // Increment creation counter to prevent the section to be destroyed while 
+    // we are checking it. Assume that an unitialized section has the counter == 0
     DosInterlockedIncrement(&crit->CreationCount);
-    return NO_ERROR;
-}
-/***********************************************************************
- *           DosDeleteCriticalSection
- */
+    
+    if (DosValidateCriticalSection (crit) == NO_ERROR)
+    {
+        // the section already initialized, use it
+        HEV hevLock = NULLHANDLE;
+        
+        if (pszSemName == NULL)
+        {
+            hevLock = crit->hevLock;
+        }
+
+        rc = DosOpenEventSem(pszSemName, &hevLock);
+
+        if (rc != NO_ERROR)
+        {
+            DosInterlockedDecrement(&crit->CreationCount);
+            DebugInt3();
+        }
+    }
+    else
+    {
+        rc = DosInitializeCriticalSection (crit, pszSemName, TRUE);
+    }
+     
+    return NO_ERROR;
+}
+
 ULONG WIN32API DosDeleteCriticalSection( CRITICAL_SECTION_OS2 *crit )
 {
-    if (crit->hmtxLock)
-    {
-#ifdef DEBUG
-        if (  (crit->LockCount != -1 && crit->CreationCount == 1)
-            || crit->OwningThread
-            || crit->RecursionCount)  /* Should not happen */
-        {
-           DebugInt3();
-        }
-#endif
-        DosCloseEventSem(crit->hmtxLock);
+    if (DosValidateCriticalSection (crit))
+    {
+        DosCloseEventSem (crit->hevLock);
+        
         if(DosInterlockedDecrement(&crit->CreationCount) == 0)
         {
@@ -156,80 +144,124 @@
             crit->RecursionCount = 0;
             crit->OwningThread   = 0;
-            crit->hmtxLock       = 0;
-            crit->Reserved       = (DWORD)-1;
-        }
-    }
-    return NO_ERROR;
-}
-
-
-/***********************************************************************
- *           DosEnterCriticalSection
+            crit->hevLock        = 0;
+            crit->Reserved       = 0;
+        }
+    }
+    return NO_ERROR;
+}
+
+
+ULONG WIN32API DosEnterCriticalSection( CRITICAL_SECTION_OS2 *crit, ULONG ulTimeout )
+{
+    APIRET rc = NO_ERROR;
+            
+    ULONG threadid = GetCurrentThreadId();
+            
+    if (!crit->hevLock)
+    {
+        rc = DosInitializeCriticalSection (crit, NULL, FALSE);
+        if (rc != NO_ERROR)
+        {
+            return rc;
+        }
+    }
+
+    dprintf(("Entering the section: owner = %8.8X\n", crit->OwningThread));
+
+    // We want to acquire the section, count the entering
+    DosInterlockedIncrement (&crit->LockCount);
+    
+    // try to acquire the section
+    for (;;)
+    {
+        // try to assign owning thread id atomically
+        if (DosInterlockedCompareExchange((PLONG)&crit->OwningThread, threadid, 0) == 0)
+        {
+            ULONG ulnrposts = 0;
+
+            dprintf(("Acquired the section: owner = %8.8X\n", crit->OwningThread));
+            DosResetEventSem (crit->hevLock, &ulnrposts);
+            break;
+        }
+        
+        if (crit->OwningThread == threadid)
+        {
+            // This thread already owns the section
+            crit->RecursionCount++;
+            dprintf(("Recursion: %d\n", crit->RecursionCount));
+            return NO_ERROR;
+        }
+
+        // Arise any timing problems and let others to run
+        DosSleep (0);
+
+        dprintf(("Waiting on sem: owner = %8.8X\n", crit->OwningThread));
+        rc = DosWaitEventSem (crit->hevLock, ulTimeout);
+        dprintf(("Returned from wait: owner = %8.8X, rc = %d\n", crit->OwningThread, rc));
+       
+        if (rc != NO_ERROR) 
+        {
+            dprintf(("Returned from wait: FAILED!!!\n"));
+            // We fail, deregister itself
+            DosInterlockedDecrement (&crit->LockCount);
+            return rc;
+        }
+    }
+    
+    // the section was successfully aquired
+    crit->RecursionCount = 1;
+    
+    if (crit->Reserved != 0)
+    {
+        // the section already entered!!!!
+        DosBeep (2000, 200);
+    }
+    
+    crit->Reserved = 1;
+    
+    return NO_ERROR;
+}
+
+
+ULONG WIN32API DosLeaveCriticalSection( CRITICAL_SECTION_OS2 *crit )
+{
+    dprintf(("Leaving the section\n"));
+    if (crit->OwningThread != GetCurrentThreadId()) {
+        dprintf(("WRONG THREAD ID!!! owner is %8.8X\n", crit->OwningThread));
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    if (--crit->RecursionCount)
+    {
+        dprintf(("Recursion exit: %d\n", crit->RecursionCount));
+        DosInterlockedDecrement( &crit->LockCount );
+        return NO_ERROR;
+    }
+    
+    crit->Reserved = 0;
+    crit->OwningThread = 0;
+
+    dprintf(("Released the section\n"));
+
+    if (DosInterlockedDecrement( &crit->LockCount ) >= 0)
+    {
+        dprintf(("Posted the semaphore\n"));
+        DosPostEventSem(crit->hevLock);
+    }
+    
+    return NO_ERROR;
+}
+
+
+/**
+ * Checks if the current thread is in the critical section or now.
+ *
+ * @returns NO_ERROR if in the critical section.
+ * @returns ERROR_NOT_OWNER if not in the critical section.
+ * @param   pCrit   Pointer to the critical section.
  */
-ULONG WIN32API DosEnterCriticalSection( CRITICAL_SECTION_OS2 *crit, ULONG ulTimeout )
-{
-    DWORD res;
-    DWORD threadid = GetCurrentThreadId();
-
-    // create crit sect just in time...
-    if (!crit->hmtxLock)
-    {
-    	DosInitializeCriticalSection(crit, NULL);
-    }
-    // if the same thread is requesting it again, memorize it
-    if (crit->OwningThread == threadid)
-    {
-        crit->RecursionCount++;
-        return NO_ERROR;
-    }
-
-    // do an atomic increase of the lockcounter
-    DosInterlockedIncrement(&crit->LockCount);
-
-    // do an atomic operation where we compare the owning thread id with 0
-    // and if this is true, exchange it with the id of the current thread.
-testenter:
-    if(DosInterlockedCompareExchange((PLONG)&crit->OwningThread, threadid, 0))
-    {
-        // the crit sect is in use
-        ULONG ulnrposts;
-
-        // now wait for it
-        APIRET rc = DosWaitEventSem(crit->hmtxLock, ulTimeout);
-        if(rc != NO_ERROR) {
-            DebugInt3();
-            return rc;
-        }
-        DosResetEventSem(crit->hmtxLock, &ulnrposts);
-        // multiple waiters could be running now. Repeat the logic so that
-        // only one actually can get the critical section
-        goto testenter;
-    }
-    crit->RecursionCount = 1;
-    return NO_ERROR;
-}
-
-
-/***********************************************************************
- *           DosLeaveCriticalSection
- */
-ULONG WIN32API DosLeaveCriticalSection( CRITICAL_SECTION_OS2 *crit )
-{
-    if (crit->OwningThread != GetCurrentThreadId()) {
-        DebugInt3();
-        return ERROR_INVALID_PARAMETER;
-    }
-
-    if (--crit->RecursionCount)
-    {
-        //just return
-        return NO_ERROR;
-    }
-    crit->OwningThread = 0;
-    if (DosInterlockedDecrement( &crit->LockCount ) >= 0)
-    {
-        /* Someone is waiting */
-        DosPostEventSem(crit->hmtxLock);
-    }
-    return NO_ERROR;
-}
+ULONG WIN32API DosIsInCriticalSection( CRITICAL_SECTION_OS2 *pCrit )
+{
+    return  (pCrit->hevLock && pCrit->OwningThread == GetCurrentThreadId() ? NO_ERROR : ERROR_NOT_OWNER);
+}
+
Index: trunk/src/odincrt/odin36.def
===================================================================
--- trunk/src/odincrt/odin36.def	(revision 10530)
+++ trunk/src/odincrt/odin36.def	(revision 10533)
@@ -1,3 +1,3 @@
-; $Id: odin36.def,v 1.10 2003-07-28 11:30:17 sandervl Exp $
+; $Id: odin36.def,v 1.11 2004-03-16 17:24:53 sandervl Exp $
 ; Odin VAC++ 3.6.5 shared multithreaded runtime
 LIBRARY ODINCRT INITINSTANCE TERMINSTANCE
@@ -986,2 +986,3 @@
     _DosInterlockedExchangeAdd@8                       @1208 NONAME
     _DosInterlockedIncrement@4                         @1209 NONAME
+    _DosValidateCriticalSection@4                      @1210 NONAME
Index: trunk/src/odincrt/odin36d.def
===================================================================
--- trunk/src/odincrt/odin36d.def	(revision 10530)
+++ trunk/src/odincrt/odin36d.def	(revision 10533)
@@ -1,3 +1,3 @@
-; $Id: odin36d.def,v 1.10 2003-07-28 11:30:18 sandervl Exp $
+; $Id: odin36d.def,v 1.11 2004-03-16 17:24:54 sandervl Exp $
 ; Odin VAC++ 3.6.5 shared multithreaded runtime
 LIBRARY ODINCRTD INITINSTANCE TERMINSTANCE
@@ -994,2 +994,3 @@
     _DosInterlockedExchangeAdd@8                       @1208 NONAME
     _DosInterlockedIncrement@4                         @1209 NONAME
+    _DosValidateCriticalSection@4                      @1210 NONAME
Index: trunk/src/odincrt/odincrt.def
===================================================================
--- trunk/src/odincrt/odincrt.def	(revision 10530)
+++ trunk/src/odincrt/odincrt.def	(revision 10533)
@@ -1,3 +1,3 @@
-; $Id: odincrt.def,v 1.30 2003-07-28 11:30:19 sandervl Exp $
+; $Id: odincrt.def,v 1.31 2004-03-16 17:24:54 sandervl Exp $
 ; Odin VAC++ 3.08 shared multithreaded runtime
 LIBRARY ODINCRT INITINSTANCE TERMINSTANCE
@@ -967,2 +967,3 @@
     _DosInterlockedExchangeAdd@8                       @1208 NONAME
     _DosInterlockedIncrement@4                         @1209 NONAME
+    _DosValidateCriticalSection@4                      @1210 NONAME
Index: trunk/src/odincrt/odincrtd.def
===================================================================
--- trunk/src/odincrt/odincrtd.def	(revision 10530)
+++ trunk/src/odincrt/odincrtd.def	(revision 10533)
@@ -1,3 +1,3 @@
-; $Id: odincrtd.def,v 1.11 2003-07-28 11:30:19 sandervl Exp $
+; $Id: odincrtd.def,v 1.12 2004-03-16 17:24:54 sandervl Exp $
 ; Odin VAC++ 3.08 shared multithreaded runtime
 LIBRARY ODINCRTD INITINSTANCE TERMINSTANCE
@@ -966,2 +966,3 @@
     _DosInterlockedExchangeAdd@8                       @1208 NONAME
     _DosInterlockedIncrement@4                         @1209 NONAME
+    _DosValidateCriticalSection@4                      @1210 NONAME
Index: trunk/src/odincrt/odincrtp.def
===================================================================
--- trunk/src/odincrt/odincrtp.def	(revision 10530)
+++ trunk/src/odincrt/odincrtp.def	(revision 10533)
@@ -1,3 +1,3 @@
-; $Id: odincrtp.def,v 1.8 2003-07-28 11:30:20 sandervl Exp $
+; $Id: odincrtp.def,v 1.9 2004-03-16 17:24:54 sandervl Exp $
 ; Odin VAC++ 3.08 shared multithreaded runtime
 LIBRARY ODINCRTP INITINSTANCE TERMINSTANCE
@@ -987,2 +987,3 @@
     _DosInterlockedExchangeAdd@8                       @1208 NONAME
     _DosInterlockedIncrement@4                         @1209 NONAME
+    _DosValidateCriticalSection@4                      @1210 NONAME
