From 338e73aef8dcd3e7e43e4337071ea9d77568c18b Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 7 Jul 2016 15:35:13 +0200 Subject: [PATCH] Replace Windows specific thread handling Use the platform independent primitives instead. --- common/rfb/Configuration.cxx | 19 ++-- common/rfb/Configuration.h | 4 + common/rfb/KeyRemapper.cxx | 27 ++++-- common/rfb/KeyRemapper.h | 6 +- common/rfb/Logger_file.cxx | 18 ++-- common/rfb/Logger_file.h | 3 + common/rfb/Logger_syslog.cxx | 1 - common/rfb/Threading.h | 31 ------ win/rfb_win32/CMakeLists.txt | 1 - win/rfb_win32/Clipboard.h | 1 - win/rfb_win32/RegConfig.cxx | 15 ++- win/rfb_win32/RegConfig.h | 9 +- win/rfb_win32/Service.cxx | 2 +- win/rfb_win32/Threading.cxx | 151 ----------------------------- win/rfb_win32/Threading.h | 155 ------------------------------ win/rfb_win32/WMHooks.cxx | 56 ++++++----- win/rfb_win32/WMNotifier.h | 1 - win/winvnc/QueryConnectDialog.cxx | 4 +- win/winvnc/QueryConnectDialog.h | 8 +- win/winvnc/STrayIcon.cxx | 22 ++++- win/winvnc/STrayIcon.h | 20 ++-- win/winvnc/VNCServerWin32.cxx | 57 +++++++---- win/winvnc/VNCServerWin32.h | 14 ++- 23 files changed, 171 insertions(+), 454 deletions(-) delete mode 100644 common/rfb/Threading.h delete mode 100644 win/rfb_win32/Threading.cxx delete mode 100644 win/rfb_win32/Threading.h diff --git a/common/rfb/Configuration.cxx b/common/rfb/Configuration.cxx index 8e1ea6e9..a5c23028 100644 --- a/common/rfb/Configuration.cxx +++ b/common/rfb/Configuration.cxx @@ -23,24 +23,14 @@ #include #include +#include + #include #include #include #include -#include -#ifdef __RFB_THREADING_IMPL -// On platforms that support Threading, we use Locks to make getData safe -#define LOCK_CONFIG Lock l(*configLock()) -rfb::Mutex* configLock_ = 0; -static rfb::Mutex* configLock() { - if (!configLock_) - configLock_ = new rfb::Mutex; - return configLock_; -} -#else -#define LOCK_CONFIG -#endif +#define LOCK_CONFIG os::AutoMutex a(mutex) #include #include @@ -195,9 +185,12 @@ VoidParameter::VoidParameter(const char* name_, const char* desc_, _next = conf->head; conf->head = this; + + mutex = new os::Mutex(); } VoidParameter::~VoidParameter() { + delete mutex; } const char* diff --git a/common/rfb/Configuration.h b/common/rfb/Configuration.h index da93fddf..fbf161db 100644 --- a/common/rfb/Configuration.h +++ b/common/rfb/Configuration.h @@ -45,6 +45,8 @@ #include +namespace os { class Mutex; } + namespace rfb { class VoidParameter; struct ParameterIterator; @@ -174,6 +176,8 @@ namespace rfb { bool immutable; const char* name; const char* description; + + os::Mutex* mutex; }; class AliasParameter : public VoidParameter { diff --git a/common/rfb/KeyRemapper.cxx b/common/rfb/KeyRemapper.cxx index d33f0a45..b4c2793c 100644 --- a/common/rfb/KeyRemapper.cxx +++ b/common/rfb/KeyRemapper.cxx @@ -17,6 +17,9 @@ */ #include + +#include + #include #include #include @@ -27,14 +30,21 @@ static LogWriter vlog("KeyRemapper"); KeyRemapper KeyRemapper::defInstance; -#ifdef __RFB_THREADING_IMPL -static Mutex mappingLock; -#endif +KeyRemapper::KeyRemapper(const char* m) +{ + mutex = new os::Mutex; + + setMapping(m); +} + +KeyRemapper::~KeyRemapper() +{ + delete mutex; +} void KeyRemapper::setMapping(const char* m) { -#ifdef __RFB_THREADING_IMPL - Lock l(mappingLock); -#endif + os::AutoMutex a(mutex); + mapping.clear(); while (m[0]) { int from, to; @@ -59,9 +69,8 @@ void KeyRemapper::setMapping(const char* m) { } rdr::U32 KeyRemapper::remapKey(rdr::U32 key) const { -#ifdef __RFB_THREADING_IMPL - Lock l(mappingLock); -#endif + os::AutoMutex a(mutex); + std::map::const_iterator i = mapping.find(key); if (i != mapping.end()) return i->second; diff --git a/common/rfb/KeyRemapper.h b/common/rfb/KeyRemapper.h index a4b7aa01..1406bad2 100644 --- a/common/rfb/KeyRemapper.h +++ b/common/rfb/KeyRemapper.h @@ -22,16 +22,20 @@ #include #include +namespace os { class Mutex; } + namespace rfb { class KeyRemapper { public: - KeyRemapper(const char* m="") { setMapping(m); } + KeyRemapper(const char* m=""); + ~KeyRemapper(); void setMapping(const char* m); rdr::U32 remapKey(rdr::U32 key) const; static KeyRemapper defInstance; private: std::map mapping; + os::Mutex* mutex; }; }; diff --git a/common/rfb/Logger_file.cxx b/common/rfb/Logger_file.cxx index ebe15d52..149ad404 100644 --- a/common/rfb/Logger_file.cxx +++ b/common/rfb/Logger_file.cxx @@ -21,36 +21,30 @@ #include #include +#include + #include #include -#include using namespace rfb; - -// If threading is available then protect the write() operation -// from concurrent accesses -#ifdef __RFB_THREADING_IMPL -static Mutex logLock; -#endif - - Logger_File::Logger_File(const char* loggerName) : Logger(loggerName), indent(13), width(79), m_filename(0), m_file(0), m_lastLogTime(0) { + mutex = new os::Mutex(); } Logger_File::~Logger_File() { closeFile(); + delete mutex; } void Logger_File::write(int level, const char *logname, const char *message) { -#ifdef __RFB_THREADING_IMPL - Lock l(logLock); -#endif + os::AutoMutex a(mutex); + if (!m_file) { if (!m_filename) return; CharArray bakFilename(strlen(m_filename) + 1 + 4); diff --git a/common/rfb/Logger_file.h b/common/rfb/Logger_file.h index 5e0c917b..5b5c34e1 100644 --- a/common/rfb/Logger_file.h +++ b/common/rfb/Logger_file.h @@ -24,6 +24,8 @@ #include #include +namespace os { class Mutex; } + namespace rfb { class Logger_File : public Logger { @@ -43,6 +45,7 @@ namespace rfb { char* m_filename; FILE* m_file; time_t m_lastLogTime; + os::Mutex* mutex; }; bool initFileLogger(const char* filename); diff --git a/common/rfb/Logger_syslog.cxx b/common/rfb/Logger_syslog.cxx index 291d36cd..dc1d0c1a 100644 --- a/common/rfb/Logger_syslog.cxx +++ b/common/rfb/Logger_syslog.cxx @@ -25,7 +25,6 @@ #include #include #include -#include using namespace rfb; diff --git a/common/rfb/Threading.h b/common/rfb/Threading.h deleted file mode 100644 index 66b3aa0f..00000000 --- a/common/rfb/Threading.h +++ /dev/null @@ -1,31 +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.h -// General purpose threading interface. -// If the current platform supports threading then __RFB_THREADING_IMPL -// will be defined after this header has been included. - -#ifndef __RFB_THREADING_H__ -#define __RFB_THREADING_H__ - -#ifdef WIN32 -#include -#endif - -#endif // __RFB_THREADING_H__ diff --git a/win/rfb_win32/CMakeLists.txt b/win/rfb_win32/CMakeLists.txt index 047b0d86..305247a8 100644 --- a/win/rfb_win32/CMakeLists.txt +++ b/win/rfb_win32/CMakeLists.txt @@ -22,7 +22,6 @@ set(RFB_WIN32_SOURCES 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 498f75fe..3da7bfca 100644 --- a/win/rfb_win32/Clipboard.h +++ b/win/rfb_win32/Clipboard.h @@ -25,7 +25,6 @@ #define __RFB_WIN32_CLIPBOARD_H__ #include -#include #include #include diff --git a/win/rfb_win32/RegConfig.cxx b/win/rfb_win32/RegConfig.cxx index 30cb3102..5c89e780 100644 --- a/win/rfb_win32/RegConfig.cxx +++ b/win/rfb_win32/RegConfig.cxx @@ -85,30 +85,29 @@ void RegConfig::processEvent(HANDLE event_) { } -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 e9c01b1d..c092090d 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 +#include + #include #include #include @@ -63,7 +64,7 @@ namespace rfb { RegKey key; }; - class RegConfigThread : Thread { + class RegConfigThread : os::Thread { public: RegConfigThread(); ~RegConfigThread(); @@ -71,10 +72,10 @@ namespace rfb { // 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 d054ce4d..719c44b6 100644 --- a/win/rfb_win32/Service.cxx +++ b/win/rfb_win32/Service.cxx @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/win/rfb_win32/Threading.cxx b/win/rfb_win32/Threading.cxx deleted file mode 100644 index 5873b58f..00000000 --- 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 - -#include -#include -#include -#include - -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 70bef416..00000000 --- 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 -#include -#include -//#include - - -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 0e5e70a4..bbc15088 100644 --- a/win/rfb_win32/WMHooks.cxx +++ b/win/rfb_win32/WMHooks.cxx @@ -18,11 +18,13 @@ // -=- WMHooks.cxx +#include +#include + #include #include #include #include -#include #include #include @@ -108,20 +110,21 @@ error: } -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 hooks; -static Mutex hook_mgr_lock; +static os::Mutex hook_mgr_lock; static bool StartHookThread() { @@ -131,15 +134,17 @@ static bool StartHookThread() { 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 @@ static void StopHookThread() { 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 AddHook(WMHooks* hook) { 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 bool RemHook(WMHooks* hook) { } static void NotifyHooksRegion(const Region& r) { - Lock l(hook_mgr_lock); + os::AutoMutex a(&hook_mgr_lock); std::list::iterator i; for (i=hooks.begin(); i!=hooks.end(); i++) (*i)->NotifyHooksRegion(r); @@ -182,7 +188,7 @@ static void NotifyHooksRegion(const Region& r) { 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 @@ WMHooksThread::run() { vlog.debug("starting hook thread"); + thread_id = GetCurrentThreadId(); + while (active && GetMessage(&msg, NULL, 0, 0)) { count++; @@ -283,13 +291,13 @@ WMHooksThread::run() { 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::setEvent(HANDLE ue) { 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 @@ static bool blockRealInputs(bool block_) { 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 ada45d09..3855430b 100644 --- a/win/rfb_win32/WMNotifier.h +++ b/win/rfb_win32/WMNotifier.h @@ -28,7 +28,6 @@ #define __RFB_WIN32_NOTIFIER_H__ #include -#include #include #include #include diff --git a/win/winvnc/QueryConnectDialog.cxx b/win/winvnc/QueryConnectDialog.cxx index 8e506966..103621ee 100644 --- a/win/winvnc/QueryConnectDialog.cxx +++ b/win/winvnc/QueryConnectDialog.cxx @@ -41,7 +41,7 @@ static IntParameter timeout("QueryConnectTimeout", QueryConnectDialog::QueryConnectDialog(network::Socket* sock_, const char* userName_, VNCServerWin32* s) -: Thread("QueryConnectDialog"), Dialog(GetModuleHandle(0)), +: Dialog(GetModuleHandle(0)), sock(sock_), approve(false), server(s) { peerIp.buf = sock->getPeerAddress(); userName.buf = strDup(userName_); @@ -54,7 +54,7 @@ void QueryConnectDialog::startDialog() { // - Thread overrides -void QueryConnectDialog::run() { +void QueryConnectDialog::worker() { countdown = timeout; try { if (desktopChangeRequired() && !changeDesktop()) diff --git a/win/winvnc/QueryConnectDialog.h b/win/winvnc/QueryConnectDialog.h index b28de198..de5e31ee 100644 --- a/win/winvnc/QueryConnectDialog.h +++ b/win/winvnc/QueryConnectDialog.h @@ -21,24 +21,26 @@ #ifndef __WINVNC_QUERY_CONNECT_DIALOG_H__ #define __WINVNC_QUERY_CONNECT_DIALOG_H__ -#include #include #include +namespace os { class Thread; } + namespace network { class Socket; } namespace winvnc { class VNCServerWin32; - class QueryConnectDialog : public rfb::Thread, rfb::win32::Dialog { + class QueryConnectDialog : public os::Thread, rfb::win32::Dialog { public: QueryConnectDialog(network::Socket* sock, const char* userName, VNCServerWin32* s); virtual void startDialog(); - virtual void run(); network::Socket* getSock() {return sock;} bool isAccepted() const {return approve;} protected: + // Thread methods + virtual void worker(); // Dialog methods (protected) virtual void initDialog(); diff --git a/win/winvnc/STrayIcon.cxx b/win/winvnc/STrayIcon.cxx index 762a56af..05a38d6e 100644 --- a/win/winvnc/STrayIcon.cxx +++ b/win/winvnc/STrayIcon.cxx @@ -22,14 +22,19 @@ #include #include +#include +#include + #include #include + #include #include #include #include #include #include + #include using namespace rfb; @@ -209,7 +214,7 @@ public: case WM_SET_TOOLTIP: { - rfb::Lock l(thread.lock); + os::AutoMutex a(thread.lock); if (thread.toolTip.buf) setToolTip(thread.toolTip.buf); } @@ -231,15 +236,24 @@ protected: STrayIconThread::STrayIconThread(VNCServerWin32& sm, UINT inactiveIcon_, UINT activeIcon_, UINT dis_inactiveIcon_, UINT dis_activeIcon_, UINT menu_) -: Thread("TrayIcon"), windowHandle(0), server(sm), +: thread_id(-1), windowHandle(0), server(sm), inactiveIcon(inactiveIcon_), activeIcon(activeIcon_), dis_inactiveIcon(dis_inactiveIcon_), dis_activeIcon(dis_activeIcon_), menu(menu_), runTrayIcon(true) { + lock = new os::Mutex; start(); + while (thread_id == (DWORD)-1) + Sleep(0); } +STrayIconThread::~STrayIconThread() { + runTrayIcon = false; + PostThreadMessage(thread_id, WM_QUIT, 0, 0); + delete lock; +} -void STrayIconThread::run() { +void STrayIconThread::worker() { + thread_id = GetCurrentThreadId(); while (runTrayIcon) { if (rfb::win32::desktopChangeRequired() && !rfb::win32::changeDesktop()) @@ -260,7 +274,7 @@ void STrayIconThread::run() { void STrayIconThread::setToolTip(const TCHAR* text) { if (!windowHandle) return; - Lock l(lock); + os::AutoMutex a(lock); delete [] toolTip.buf; toolTip.buf = tstrDup(text); PostMessage(windowHandle, WM_SET_TOOLTIP, 0, 0); diff --git a/win/winvnc/STrayIcon.h b/win/winvnc/STrayIcon.h index 309d3f4a..09066362 100644 --- a/win/winvnc/STrayIcon.h +++ b/win/winvnc/STrayIcon.h @@ -22,20 +22,19 @@ #include #include #include -#include + +namespace os { + class Mutex; + class Thread; +} namespace winvnc { - class STrayIconThread : rfb::Thread { + class STrayIconThread : os::Thread { public: STrayIconThread(VNCServerWin32& sm, UINT inactiveIcon, UINT activeIcon, UINT dis_inactiveIcon, UINT dis_activeIcon, UINT menu); - virtual ~STrayIconThread() { - runTrayIcon = false; - PostThreadMessage(getThreadId(), WM_QUIT, 0, 0); - } - - virtual void run(); + virtual ~STrayIconThread(); void setToolTip(const TCHAR* text); @@ -44,7 +43,10 @@ namespace winvnc { friend class STrayIcon; protected: - rfb::Mutex lock; + virtual void worker(); + + os::Mutex* lock; + DWORD thread_id; HWND windowHandle; rfb::TCharArray toolTip; VNCServerWin32& server; diff --git a/win/winvnc/VNCServerWin32.cxx b/win/winvnc/VNCServerWin32.cxx index 27aea9f6..d86384da 100644 --- a/win/winvnc/VNCServerWin32.cxx +++ b/win/winvnc/VNCServerWin32.cxx @@ -21,9 +21,13 @@ #include #include #include + +#include + #include #include #include + #include #include @@ -53,16 +57,21 @@ static BoolParameter showTrayIcon("ShowTrayIcon", VNCServerWin32::VNCServerWin32() - : command(NoCommand), commandSig(commandLock), + : command(NoCommand), commandEvent(CreateEvent(0, TRUE, FALSE, 0)), sessionEvent(isServiceProcess() ? CreateEvent(0, FALSE, FALSE, "Global\\SessionEventTigerVNC") : 0), vncServer(CStr(ComputerName().buf), &desktop), - hostThread(0), runServer(false), isDesktopStarted(false), + thread_id(-1), runServer(false), isDesktopStarted(false), httpServer(&vncServer), config(&sockMgr), rfbSock(&sockMgr), httpSock(&sockMgr), trayIcon(0), queryConnectDialog(0) { + commandLock = new os::Mutex; + commandSig = new os::Condition(commandLock); + + runLock = new os::Mutex; + // Initialise the desktop desktop.setStatusLocation(&isDesktopStarted); @@ -85,8 +94,15 @@ VNCServerWin32::~VNCServerWin32() { desktop.setStatusLocation(0); // Join the Accept/Reject dialog thread - if (queryConnectDialog) - delete queryConnectDialog->join(); + if (queryConnectDialog) { + queryConnectDialog->wait(); + delete queryConnectDialog; + } + + delete runLock; + + delete commandSig; + delete commandLock; } @@ -149,8 +165,9 @@ void VNCServerWin32::regConfigChanged() { int VNCServerWin32::run() { - { Lock l(runLock); - hostThread = Thread::self(); + { + os::AutoMutex a(runLock); + thread_id = GetCurrentThreadId(); runServer = true; } @@ -195,19 +212,20 @@ int VNCServerWin32::run() { vlog.error("%s", e.str()); } - { Lock l(runLock); + { + os::AutoMutex a(runLock); runServer = false; - hostThread = 0; + thread_id = (DWORD)-1; } return result; } void VNCServerWin32::stop() { - Lock l(runLock); + os::AutoMutex a(runLock); runServer = false; - if (hostThread) - PostThreadMessage(hostThread->getThreadId(), WM_QUIT, 0, 0); + if (thread_id != (DWORD)-1) + PostThreadMessage(thread_id, WM_QUIT, 0, 0); } @@ -261,17 +279,17 @@ void VNCServerWin32::queryConnectionComplete() { bool VNCServerWin32::queueCommand(Command cmd, const void* data, int len, bool wait) { - Lock l(commandLock); + os::AutoMutex a(commandLock); while (command != NoCommand) - commandSig.wait(); + commandSig->wait(); command = cmd; commandData = data; commandDataLen = len; SetEvent(commandEvent); if (wait) { while (command != NoCommand) - commandSig.wait(); - commandSig.signal(); + commandSig->wait(); + commandSig->signal(); } return true; } @@ -282,7 +300,7 @@ void VNCServerWin32::processEvent(HANDLE event_) { if (event_ == commandEvent.h) { // If there is no command queued then return immediately { - Lock l(commandLock); + os::AutoMutex a(commandLock); if (command == NoCommand) return; } @@ -312,7 +330,8 @@ void VNCServerWin32::processEvent(HANDLE event_) { vncServer.approveConnection(queryConnectDialog->getSock(), queryConnectDialog->isAccepted(), "Connection rejected by user"); - delete queryConnectDialog->join(); + queryConnectDialog->wait(); + delete queryConnectDialog; queryConnectDialog = 0; break; @@ -322,9 +341,9 @@ void VNCServerWin32::processEvent(HANDLE event_) { // Clear the command and signal completion { - Lock l(commandLock); + os::AutoMutex a(commandLock); command = NoCommand; - commandSig.signal(); + commandSig->signal(); } } else if (event_ == sessionEvent.h) { stop(); diff --git a/win/winvnc/VNCServerWin32.h b/win/winvnc/VNCServerWin32.h index b85814a4..225e6342 100644 --- a/win/winvnc/VNCServerWin32.h +++ b/win/winvnc/VNCServerWin32.h @@ -30,6 +30,12 @@ #include #include +namespace os { + class Mutex; + class Condition; + class Thread; +} + namespace winvnc { class STrayIconThread; @@ -99,16 +105,16 @@ namespace winvnc { Command command; const void* commandData; int commandDataLen; - rfb::Mutex commandLock; - rfb::Condition commandSig; + os::Mutex* commandLock; + os::Condition* commandSig; rfb::win32::Handle commandEvent; rfb::win32::Handle sessionEvent; // VNCServerWin32 Server-internal state rfb::win32::SDisplay desktop; rfb::VNCServerST vncServer; - rfb::Mutex runLock; - rfb::Thread* hostThread; + os::Mutex* runLock; + DWORD thread_id; bool runServer; bool isDesktopStarted; JavaViewerServer httpServer; -- 2.39.5