+bool wxThreadModule::OnInit()
+{
+    gs_pCritsectWaitingForGui = new wxCriticalSection();
+
+    gs_pCritsectGui = new wxCriticalSection();
+    gs_pCritsectGui->Enter();
+
+    PTIB                            ptib;
+    PPIB                            ppib;
+
+    ::DosGetInfoBlocks(&ptib, &ppib);
+
+    s_ulIdMainThread = ptib->tib_ptib2->tib2_ultid;
+    return TRUE;
+}
+
+void wxThreadModule::OnExit()
+{
+    if (gs_pCritsectGui)
+    {
+        gs_pCritsectGui->Leave();
+#if (!(defined(__VISAGECPP__) && (__IBMCPP__ < 400 || __IBMC__ < 400 )))
+        delete gs_pCritsectGui;
+#endif
+        gs_pCritsectGui = NULL;
+    }
+
+#if (!(defined(__VISAGECPP__) && (__IBMCPP__ < 400 || __IBMC__ < 400 )))
+    wxDELETE(gs_pCritsectWaitingForGui);
+#endif
+}
+
+// ----------------------------------------------------------------------------
+// Helper functions
+// ----------------------------------------------------------------------------
+
+// Does nothing under OS/2 [for now]
+void WXDLLEXPORT wxWakeUpMainThread()
+{
+}
+
+void WXDLLEXPORT wxMutexGuiLeave()
+{
+    wxCriticalSectionLocker enter(*gs_pCritsectWaitingForGui);
+
+    if ( wxThread::IsMain() )
+    {
+        gs_bGuiOwnedByMainThread = FALSE;
+    }
+    else
+    {
+        // decrement the number of waiters now
+        wxASSERT_MSG(gs_nWaitingForGui > 0,
+                      wxT("calling wxMutexGuiLeave() without entering it first?") );
+
+        gs_nWaitingForGui--;
+
+        wxWakeUpMainThread();
+    }
+
+    gs_pCritsectGui->Leave();
+}
+
+void WXDLLEXPORT wxMutexGuiLeaveOrEnter()
+{
+    wxASSERT_MSG( wxThread::IsMain(),
+                  wxT("only main thread may call wxMutexGuiLeaveOrEnter()!") );
+
+    wxCriticalSectionLocker enter(*gs_pCritsectWaitingForGui);
+
+    if (gs_nWaitingForGui == 0)
+    {
+        // no threads are waiting for GUI - so we may acquire the lock without
+        // any danger (but only if we don't already have it)
+        if (!wxGuiOwnedByMainThread())
+        {
+            gs_pCritsectGui->Enter();
+
+            gs_bGuiOwnedByMainThread = TRUE;
+        }
+        //else: already have it, nothing to do
+    }
+    else
+    {
+        // some threads are waiting, release the GUI lock if we have it
+        if (wxGuiOwnedByMainThread())
+        {
+            wxMutexGuiLeave();
+        }
+        //else: some other worker thread is doing GUI
+    }
+}
+
+bool WXDLLEXPORT wxGuiOwnedByMainThread()
+{
+    return gs_bGuiOwnedByMainThread;
+}
+
+bool WXDLLEXPORT wxIsWaitingForThread()
+{
+    return gs_bWaitingForThread;
+}
+