]> git.saurik.com Git - wxWidgets.git/commitdiff
1. Pause()/Resume() implemented for wxMSW
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 27 Dec 1998 00:54:53 +0000 (00:54 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 27 Dec 1998 00:54:53 +0000 (00:54 +0000)
2. crash on startup in the sample corrected

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1267 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/thread.h
samples/thread/test.cpp
src/msw/thread.cpp

index 4ecfaa271ee0faf451384f3a403618e7a2cb7e60..b02df5244f1e0d52dab50b6ed3484added7ccabd 100644 (file)
 #pragma interface "thread.h"
 #endif
 
 #pragma interface "thread.h"
 #endif
 
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
 #include "wx/object.h"
 #include "wx/setup.h"
 
 #include "wx/object.h"
 #include "wx/setup.h"
 
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
 typedef enum {
 typedef enum {
-  MUTEX_NO_ERROR=0,
-  MUTEX_DEAD_LOCK,             // Mutex has been already locked by THE CALLING thread 
-  MUTEX_BUSY,                  // Mutex has been already locked by ONE thread
-  MUTEX_UNLOCKED
+  wxMUTEX_NO_ERROR = 0,
+  wxMUTEX_DEAD_LOCK,      // Mutex has been already locked by THE CALLING thread 
+  wxMUTEX_BUSY,           // Mutex has been already locked by ONE thread
+  wxMUTEX_UNLOCKED,
+  wxMUTEX_MISC_ERROR
 } wxMutexError;
 
 typedef enum {
 } wxMutexError;
 
 typedef enum {
-  THREAD_NO_ERROR=0,           // No error
-  THREAD_NO_RESOURCE,          // No resource left to create a new thread
-  THREAD_RUNNING,              // The thread is already running
-  THREAD_NOT_RUNNING,          // The thread isn't running
-  THREAD_MISC_ERROR             // Some other error
+  wxTHREAD_NO_ERROR = 0,      // No error
+  wxTHREAD_NO_RESOURCE,       // No resource left to create a new thread
+  wxTHREAD_RUNNING,           // The thread is already running
+  wxTHREAD_NOT_RUNNING,       // The thread isn't running
+  wxTHREAD_MISC_ERROR         // Some other error
 } wxThreadError;
 
 // defines the interval of priority.
 } wxThreadError;
 
 // 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
 
 
-// ---------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
 // Mutex handler
 // Mutex handler
+// ----------------------------------------------------------------------------
 class WXDLLEXPORT wxMutexInternal;
 class WXDLLEXPORT wxMutex {
 public:
 class WXDLLEXPORT wxMutexInternal;
 class WXDLLEXPORT wxMutex {
 public:
@@ -57,6 +66,7 @@ public:
 
   // Returns true if the mutex is locked.
   bool IsLocked() const { return (m_locked > 0); }
 
   // Returns true if the mutex is locked.
   bool IsLocked() const { return (m_locked > 0); }
+
 protected:
   friend class wxCondition;
 
 protected:
   friend class wxCondition;
 
@@ -64,8 +74,9 @@ protected:
   wxMutexInternal *p_internal;
 };
 
   wxMutexInternal *p_internal;
 };
 
-// ---------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
 // Condition handler.
 // Condition handler.
+// ----------------------------------------------------------------------------
 class wxConditionInternal;
 class WXDLLEXPORT wxCondition {
 public:
 class wxConditionInternal;
 class WXDLLEXPORT wxCondition {
 public:
@@ -81,12 +92,14 @@ public:
   void Signal();
   // Broadcasts to all "Waiters".
   void Broadcast();
   void Signal();
   // Broadcasts to all "Waiters".
   void Broadcast();
+
 private:
   wxConditionInternal *p_internal;
 };
 
 private:
   wxConditionInternal *p_internal;
 };
 
-// ---------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
 // Thread management class
 // Thread management class
+// ----------------------------------------------------------------------------
 class wxThreadInternal;
 class WXDLLEXPORT wxThread {
 public:
 class wxThreadInternal;
 class WXDLLEXPORT wxThread {
 public:
@@ -126,6 +139,9 @@ public:
   bool IsAlive() const;
   // Returns true if the thread is running (not paused, not killed).
   bool IsRunning() const;
   bool IsAlive() const;
   // Returns true if the thread is running (not paused, not killed).
   bool IsRunning() const;
+  // Returns true if the thread is suspended
+  bool IsPaused() const { return IsAlive() && !IsRunning(); }
+
   // Returns true if the thread is the main thread (aka the GUI thread).
   static bool IsMain();
 
   // Returns true if the thread is the main thread (aka the GUI thread).
   static bool IsMain();
 
@@ -137,6 +153,7 @@ protected:
   void TestDestroy();
   // Exits from the current thread.
   void Exit(void *status = NULL);
   void TestDestroy();
   // Exits from the current thread.
   void Exit(void *status = NULL);
+
 private:
   // Entry point for the thread.
   virtual void *Entry() = 0;
 private:
   // Entry point for the thread.
   virtual void *Entry() = 0;
@@ -147,11 +164,12 @@ private:
   wxThreadInternal *p_internal;
 };
 
   wxThreadInternal *p_internal;
 };
 
-// ---------------------------------------------------------------------------
-// Global variables
+// ----------------------------------------------------------------------------
+// Global functions and variables
+// ----------------------------------------------------------------------------
 
 // GUI mutex handling.
 void WXDLLEXPORT wxMutexGuiEnter();
 void WXDLLEXPORT wxMutexGuiLeave();
 
 
 // GUI mutex handling.
 void WXDLLEXPORT wxMutexGuiEnter();
 void WXDLLEXPORT wxMutexGuiLeave();
 
-#endif
+#endif // __THREADH__
index 1455acf3c582ef61c5d6e80571177cf51c66277a..071f954478ed68a21489ac28593c20fe7a0eddf1 100644 (file)
 // Define a new application type
 class MyApp: public wxApp
 {
 // Define a new application type
 class MyApp: public wxApp
 {
- public:
+public:
     bool OnInit(void);
 };
 
     bool OnInit(void);
 };
 
-WX_DEFINE_ARRAY(wxThread *,wxArrayThread);
+WX_DEFINE_ARRAY(wxThread *, wxArrayThread);
 
 // Define a new frame type
 class MyFrame: public wxFrame
 {
 
 // Define a new frame type
 class MyFrame: public wxFrame
 {
- public:
+public:
+    // ctor
     MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
     
     MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
     
- public:
+    // operations
+    void WriteText(const wxString& text) { m_txtctrl->WriteText(text); }
+
+    // callbacks
     void OnQuit(wxCommandEvent& event);
     void OnAbout(wxCommandEvent& event);
     void OnQuit(wxCommandEvent& event);
     void OnAbout(wxCommandEvent& event);
+
     void OnStartThread(wxCommandEvent& event);
     void OnStopThread(wxCommandEvent& event);
     void OnPauseThread(wxCommandEvent& event);
     void OnStartThread(wxCommandEvent& event);
     void OnStopThread(wxCommandEvent& event);
     void OnPauseThread(wxCommandEvent& event);
+    void OnResumeThread(wxCommandEvent& event);
+
     void OnSize(wxSizeEvent &event);
     bool OnClose(void) { return TRUE; }
     void OnSize(wxSizeEvent &event);
     bool OnClose(void) { return TRUE; }
+    
+public:
+    wxArrayThread m_threads;
 
 
- public:
-   wxArrayThread m_threads;
-   wxTextCtrl *m_txtctrl;
-
-   DECLARE_EVENT_TABLE()
+private:
+    wxTextCtrl *m_txtctrl;
+    
+    DECLARE_EVENT_TABLE()
 };
 
 class MyThread: public wxThread
 {
 };
 
 class MyThread: public wxThread
 {
- public:
+public:
     MyThread(MyFrame *frame);
     MyThread(MyFrame *frame);
-
+    
     void *Entry();
     void *Entry();
- public:
+
+public:
+    size_t   m_count;
     MyFrame *m_frame;
 };
 
 MyThread::MyThread(MyFrame *frame)
     MyFrame *m_frame;
 };
 
 MyThread::MyThread(MyFrame *frame)
-  : wxThread()
+        : wxThread()
 {
 {
-  m_frame = frame;
+    m_count = 0;
+    m_frame = frame;
 }
 
 void *MyThread::Entry()
 {
 }
 
 void *MyThread::Entry()
 {
-  wxString text;
-
-  text.Printf("Thread 0x%x: Hello !\n", GetID());
-  DeferDestroy(TRUE);
-
-  while (1) {
-    TestDestroy();
-    wxMutexGuiEnter();
-    m_frame->m_txtctrl->WriteText(text);
-    wxMutexGuiLeave();
-    wxSleep(1);
-  }
-  
-  return NULL;
+    wxString text;
+   
+    DeferDestroy(TRUE);
+    
+    while (1) {
+        TestDestroy();
+        wxMutexGuiEnter();
+
+        text.Printf("[%u] Thread 0x%x here.\n", ++m_count, GetID());
+        m_frame->WriteText(text);
+
+        wxMutexGuiLeave();
+        wxSleep(1);
+    }
+    
+    return NULL;
 }
 
 // ID for the menu commands
 }
 
 // ID for the menu commands
@@ -100,14 +114,17 @@ void *MyThread::Entry()
 #define TEST_START_THREAD 103
 #define TEST_STOP_THREAD  104
 #define TEST_PAUSE_THREAD 105
 #define TEST_START_THREAD 103
 #define TEST_STOP_THREAD  104
 #define TEST_PAUSE_THREAD 105
+#define TEST_RESUME_THREAD 106
 
 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
 
 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
-       EVT_MENU(TEST_QUIT, MyFrame::OnQuit)
-       EVT_MENU(TEST_ABOUT, MyFrame::OnAbout)
-       EVT_MENU(TEST_START_THREAD, MyFrame::OnStartThread)
-       EVT_MENU(TEST_STOP_THREAD, MyFrame::OnStopThread)
-       EVT_MENU(TEST_PAUSE_THREAD, MyFrame::OnPauseThread)
-       EVT_SIZE(MyFrame::OnSize)
+    EVT_MENU(TEST_QUIT, MyFrame::OnQuit)
+    EVT_MENU(TEST_ABOUT, MyFrame::OnAbout)
+    EVT_MENU(TEST_START_THREAD, MyFrame::OnStartThread)
+    EVT_MENU(TEST_STOP_THREAD, MyFrame::OnStopThread)
+    EVT_MENU(TEST_PAUSE_THREAD, MyFrame::OnPauseThread)
+    EVT_MENU(TEST_RESUME_THREAD, MyFrame::OnResumeThread)
+
+    EVT_SIZE(MyFrame::OnSize)
 END_EVENT_TABLE()
 
 // Create a new application object
 END_EVENT_TABLE()
 
 // Create a new application object
@@ -116,93 +133,117 @@ IMPLEMENT_APP    (MyApp)
 // `Main program' equivalent, creating windows and returning main app frame
 bool MyApp::OnInit(void)
 {
 // `Main program' equivalent, creating windows and returning main app frame
 bool MyApp::OnInit(void)
 {
-  // Create the main frame window
-  MyFrame *frame = new MyFrame((wxFrame *) NULL, (char *) "Minimal wxWindows App", 50, 50, 450, 340);
-
-  // Make a menubar
-  wxMenu *file_menu = new wxMenu;
-
-  file_menu->Append(TEST_ABOUT, "&About");
-  file_menu->Append(TEST_QUIT, "E&xit");
-  wxMenuBar *menu_bar = new wxMenuBar;
-  menu_bar->Append(file_menu, "&File");
-
-  wxMenu *thread_menu = new wxMenu;
-  thread_menu->Append(TEST_START_THREAD, "Start a new thread");
-  thread_menu->Append(TEST_STOP_THREAD, "Stop a running thread");
-  thread_menu->Append(TEST_PAUSE_THREAD, "Pause a running thread");
-  menu_bar->Append(thread_menu, "Thread");
-  frame->SetMenuBar(menu_bar);
-
-  // Make a panel with a message
-  wxPanel *panel = new wxPanel( frame, -1, wxPoint(0, 0), wxSize(400, 200), wxTAB_TRAVERSAL );
-  
-  (void)new wxStaticText( panel, -1, "Log window", wxPoint(10,10) );
-  
-
-  frame->m_txtctrl = new wxTextCtrl(panel, -1, "", wxPoint(10,30), wxSize(390, 190),
-                           wxTE_MULTILINE);
-
-  // Show the frame
-  frame->Show(TRUE);
-  
-  SetTopWindow(frame);
-
-  return TRUE;
+    // Create the main frame window
+    MyFrame *frame = new MyFrame((wxFrame *) NULL, "wxWindows thread sample",
+                                 50, 50, 450, 340);
+    
+    // Make a menubar
+    wxMenu *file_menu = new wxMenu;
+    
+    file_menu->Append(TEST_ABOUT, "&About");
+    file_menu->Append(TEST_QUIT, "E&xit");
+    wxMenuBar *menu_bar = new wxMenuBar;
+    menu_bar->Append(file_menu, "&File");
+    
+    wxMenu *thread_menu = new wxMenu;
+    thread_menu->Append(TEST_START_THREAD, "Start a new thread");
+    thread_menu->Append(TEST_STOP_THREAD, "Stop a running thread");
+    thread_menu->AppendSeparator();
+    thread_menu->Append(TEST_PAUSE_THREAD, "Pause a running thread");
+    thread_menu->Append(TEST_RESUME_THREAD, "Resume suspended thread");
+    menu_bar->Append(thread_menu, "Thread");
+    frame->SetMenuBar(menu_bar);
+    
+    // Show the frame
+    frame->Show(TRUE);
+    
+    SetTopWindow(frame);
+    
+    return TRUE;
 }
 
 // My frame constructor
 }
 
 // My frame constructor
-MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h):
-  wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h))
-{}
-
-void MyFrame::OnStartThread(wxCommandEvent& WXUNUSED(event) )
+MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
+       : wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h))
 {
 {
-  MyThread *thread = new MyThread(this);
+    wxPanel *panel = new wxPanel(this, -1, wxPoint(0, 0), wxSize(400, 200),
+                                 wxTAB_TRAVERSAL );
+    
+    m_txtctrl = new wxTextCtrl(panel, -1, "", wxPoint(10,30), wxSize(390, 190),
+                               wxTE_MULTILINE);
 
 
-  thread->Create();
+    (void)new wxStaticText(panel, -1, "Log window", wxPoint(10,10));
+}
 
 
-  m_threads.Add(thread);
+void MyFrame::OnStartThread(wxCommandEvent& WXUNUSED(event) )
+{
+    MyThread *thread = new MyThread(this);
+    
+    thread->Create();
+    
+    m_threads.Add(thread);
 }
 
 void MyFrame::OnStopThread(wxCommandEvent& WXUNUSED(event) )
 {
 }
 
 void MyFrame::OnStopThread(wxCommandEvent& WXUNUSED(event) )
 {
-  int no_thrd = m_threads.Count()-1;
-
-  if (no_thrd < 0)
-    return;
+    int no_thrd = m_threads.Count()-1;
+    
+    if (no_thrd < 0)
+        return;
+    
+    delete (m_threads[no_thrd]);
+    m_threads.Remove(no_thrd);
+}
 
 
-  delete (m_threads[no_thrd]);
-  m_threads.Remove(no_thrd);
+void MyFrame::OnResumeThread(wxCommandEvent& WXUNUSED(event) )
+{
+    // resume first suspended thread 
+    size_t n = 0;
+    while ( n < m_threads.Count() && m_threads[n]->IsPaused() )
+        n--;
+    
+    if ( n < 0 )
+        wxLogError("No thread to pause!");
+    else
+        m_threads[n]->Resume();
 }
 
 void MyFrame::OnPauseThread(wxCommandEvent& WXUNUSED(event) )
 {
 }
 
 void MyFrame::OnPauseThread(wxCommandEvent& WXUNUSED(event) )
 {
+    // pause last running thread 
+    int n = m_threads.Count() - 1;
+    while ( n >= 0 && !m_threads[n]->IsRunning() )
+        n--;
+    
+    if ( n < 0 )
+        wxLogError("No thread to pause!");
+    else
+        m_threads[n]->Pause();
 }
 
 void MyFrame::OnSize(wxSizeEvent& event )
 {
 }
 
 void MyFrame::OnSize(wxSizeEvent& event )
 {
-  wxFrame::OnSize(event);
-
-  wxSize size( GetClientSize() );
-  
-  m_txtctrl->SetSize( 10, 30, size.x-20, size.y-40 );
+    wxFrame::OnSize(event);
+    
+    wxSize size( GetClientSize() );
+    
+    m_txtctrl->SetSize( 10, 30, size.x-20, size.y-40 );
 }
 
 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
 {
 }
 
 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
 {
-  unsigned int i;
-  for (i=0;i<m_threads.Count();i++)
-    delete (m_threads[i]);
-  Close(TRUE);
+    unsigned int i;
+    for (i=0;i<m_threads.Count();i++)
+        delete (m_threads[i]);
+    Close(TRUE);
 }
 
 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
 {
 }
 
 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
 {
-  wxMessageDialog dialog(this, "wxThread sample (based on minimal)\nJulian Smart and Guilhem Lavaux",
-       "About wxThread sample", wxYES_NO|wxCANCEL);
-
-  dialog.ShowModal();
+    wxMessageDialog dialog(this, "wxThread sample (based on minimal)\nJulian Smart and Guilhem Lavaux",
+        "About wxThread sample", wxYES_NO|wxCANCEL);
+    
+    dialog.ShowModal();
 }
 
 
 }
 
 
index 6ca57c6ce33b549ec02fbe55178557482606f125..0832f9a2b7042b711709158923e26998bebc299a 100644 (file)
@@ -59,13 +59,18 @@ wxMutex::wxMutex()
 {
   p_internal = new wxMutexInternal;
   p_internal->p_mutex = CreateMutex(NULL, FALSE, NULL);
 {
   p_internal = new wxMutexInternal;
   p_internal->p_mutex = CreateMutex(NULL, FALSE, NULL);
+  if ( !p_internal->p_mutex )
+  {
+    wxLogSysError(_("Can not create mutex."));
+  }
+
   m_locked = 0;
 }
 
 wxMutex::~wxMutex()
 {
   if (m_locked > 0)
   m_locked = 0;
 }
 
 wxMutex::~wxMutex()
 {
   if (m_locked > 0)
-    wxDebugMsg("wxMutex warning: freeing a locked mutex (%d locks)\n", m_locked);
+    wxLogDebug("Warning: freeing a locked mutex (%d locks).", m_locked);
   CloseHandle(p_internal->p_mutex);
 }
 
   CloseHandle(p_internal->p_mutex);
 }
 
@@ -75,10 +80,10 @@ wxMutexError wxMutex::Lock()
 
   ret = WaitForSingleObject(p_internal->p_mutex, INFINITE);
   if (ret == WAIT_ABANDONED)
 
   ret = WaitForSingleObject(p_internal->p_mutex, INFINITE);
   if (ret == WAIT_ABANDONED)
-    return MUTEX_BUSY;
+    return wxMUTEX_BUSY;
 
   m_locked++;
 
   m_locked++;
-  return MUTEX_NO_ERROR;
+  return wxMUTEX_NO_ERROR;
 }
 
 wxMutexError wxMutex::TryLock()
 }
 
 wxMutexError wxMutex::TryLock()
@@ -87,23 +92,25 @@ wxMutexError wxMutex::TryLock()
 
   ret = WaitForSingleObject(p_internal->p_mutex, 0);
   if (ret == WAIT_TIMEOUT || ret == WAIT_ABANDONED)
 
   ret = WaitForSingleObject(p_internal->p_mutex, 0);
   if (ret == WAIT_TIMEOUT || ret == WAIT_ABANDONED)
-    return MUTEX_BUSY;
+    return wxMUTEX_BUSY;
 
   m_locked++;
 
   m_locked++;
-  return MUTEX_NO_ERROR;
+  return wxMUTEX_NO_ERROR;
 }
 
 wxMutexError wxMutex::Unlock()
 {
 }
 
 wxMutexError wxMutex::Unlock()
 {
-  BOOL ret;
-
   if (m_locked > 0)
     m_locked--;
 
   if (m_locked > 0)
     m_locked--;
 
-    // Why does this have 3 args? The redundant ones removed by JACS
-//  ret = ReleaseMutex(p_internal->p_mutex, 1, NULL);
-  ret = ReleaseMutex(p_internal->p_mutex);
-  return MUTEX_NO_ERROR;
+  BOOL ret = ReleaseMutex(p_internal->p_mutex);
+  if ( ret != 0 )
+  {
+      wxLogSysError(_("Couldn't release a mutex"));
+      return wxMUTEX_MISC_ERROR;
+  }
+
+  return wxMUTEX_NO_ERROR;
 }
 
 class wxConditionInternal {
 }
 
 class wxConditionInternal {
@@ -116,6 +123,11 @@ wxCondition::wxCondition()
 {
   p_internal = new wxConditionInternal;
   p_internal->event = CreateEvent(NULL, FALSE, FALSE, NULL);
 {
   p_internal = new wxConditionInternal;
   p_internal->event = CreateEvent(NULL, FALSE, FALSE, NULL);
+  if ( !p_internal->event )
+  {
+    wxLogSysError(_("Can not create event object."));
+  }
+
   p_internal->waiters = 0;
 }
 
   p_internal->waiters = 0;
 }
 
@@ -157,7 +169,12 @@ void wxCondition::Broadcast()
   int i;
 
   for (i=0;i<p_internal->waiters;i++)
   int i;
 
   for (i=0;i<p_internal->waiters;i++)
-    SetEvent(p_internal->event);
+  {
+    if ( SetEvent(p_internal->event) == 0 )
+    {
+        wxLogSysError(_("Couldn't change the state of event object."));
+    }
+  }
 }
 
 class wxThreadInternal {
 }
 
 class wxThreadInternal {
@@ -183,16 +200,19 @@ DWORD wxThreadInternal::WinThreadStart(LPVOID arg)
 
 wxThreadError wxThread::Create()
 {
 
 wxThreadError wxThread::Create()
 {
-  int win_prio, prio = p_internal->prio;
+  int prio = p_internal->prio;
 
   p_internal->thread_id = CreateThread(NULL, 0,
                    (LPTHREAD_START_ROUTINE)wxThreadInternal::WinThreadStart,
                    (void *)this, CREATE_SUSPENDED, &p_internal->tid);
 
   p_internal->thread_id = CreateThread(NULL, 0,
                    (LPTHREAD_START_ROUTINE)wxThreadInternal::WinThreadStart,
                    (void *)this, CREATE_SUSPENDED, &p_internal->tid);
-  if (p_internal->thread_id == NULL) {
-    printf("Error = %d\n", GetLastError());
-    return THREAD_NO_RESOURCE;
+
+  if ( p_internal->thread_id == NULL )
+  {
+    wxLogSysError(_("Can't create thread"));
+    return wxTHREAD_NO_RESOURCE;
   }
 
   }
 
+  int win_prio;
   if (prio <= 20)
     win_prio = THREAD_PRIORITY_LOWEST;
   else if (prio <= 40)
   if (prio <= 20)
     win_prio = THREAD_PRIORITY_LOWEST;
   else if (prio <= 40)
@@ -203,26 +223,57 @@ wxThreadError wxThread::Create()
     win_prio = THREAD_PRIORITY_ABOVE_NORMAL;
   else if (prio <= 100)
     win_prio = THREAD_PRIORITY_HIGHEST;
     win_prio = THREAD_PRIORITY_ABOVE_NORMAL;
   else if (prio <= 100)
     win_prio = THREAD_PRIORITY_HIGHEST;
+  else
+  {
+    wxFAIL_MSG("invalid value of thread priority parameter");
+    win_prio = THREAD_PRIORITY_NORMAL;
+  }
 
   SetThreadPriority(p_internal->thread_id, win_prio);
 
   ResumeThread(p_internal->thread_id);
   p_internal->state = STATE_RUNNING;
  
 
   SetThreadPriority(p_internal->thread_id, win_prio);
 
   ResumeThread(p_internal->thread_id);
   p_internal->state = STATE_RUNNING;
  
-  return THREAD_NO_ERROR;
+  return wxTHREAD_NO_ERROR;
 }
 
 wxThreadError wxThread::Destroy()
 {
   if (p_internal->state != STATE_RUNNING)
 }
 
 wxThreadError wxThread::Destroy()
 {
   if (p_internal->state != STATE_RUNNING)
-    return THREAD_NOT_RUNNING;
+    return wxTHREAD_NOT_RUNNING;
 
   if (p_internal->defer == FALSE)
     TerminateThread(p_internal->thread_id, 0);
   else
     p_internal->state = STATE_CANCELED;
 
 
   if (p_internal->defer == FALSE)
     TerminateThread(p_internal->thread_id, 0);
   else
     p_internal->state = STATE_CANCELED;
 
-  return THREAD_NO_ERROR;
+  return wxTHREAD_NO_ERROR;
+}
+
+wxThreadError wxThread::Pause()
+{
+    DWORD nSuspendCount = ::SuspendThread(p_internal->thread_id);
+    if ( nSuspendCount == (DWORD)-1 )
+    {
+        wxLogSysError(_("Can not suspend thread %x"), p_internal->thread_id);
+
+        return wxTHREAD_MISC_ERROR;   // no idea what might provoke this error...
+    }
+
+    return wxTHREAD_NO_ERROR;
+}
+
+wxThreadError wxThread::Resume()
+{
+    DWORD nSuspendCount = ::ResumeThread(p_internal->thread_id);
+    if ( nSuspendCount == (DWORD)-1 )
+    {
+        wxLogSysError(_("Can not resume thread %x"), p_internal->thread_id);
+
+        return wxTHREAD_MISC_ERROR;   // no idea what might provoke this error...
+    }
+
+    return wxTHREAD_NO_ERROR;
 }
 
 void wxThread::Exit(void *status)
 }
 
 void wxThread::Exit(void *status)
@@ -335,3 +386,12 @@ public:
 
 IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
 
 
 IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
 
+void WXDLLEXPORT wxMutexGuiEnter()
+{
+  wxFAIL_MSG("not implemented");
+}
+
+void WXDLLEXPORT wxMutexGuiLeave()
+{
+  wxFAIL_MSG("not implemented");
+}