Replace Windows specific thread handling

Use the platform independent primitives instead.
diff --git a/win/rfb_win32/CMakeLists.txt b/win/rfb_win32/CMakeLists.txt
index 047b0d8..305247a 100644
--- a/win/rfb_win32/CMakeLists.txt
+++ b/win/rfb_win32/CMakeLists.txt
@@ -22,7 +22,6 @@
   SInput.cxx
   SocketManager.cxx
   TCharArray.cxx
-  Threading.cxx
   TsSessions.cxx
   Win32Util.cxx
   WMCursor.cxx
diff --git a/win/rfb_win32/Clipboard.h b/win/rfb_win32/Clipboard.h
index 498f75f..3da7bfc 100644
--- a/win/rfb_win32/Clipboard.h
+++ b/win/rfb_win32/Clipboard.h
@@ -25,7 +25,6 @@
 #define __RFB_WIN32_CLIPBOARD_H__
 
 #include <rfb/SDesktop.h>
-#include <rfb/Threading.h>
 #include <rfb_win32/MsgWindow.h>
 #include <rfb_win32/DeviceFrameBuffer.h>
 
diff --git a/win/rfb_win32/RegConfig.cxx b/win/rfb_win32/RegConfig.cxx
index 30cb310..5c89e78 100644
--- a/win/rfb_win32/RegConfig.cxx
+++ b/win/rfb_win32/RegConfig.cxx
@@ -85,30 +85,29 @@
 }
 
 
-RegConfigThread::RegConfigThread() : Thread("RegConfigThread"), config(&eventMgr) {
+RegConfigThread::RegConfigThread() : config(&eventMgr), thread_id(-1) {
 }
 
 RegConfigThread::~RegConfigThread() {
-  join();
+  PostThreadMessage(thread_id, WM_QUIT, 0, 0);
+  wait();
 }
 
 bool RegConfigThread::start(const HKEY rootKey, const TCHAR* keyname) {
   if (config.setKey(rootKey, keyname)) {
     Thread::start();
+    while (thread_id == (DWORD)-1)
+      Sleep(0);
     return true;
   }
   return false;
 }
 
-void RegConfigThread::run() {
+void RegConfigThread::worker() {
   DWORD result = 0;
   MSG msg;
+  thread_id = GetCurrentThreadId();
   while ((result = eventMgr.getMessage(&msg, 0, 0, 0)) > 0) {}
   if (result < 0)
     throw rdr::SystemException("RegConfigThread failed", GetLastError());
 }
-
-Thread* RegConfigThread::join() {
-  PostThreadMessage(getThreadId(), WM_QUIT, 0, 0);
-  return Thread::join();
-}
diff --git a/win/rfb_win32/RegConfig.h b/win/rfb_win32/RegConfig.h
index e9c01b1..c092090 100644
--- a/win/rfb_win32/RegConfig.h
+++ b/win/rfb_win32/RegConfig.h
@@ -24,7 +24,8 @@
 #ifndef __RFB_WIN32_REG_CONFIG_H__
 #define __RFB_WIN32_REG_CONFIG_H__
 
-#include <rfb/Threading.h>
+#include <os/Thread.h>
+
 #include <rfb/Configuration.h>
 #include <rfb_win32/Registry.h>
 #include <rfb_win32/EventManager.h>
@@ -63,7 +64,7 @@
       RegKey key;
     };
 
-    class RegConfigThread : Thread {
+    class RegConfigThread : os::Thread {
     public:
       RegConfigThread();
       ~RegConfigThread();
@@ -71,10 +72,10 @@
       // Start the thread, reading from the specified key
       bool start(const HKEY rootkey, const TCHAR* keyname);
     protected:
-      void run();
-      Thread* join();
+      virtual void worker();
       EventManager eventMgr;
       RegConfig config;
+      DWORD thread_id;
     };
 
   };
diff --git a/win/rfb_win32/Service.cxx b/win/rfb_win32/Service.cxx
index d054ce4..719c44b 100644
--- a/win/rfb_win32/Service.cxx
+++ b/win/rfb_win32/Service.cxx
@@ -22,7 +22,7 @@
 #include <rfb_win32/MsgWindow.h>
 #include <rfb_win32/ModuleFileName.h>
 #include <rfb_win32/Registry.h>
-#include <rfb/Threading.h>
+#include <rfb_win32/Handle.h>
 #include <logmessages/messages.h>
 #include <rdr/Exception.h>
 #include <rfb/LogWriter.h>
diff --git a/win/rfb_win32/Threading.cxx b/win/rfb_win32/Threading.cxx
deleted file mode 100644
index 5873b58..0000000
--- a/win/rfb_win32/Threading.cxx
+++ /dev/null
@@ -1,151 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-// -=- Threading.cxx
-// Win32 Threading interface implementation
-
-#include <malloc.h>
-
-#include <rdr/Exception.h>
-#include <rfb/LogWriter.h>
-#include <rfb/util.h>
-#include <rfb_win32/Threading.h>
-
-using namespace rfb;
-
-static LogWriter vlog("Threading");
-
-static DWORD threadStorage = TlsAlloc();
-
-
-inline void logAction(Thread* t, const char* action) {
-  vlog.debug("%-16.16s %s(%p)", action, t->getName(), t);
-}
-
-inline void logError(Thread* t, const char* err) {
-  vlog.error("%-16.16s %s(%p):%s", "failed", t->getName(), t, err);
-}
-
-
-DWORD WINAPI
-Thread::threadProc(LPVOID lpParameter) {
-  Thread* thread = (Thread*) lpParameter;
-  TlsSetValue(threadStorage, thread);
-  logAction(thread, "started");
-  try {
-    thread->run();
-    logAction(thread, "stopped");
-  } catch (rdr::Exception& e) {
-    logError(thread, e.str());
-  }
-  bool deleteThread = false;
-  {
-    Lock l(thread->mutex);
-    thread->state = ThreadStopped;
-    thread->sig->signal();
-    deleteThread = thread->deleteAfterRun;
-  }
-  if (deleteThread)
-    delete thread;
-  return 0;
-}
-
-Thread::Thread(const char* name_) : name(strDup(name_ ? name_ : "Unnamed")), sig(0), deleteAfterRun(false) {
-  sig = new Condition(mutex);
-  cond_event.h = CreateEvent(NULL, TRUE, FALSE, NULL);
-  thread.h = CreateThread(NULL, 0, threadProc, this, CREATE_SUSPENDED, &thread_id);
-  state = ThreadCreated;
-  logAction(this, "created");
-}
-
-Thread::Thread(HANDLE thread_, DWORD thread_id_) : 
-  thread(thread_), thread_id(thread_id_), name(strDup("Native")), sig(0), deleteAfterRun(false) {
-  cond_event.h = CreateEvent(NULL, TRUE, FALSE, NULL);
-  state = ThreadNative;
-  logAction(this, "created");
-}
-
-Thread::~Thread() {
-  logAction(this, "destroying");
-  if (!deleteAfterRun && state != ThreadNative)
-    this->join();
-  if (sig)
-    delete sig;
-  logAction(this, "destroyed");
-}
-
-void
-Thread::run() {
-}
-
-void
-Thread::start() {
-  Lock l(mutex);
-  if (state == ThreadCreated) {
-    state = ThreadStarted;
-    sig->signal();
-    ResumeThread(thread);
-  }
-}
-
-Thread*
-Thread::join() {
-  if (deleteAfterRun)
-    throw rdr::Exception("attempt to join() with deleteAfterRun thread");
-  Lock l(mutex);
-  if (state == ThreadJoined) {
-    logAction(this, "already joined");
-  } else {
-    logAction(this, "joining");
-    while (state == ThreadStarted) {
-      sig->wait();
-      logAction(this, "checking");
-    }
-    state = ThreadJoined;
-    logAction(this, "joined");
-  }
-  return this;
-}
-
-const char*
-Thread::getName() const {
-  return name.buf;
-}
-
-ThreadState
-Thread::getState() const {
-  return state;
-}
-
-unsigned long
-Thread::getThreadId() const {
-  return thread_id;
-}
-
-
-Thread*
-Thread::self() {
-  Thread* thread = (Thread*) TlsGetValue(threadStorage);
-  if (!thread) {
-    // *** memory leak - could use GetExitCodeThread to lazily detect when
-    //     to clean up native thread objects
-    thread = new Thread(GetCurrentThread(), GetCurrentThreadId());
-    TlsSetValue(threadStorage, thread);
-  }
-  return thread;
-}
diff --git a/win/rfb_win32/Threading.h b/win/rfb_win32/Threading.h
deleted file mode 100644
index 70bef41..0000000
--- a/win/rfb_win32/Threading.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- * USA.
- */
-
-// -=- Threading_win32.h
-// Win32 Threading interface implementation
-
-#ifndef __RFB_THREADING_IMPL_WIN32
-#define __RFB_THREADING_IMPL_WIN32
-
-#define __RFB_THREADING_IMPL WIN32
-
-#include <rfb_win32/Handle.h>
-#include <rfb/util.h>
-#include <rdr/Exception.h>
-//#include <stdio.h>
-
-
-namespace rfb {
-  class Condition;
-
-  class Mutex {
-  public:
-    Mutex() {
-      InitializeCriticalSection(&crit);
-    }
-    ~Mutex() {
-      DeleteCriticalSection(&crit);
-    }
-    friend class Lock;
-    friend class Condition;
-  protected:
-    void enter() {EnterCriticalSection(&crit);}
-    void exit() {LeaveCriticalSection(&crit);}
-    CRITICAL_SECTION crit;
-  };
-
-  class Lock {
-  public:
-    Lock(Mutex& m) : mutex(m) {m.enter();}
-    ~Lock() {mutex.exit();}
-  protected:
-    Mutex& mutex;
-  };
-
-  enum ThreadState {ThreadCreated, ThreadStarted, ThreadStopped, ThreadJoined, ThreadNative};
-
-  class Thread {
-  public:
-    Thread(const char* name_=0);
-    virtual ~Thread();
-
-    virtual void run();
-
-    virtual void start();
-    virtual Thread* join();
-
-    const char* getName() const;
-    ThreadState getState() const;
-
-    // Determines whether the thread should delete itself when run() returns
-    // If you set this, you must NEVER call join()!
-    void setDeleteAfterRun() {deleteAfterRun = true;};
-
-    unsigned long getThreadId() const;
-
-    static Thread* self();
-
-    friend class Condition;
-
-  protected:
-    Thread(HANDLE thread_, DWORD thread_id_);
-    static DWORD WINAPI threadProc(LPVOID lpParameter);
-
-    win32::Handle thread;
-    DWORD thread_id;
-    CharArray name;
-    ThreadState state;
-    Condition* sig;
-    Mutex mutex;
-
-    win32::Handle cond_event;
-	  Thread* cond_next;
-
-    bool deleteAfterRun;
-  };
-
-  class Condition {
-  public:
-    Condition(Mutex& m) : mutex(m), waiting(0) {
-    }
-    ~Condition() {
-    }
-
-    // Wake up the specified number of threads that are waiting
-    // on this Condition, or all of them if -1 is specified.
-    void signal(int howMany=1) {
-      Lock l(cond_lock);
-      while (waiting && howMany!=0) {
-        SetEvent(waiting->cond_event);
-        waiting = waiting->cond_next;
-        if (howMany>0) --howMany;
-      }
-    }
-
-    // NB: Must hold "mutex" to call wait()
-    // Wait until either the Condition is signalled or the timeout
-    // expires.
-    void wait(DWORD timeout=INFINITE) {
-      Thread* self = Thread::self();
-      ResetEvent(self->cond_event);
-      { Lock l(cond_lock);
-        self->cond_next = waiting;
-        waiting = self;
-      }
-      mutex.exit();
-      DWORD result = WaitForSingleObject(self->cond_event, timeout);
-      mutex.enter();
-      if (result == WAIT_TIMEOUT) {
-        Lock l(cond_lock);
-        // Remove this thread from the Condition
-        for (Thread** removeFrom = &waiting; *removeFrom; removeFrom = &(*removeFrom)->cond_next) {
-          if (*removeFrom == self) {
-            *removeFrom = self->cond_next;
-            break;
-          }
-        }
-      } else if (result == WAIT_FAILED) {
-        throw rdr::SystemException("failed to wait on Condition", GetLastError());
-      }
-    }
-    
-  protected:
-    Mutex& mutex;
-    Mutex cond_lock;
-	  Thread* waiting;
-  };
-
-};
-
-#endif // __RFB_THREADING_IMPL
diff --git a/win/rfb_win32/WMHooks.cxx b/win/rfb_win32/WMHooks.cxx
index 0e5e70a..bbc1508 100644
--- a/win/rfb_win32/WMHooks.cxx
+++ b/win/rfb_win32/WMHooks.cxx
@@ -18,11 +18,13 @@
 
 // -=- WMHooks.cxx
 
+#include <os/Mutex.h>
+#include <os/Thread.h>
+
 #include <rfb_win32/WMHooks.h>
 #include <rfb_win32/Service.h>
 #include <rfb_win32/MsgWindow.h>
 #include <rfb_win32/IntervalTimer.h>
-#include <rfb/Threading.h>
 #include <rfb/LogWriter.h>
 
 #include <list>
@@ -108,20 +110,21 @@
 }
 
 
-class WMHooksThread : public Thread {
+class WMHooksThread : public os::Thread {
 public:
-  WMHooksThread() : Thread("WMHookThread"), 
-    active(true) {
-  }
-  virtual void run();
-  virtual Thread* join();
+  WMHooksThread() : active(true), thread_id(-1) { }
+  void stop();
+  DWORD getThreadId() { return thread_id; }
+protected:
+  virtual void worker();
 protected:
   bool active;
+  DWORD thread_id;
 };
 
 static WMHooksThread* hook_mgr = 0;
 static std::list<WMHooks*> hooks;
-static Mutex hook_mgr_lock;
+static os::Mutex hook_mgr_lock;
 
 
 static bool StartHookThread() {
@@ -131,15 +134,17 @@
     return false;
   vlog.debug("creating thread");
   hook_mgr = new WMHooksThread();
+  hook_mgr->start();
+  while (hook_mgr->getThreadId() == (DWORD)-1)
+    Sleep(0);
   vlog.debug("installing hooks");
   if (!WM_Hooks_Install(hook_mgr->getThreadId(), 0)) {
     vlog.error("failed to initialise hooks");
-    delete hook_mgr->join();
+    hook_mgr->stop();
+    delete hook_mgr;
     hook_mgr = 0;
     return false;
   }
-  vlog.debug("starting thread");
-  hook_mgr->start();
   return true;
 }
 
@@ -149,14 +154,15 @@
   if (!hooks.empty())
     return;
   vlog.debug("closing thread");
-  delete hook_mgr->join();
+  hook_mgr->stop();
+  delete hook_mgr;
   hook_mgr = 0;
 }
 
 
 static bool AddHook(WMHooks* hook) {
   vlog.debug("adding hook");
-  Lock l(hook_mgr_lock);
+  os::AutoMutex a(&hook_mgr_lock);
   if (!StartHookThread())
     return false;
   hooks.push_back(hook);
@@ -166,7 +172,7 @@
 static bool RemHook(WMHooks* hook) {
   {
     vlog.debug("removing hook");
-    Lock l(hook_mgr_lock);
+    os::AutoMutex a(&hook_mgr_lock);
     hooks.remove(hook);
   }
   StopHookThread();
@@ -174,7 +180,7 @@
 }
 
 static void NotifyHooksRegion(const Region& r) {
-  Lock l(hook_mgr_lock);
+  os::AutoMutex a(&hook_mgr_lock);
   std::list<WMHooks*>::iterator i;
   for (i=hooks.begin(); i!=hooks.end(); i++)
     (*i)->NotifyHooksRegion(r);
@@ -182,7 +188,7 @@
 
 
 void
-WMHooksThread::run() {
+WMHooksThread::worker() {
   // Obtain message ids for all supported hook messages
   UINT windowMsg = WM_Hooks_WindowChanged();
   UINT clientAreaMsg = WM_Hooks_WindowClientAreaChanged();
@@ -208,6 +214,8 @@
 
   vlog.debug("starting hook thread");
 
+  thread_id = GetCurrentThreadId();
+
   while (active && GetMessage(&msg, NULL, 0, 0)) {
     count++;
 
@@ -283,13 +291,13 @@
   WM_Hooks_Remove(getThreadId());
 }
 
-Thread*
-WMHooksThread::join() {
+void
+WMHooksThread::stop() {
   vlog.debug("stopping WMHooks thread");
   active = false;
   PostThreadMessage(thread_id, WM_QUIT, 0, 0);
-  vlog.debug("joining WMHooks thread");
-  return Thread::join();
+  vlog.debug("waiting for WMHooks thread");
+  wait();
 }
 
 // -=- WMHooks class
@@ -311,7 +319,7 @@
 
 bool rfb::win32::WMHooks::getUpdates(UpdateTracker* ut) {
   if (!updatesReady) return false;
-  Lock l(hook_mgr_lock);
+  os::AutoMutex a(&hook_mgr_lock);
   updates.copyTo(ut);
   updates.clear();
   updatesReady = false;
@@ -363,12 +371,12 @@
   return block_ == blocking;
 }
 
-Mutex blockMutex;
-int blockCount = 0;
+static os::Mutex blockMutex;
+static int blockCount = 0;
 
 bool rfb::win32::WMBlockInput::blockInputs(bool on) {
   if (active == on) return true;
-  Lock l(blockMutex);
+  os::AutoMutex a(&blockMutex);
   int newCount = on ? blockCount+1 : blockCount-1;
   if (!blockRealInputs(newCount > 0))
     return false;
diff --git a/win/rfb_win32/WMNotifier.h b/win/rfb_win32/WMNotifier.h
index ada45d0..3855430 100644
--- a/win/rfb_win32/WMNotifier.h
+++ b/win/rfb_win32/WMNotifier.h
@@ -28,7 +28,6 @@
 #define __RFB_WIN32_NOTIFIER_H__
 
 #include <rfb/SDesktop.h>
-#include <rfb/Threading.h>
 #include <rfb_win32/MsgWindow.h>
 #include <rfb_win32/DeviceFrameBuffer.h>
 #include <rfb_win32/SInput.h>