Triued in vain to fix threads segvs with gcc

Removed wxDebugStream


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1308 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
1999-01-02 22:24:41 +00:00
parent 83624f7960
commit d524867f4c
15 changed files with 158 additions and 270 deletions

View File

@@ -16,17 +16,16 @@
#pragma interface "thread.h" #pragma interface "thread.h"
#endif #endif
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "wx/object.h" #include "wx/object.h"
#include "wx/setup.h" #include "wx/setup.h"
#include "wx/module.h"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// constants // constants
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
typedef enum { typedef enum
{
wxMUTEX_NO_ERROR = 0, wxMUTEX_NO_ERROR = 0,
wxMUTEX_DEAD_LOCK, // Mutex has been already locked by THE CALLING thread wxMUTEX_DEAD_LOCK, // Mutex has been already locked by THE CALLING thread
wxMUTEX_BUSY, // Mutex has been already locked by ONE thread wxMUTEX_BUSY, // Mutex has been already locked by ONE thread
@@ -34,7 +33,8 @@ typedef enum {
wxMUTEX_MISC_ERROR wxMUTEX_MISC_ERROR
} wxMutexError; } wxMutexError;
typedef enum { typedef enum
{
wxTHREAD_NO_ERROR = 0, // No error wxTHREAD_NO_ERROR = 0, // No error
wxTHREAD_NO_RESOURCE, // No resource left to create a new thread wxTHREAD_NO_RESOURCE, // No resource left to create a new thread
wxTHREAD_RUNNING, // The thread is already running wxTHREAD_RUNNING, // The thread is already running
@@ -42,16 +42,25 @@ typedef enum {
wxTHREAD_MISC_ERROR // Some other error wxTHREAD_MISC_ERROR // Some other error
} wxThreadError; } wxThreadError;
// defines the interval of priority. /* defines the interval of priority. */
#define WXTHREAD_MIN_PRIORITY 0 #define WXTHREAD_MIN_PRIORITY 0
#define WXTHREAD_DEFAULT_PRIORITY 50 #define WXTHREAD_DEFAULT_PRIORITY 50
#define WXTHREAD_MAX_PRIORITY 100 #define WXTHREAD_MAX_PRIORITY 100
// ----------------------------------------------------------------------------
// GUI mutex handling.
// ----------------------------------------------------------------------------
void WXDLLEXPORT wxMutexGuiEnter();
void WXDLLEXPORT wxMutexGuiLeave();
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Mutex handler // Mutex handler
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class WXDLLEXPORT wxMutexInternal; class WXDLLEXPORT wxMutexInternal;
class WXDLLEXPORT wxMutex { class WXDLLEXPORT wxMutex
{
public: public:
// constructor & destructor // constructor & destructor
wxMutex(); wxMutex();
@@ -77,8 +86,10 @@ protected:
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Condition handler. // Condition handler.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class wxConditionInternal; class wxConditionInternal;
class WXDLLEXPORT wxCondition { class WXDLLEXPORT wxCondition
{
public: public:
// constructor & destructor // constructor & destructor
wxCondition(); wxCondition();
@@ -100,8 +111,10 @@ private:
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Thread management class // Thread management class
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class wxThreadInternal; class wxThreadInternal;
class WXDLLEXPORT wxThread { class WXDLLEXPORT wxThread
{
public: public:
// constructor & destructor. // constructor & destructor.
wxThread(); wxThread();
@@ -165,11 +178,20 @@ private:
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Global functions and variables // Automatic initialization
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// GUI mutex handling. class wxThreadModule : public wxModule
void WXDLLEXPORT wxMutexGuiEnter(); {
void WXDLLEXPORT wxMutexGuiLeave(); DECLARE_DYNAMIC_CLASS(wxThreadModule)
public:
wxThreadModule() {}
virtual bool OnInit();
virtual void OnExit();
};
#endif // __THREADH__ #endif // __THREADH__

View File

@@ -157,46 +157,6 @@ WXDLLEXPORT wxWindow* wxFindWindowByName(const wxString& name, wxWindow *parent
// Returns menu item id or -1 if none. // Returns menu item id or -1 if none.
WXDLLEXPORT int wxFindMenuItemId(wxFrame *frame, const wxString& menuString, const wxString& itemString); WXDLLEXPORT int wxFindMenuItemId(wxFrame *frame, const wxString& menuString, const wxString& itemString);
// A debugging stream buffer.
// Under Windows, this writes to the Windows debug output.
// Under other platforms, it writes to cerr.
// ALl this horrible gubbins required for Borland, because the calling
// convention needs to be the same as for streambuf.
// Thanks to Gerhard.Vogt@embl-heidelberg.de for this solution.
#if defined(__BORLANDC__) && defined(__BCOPT__) && !defined(_RTL_ALLOW_po) && !defined(__FLAT__)
#pragma option -po-
#endif
// Can't export a class derived from a non-export class
#if !defined(_WINDLL) && !defined(WXUSINGDLL)
// #ifdef new
// #undef new
// #endif
class WXDLLEXPORT wxDebugStreamBuf: public streambuf
{
public:
wxDebugStreamBuf(void);
~wxDebugStreamBuf(void) {}
int overflow(int i);
inline int underflow(void) { return EOF; }
int sync(void);
};
// #if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS
// #define new WXDEBUG_NEW
// #endif
#endif
#if defined(__BORLANDC__) && defined(__BCOPT__) && !defined(_RTL_ALLOW_po) && !defined(__FLAT__)
#pragma option -po.
#endif
/* /*
#if (!defined(__MINMAX_DEFINED) && !defined(max)) #if (!defined(__MINMAX_DEFINED) && !defined(max))
#define max(a,b) (((a) > (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b))
@@ -204,6 +164,7 @@ class WXDLLEXPORT wxDebugStreamBuf: public streambuf
#define __MINMAX_DEFINED 1 #define __MINMAX_DEFINED 1
#endif #endif
*/ */
#define wxMax(a,b) (((a) > (b)) ? (a) : (b)) #define wxMax(a,b) (((a) > (b)) ? (a) : (b))
#define wxMin(a,b) (((a) < (b)) ? (a) : (b)) #define wxMin(a,b) (((a) < (b)) ? (a) : (b))

View File

@@ -17,7 +17,7 @@ BIN_OBJ=\
test.o test.o
# additional things needed to link # additional things needed to link
BIN_LINK= $(THREADS_LINK) BIN_LINK=
# additional things needed to compile # additional things needed to compile
ADD_COMPILE= ADD_COMPILE=

View File

@@ -104,10 +104,6 @@ $(GUI_TK_INCLUDE) \
$(OPENGL_INCLUDE) \ $(OPENGL_INCLUDE) \
$(X_CFLAGS) $(X_CFLAGS)
# -I$(WXBASEDIR)/src/png \
# -I$(WXBASEDIR)/src/zlib \
# -I$(WXBASEDIR)/src/gdk_imlib \
WX_LIBS = -L$(GLOBAL_LIB_DIR) $(WX_LINK) WX_LIBS = -L$(GLOBAL_LIB_DIR) $(WX_LINK)
OPENGL_LIBS = $(OPENGL_LIBRARY) $(OPENGL_LINK) OPENGL_LIBS = $(OPENGL_LIBRARY) $(OPENGL_LINK)

View File

@@ -562,54 +562,6 @@ wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& i
return menuBar->FindMenuItem (menuString, itemString); return menuBar->FindMenuItem (menuString, itemString);
} }
/*
* wxDebugStreamBuf
*/
#if !defined(_WINDLL)
wxDebugStreamBuf::wxDebugStreamBuf(void)
{
// <iostream> usage doesn't need this, and i have no idea how to simulate it.
#if wxUSE_IOSTREAMH
if (allocate())
setp(base(),ebuf());
#endif
}
int wxDebugStreamBuf::overflow(int WXUNUSED(i))
{
int len = pptr() - pbase();
char *txt = new char[len+1];
strncpy(txt, pbase(), len);
txt[len] = '\0';
#ifdef __WXMSW__
OutputDebugString((LPCSTR)txt);
#else
fprintf(stderr, txt);
#endif
setp(pbase(), epptr());
delete[] txt;
return EOF;
}
int wxDebugStreamBuf::sync(void)
{
int len = pptr() - pbase();
char *txt = new char[len+1];
strncpy(txt, pbase(), len);
txt[len] = '\0';
#ifdef __WXMSW__
OutputDebugString((LPCSTR)txt);
#else
fprintf(stderr, txt);
#endif
setp(pbase(), epptr());
delete[] txt;
return 0;
}
#endif
/* /*
On Fri, 21 Jul 1995, Paul Craven wrote: On Fri, 21 Jul 1995, Paul Craven wrote:

View File

@@ -191,21 +191,21 @@ void wxApp::OnIdle( wxIdleEvent &event )
{ {
static bool inOnIdle = FALSE; static bool inOnIdle = FALSE;
// Avoid recursion (via ProcessEvent default case) /* Avoid recursion (via ProcessEvent default case) */
if (inOnIdle) if (inOnIdle)
return; return;
inOnIdle = TRUE; inOnIdle = TRUE;
// 'Garbage' collection of windows deleted with Close(). /* 'Garbage' collection of windows deleted with Close(). */
DeletePendingObjects(); DeletePendingObjects();
// flush the logged messages if any /* flush the logged messages if any */
wxLog *pLog = wxLog::GetActiveTarget(); wxLog *log = wxLog::GetActiveTarget();
if (pLog != NULL && pLog->HasPendingMessages()) if (log != NULL && log->HasPendingMessages())
pLog->Flush(); log->Flush();
// Send OnIdle events to all windows /* Send OnIdle events to all windows */
bool needMore = SendIdleEvents(); bool needMore = SendIdleEvents();
if (needMore) if (needMore)
@@ -372,14 +372,6 @@ int wxEntry( int argc, char *argv[] )
wxClassInfo::InitializeClasses(); wxClassInfo::InitializeClasses();
/* Debug stream no longer used
#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
streambuf* sBuf = new wxDebugStreamBuf;
ostream* oStr = new ostream(sBuf) ;
wxDebugContext::SetStream(oStr, sBuf);
#endif
*/
if (!wxTheApp) if (!wxTheApp)
{ {
@@ -474,7 +466,6 @@ int wxEntry( int argc, char *argv[] )
wxDebugContext::Dump(); wxDebugContext::Dump();
wxDebugContext::PrintStatistics(); wxDebugContext::PrintStatistics();
} }
// wxDebugContext::SetStream(NULL, NULL);
#endif #endif

View File

@@ -160,15 +160,10 @@ void wxThread::OnExit()
} }
// Automatic initialization IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
class wxThreadModule : public wxModule {
DECLARE_DYNAMIC_CLASS(wxThreadModule)
public:
bool OnInit();
void OnExit();
};
bool wxThreadModule::OnInit() { bool wxThreadModule::OnInit()
{
wxMainMutex = new wxMutex(); wxMainMutex = new wxMutex();
wxMainMutex->Lock(); wxMainMutex->Lock();
return TRUE; return TRUE;
@@ -180,7 +175,7 @@ void wxThreadModule::OnExit()
delete wxMainMutex; delete wxMainMutex;
} }
IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
void wxMutexGuiEnter() void wxMutexGuiEnter()
{ {

View File

@@ -43,7 +43,7 @@ enum thread_state
static pthread_t p_mainid; static pthread_t p_mainid;
wxMutex *wxMainMutex; // controls access to all GUI functions wxMutex *wxMainMutex; /* controls access to all GUI functions */
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// common GUI thread code // common GUI thread code
@@ -182,7 +182,7 @@ void *wxThreadInternal::PthreadStart(void *ptr)
{ {
wxThread *thread = (wxThread *)ptr; wxThread *thread = (wxThread *)ptr;
// Call the main entry /* Call the main entry */
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
void* status = thread->Entry(); void* status = thread->Entry();
@@ -200,7 +200,7 @@ wxThreadError wxThread::Create()
if (p_internal->state != STATE_IDLE) if (p_internal->state != STATE_IDLE)
return wxTHREAD_RUNNING; return wxTHREAD_RUNNING;
// Change thread priority /* Change thread priority */
pthread_attr_init(&a); pthread_attr_init(&a);
pthread_attr_getschedpolicy(&a, &p); pthread_attr_getschedpolicy(&a, &p);
@@ -365,7 +365,7 @@ wxThread::~wxThread()
delete p_internal; delete p_internal;
} }
// The default callback just joins the thread and throws away the result. /* The default callback just joins the thread and throws away the result. */
void wxThread::OnExit() void wxThread::OnExit()
{ {
Join(); Join();
@@ -375,28 +375,22 @@ void wxThread::OnExit()
// wxThreadModule // wxThreadModule
//-------------------------------------------------------------------- //--------------------------------------------------------------------
class wxThreadModule : public wxModule IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
{
DECLARE_DYNAMIC_CLASS(wxThreadModule)
public: bool wxThreadModule::OnInit()
virtual bool OnInit() {
{
wxMainMutex = new wxMutex(); wxMainMutex = new wxMutex();
wxThreadGuiInit(); wxThreadGuiInit();
p_mainid = pthread_self(); p_mainid = (int)getpid();
wxMainMutex->Lock(); wxMainMutex->Lock();
return TRUE; return TRUE;
} }
virtual void OnExit() void wxThreadModule::OnExit()
{ {
wxMainMutex->Unlock(); wxMainMutex->Unlock();
wxThreadGuiExit(); wxThreadGuiExit();
delete wxMainMutex; delete wxMainMutex;
} }
};
IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)

View File

@@ -238,21 +238,22 @@ void wxThread::OnExit()
} }
// Global initialization // Global initialization
class wxThreadModule : public wxModule {
DECLARE_DYNAMIC_CLASS(wxThreadModule) IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
public:
virtual bool OnInit() { bool wxThreadModule::OnInit()
{
wxMainMutex = new wxMutex(); wxMainMutex = new wxMutex();
wxThreadGuiInit(); wxThreadGuiInit();
p_mainid = (int)getpid(); p_mainid = (int)getpid();
wxMainMutex->Lock(); wxMainMutex->Lock();
} return TRUE;
}
virtual void OnExit() { void wxThreadModule::OnExit()
{
wxMainMutex->Unlock(); wxMainMutex->Unlock();
wxThreadGuiExit(); wxThreadGuiExit();
delete wxMainMutex; delete wxMainMutex;
} }
};
IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)

View File

@@ -191,21 +191,21 @@ void wxApp::OnIdle( wxIdleEvent &event )
{ {
static bool inOnIdle = FALSE; static bool inOnIdle = FALSE;
// Avoid recursion (via ProcessEvent default case) /* Avoid recursion (via ProcessEvent default case) */
if (inOnIdle) if (inOnIdle)
return; return;
inOnIdle = TRUE; inOnIdle = TRUE;
// 'Garbage' collection of windows deleted with Close(). /* 'Garbage' collection of windows deleted with Close(). */
DeletePendingObjects(); DeletePendingObjects();
// flush the logged messages if any /* flush the logged messages if any */
wxLog *pLog = wxLog::GetActiveTarget(); wxLog *log = wxLog::GetActiveTarget();
if (pLog != NULL && pLog->HasPendingMessages()) if (log != NULL && log->HasPendingMessages())
pLog->Flush(); log->Flush();
// Send OnIdle events to all windows /* Send OnIdle events to all windows */
bool needMore = SendIdleEvents(); bool needMore = SendIdleEvents();
if (needMore) if (needMore)
@@ -372,14 +372,6 @@ int wxEntry( int argc, char *argv[] )
wxClassInfo::InitializeClasses(); wxClassInfo::InitializeClasses();
/* Debug stream no longer used
#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
streambuf* sBuf = new wxDebugStreamBuf;
ostream* oStr = new ostream(sBuf) ;
wxDebugContext::SetStream(oStr, sBuf);
#endif
*/
if (!wxTheApp) if (!wxTheApp)
{ {
@@ -474,7 +466,6 @@ int wxEntry( int argc, char *argv[] )
wxDebugContext::Dump(); wxDebugContext::Dump();
wxDebugContext::PrintStatistics(); wxDebugContext::PrintStatistics();
} }
// wxDebugContext::SetStream(NULL, NULL);
#endif #endif

View File

@@ -160,15 +160,10 @@ void wxThread::OnExit()
} }
// Automatic initialization IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
class wxThreadModule : public wxModule {
DECLARE_DYNAMIC_CLASS(wxThreadModule)
public:
bool OnInit();
void OnExit();
};
bool wxThreadModule::OnInit() { bool wxThreadModule::OnInit()
{
wxMainMutex = new wxMutex(); wxMainMutex = new wxMutex();
wxMainMutex->Lock(); wxMainMutex->Lock();
return TRUE; return TRUE;
@@ -180,7 +175,7 @@ void wxThreadModule::OnExit()
delete wxMainMutex; delete wxMainMutex;
} }
IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
void wxMutexGuiEnter() void wxMutexGuiEnter()
{ {

View File

@@ -43,7 +43,7 @@ enum thread_state
static pthread_t p_mainid; static pthread_t p_mainid;
wxMutex *wxMainMutex; // controls access to all GUI functions wxMutex *wxMainMutex; /* controls access to all GUI functions */
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// common GUI thread code // common GUI thread code
@@ -182,7 +182,7 @@ void *wxThreadInternal::PthreadStart(void *ptr)
{ {
wxThread *thread = (wxThread *)ptr; wxThread *thread = (wxThread *)ptr;
// Call the main entry /* Call the main entry */
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
void* status = thread->Entry(); void* status = thread->Entry();
@@ -200,7 +200,7 @@ wxThreadError wxThread::Create()
if (p_internal->state != STATE_IDLE) if (p_internal->state != STATE_IDLE)
return wxTHREAD_RUNNING; return wxTHREAD_RUNNING;
// Change thread priority /* Change thread priority */
pthread_attr_init(&a); pthread_attr_init(&a);
pthread_attr_getschedpolicy(&a, &p); pthread_attr_getschedpolicy(&a, &p);
@@ -365,7 +365,7 @@ wxThread::~wxThread()
delete p_internal; delete p_internal;
} }
// The default callback just joins the thread and throws away the result. /* The default callback just joins the thread and throws away the result. */
void wxThread::OnExit() void wxThread::OnExit()
{ {
Join(); Join();
@@ -375,28 +375,22 @@ void wxThread::OnExit()
// wxThreadModule // wxThreadModule
//-------------------------------------------------------------------- //--------------------------------------------------------------------
class wxThreadModule : public wxModule IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
{
DECLARE_DYNAMIC_CLASS(wxThreadModule)
public: bool wxThreadModule::OnInit()
virtual bool OnInit() {
{
wxMainMutex = new wxMutex(); wxMainMutex = new wxMutex();
wxThreadGuiInit(); wxThreadGuiInit();
p_mainid = pthread_self(); p_mainid = (int)getpid();
wxMainMutex->Lock(); wxMainMutex->Lock();
return TRUE; return TRUE;
} }
virtual void OnExit() void wxThreadModule::OnExit()
{ {
wxMainMutex->Unlock(); wxMainMutex->Unlock();
wxThreadGuiExit(); wxThreadGuiExit();
delete wxMainMutex; delete wxMainMutex;
} }
};
IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)

View File

@@ -238,21 +238,22 @@ void wxThread::OnExit()
} }
// Global initialization // Global initialization
class wxThreadModule : public wxModule {
DECLARE_DYNAMIC_CLASS(wxThreadModule) IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
public:
virtual bool OnInit() { bool wxThreadModule::OnInit()
{
wxMainMutex = new wxMutex(); wxMainMutex = new wxMutex();
wxThreadGuiInit(); wxThreadGuiInit();
p_mainid = (int)getpid(); p_mainid = (int)getpid();
wxMainMutex->Lock(); wxMainMutex->Lock();
} return TRUE;
}
virtual void OnExit() { void wxThreadModule::OnExit()
{
wxMainMutex->Unlock(); wxMainMutex->Unlock();
wxThreadGuiExit(); wxThreadGuiExit();
delete wxMainMutex; delete wxMainMutex;
} }
};
IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)

View File

@@ -414,30 +414,24 @@ void wxThread::OnExit()
// wxThreadModule // wxThreadModule
//-------------------------------------------------------------------- //--------------------------------------------------------------------
class wxThreadModule : public wxModule IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
{
DECLARE_DYNAMIC_CLASS(wxThreadModule)
public: bool wxThreadModule::OnInit()
virtual bool OnInit() {
{
wxMainMutex = new wxMutex(); wxMainMutex = new wxMutex();
wxThreadGuiInit(); wxThreadGuiInit();
p_mainid = pthread_self(); p_mainid = pthread_self();
wxMainMutex->Lock(); wxMainMutex->Lock();
return TRUE; return TRUE;
} }
virtual void OnExit() void wxThreadModule::OnExit()
{ {
wxMainMutex->Unlock(); wxMainMutex->Unlock();
wxThreadGuiExit(); wxThreadGuiExit();
delete wxMainMutex; delete wxMainMutex;
}
}; };
IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
#endif #endif
// wxUSE_THREADS // wxUSE_THREADS

View File

@@ -366,25 +366,7 @@ void wxThread::OnExit()
Join(); Join();
} }
// Automatic initialization // GUI mutex functions
class wxThreadModule : public wxModule {
DECLARE_DYNAMIC_CLASS(wxThreadModule)
public:
virtual bool OnInit() {
wxMainMutex = new wxMutex();
p_mainid = GetCurrentThread();
wxMainMutex->Lock();
return TRUE;
}
// Global cleanup
virtual void OnExit() {
wxMainMutex->Unlock();
delete wxMainMutex;
}
};
IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
void WXDLLEXPORT wxMutexGuiEnter() void WXDLLEXPORT wxMutexGuiEnter()
{ {
@@ -395,3 +377,22 @@ void WXDLLEXPORT wxMutexGuiLeave()
{ {
wxFAIL_MSG("not implemented"); wxFAIL_MSG("not implemented");
} }
// Automatic initialization
IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
bool wxThreadModule::OnInit()
{
wxMainMutex = new wxMutex();
p_mainid = GetCurrentThread();
wxMainMutex->Lock();
return TRUE;
}
void wxThreadModule::OnExit()
{
wxMainMutex->Unlock();
delete wxMainMutex;
};