summaryrefslogtreecommitdiffstats
path: root/win/rfb_win32/Threading.cxx
diff options
context:
space:
mode:
authorConstantin Kaplinsky <const@tightvnc.com>2006-05-25 05:12:25 +0000
committerConstantin Kaplinsky <const@tightvnc.com>2006-05-25 05:12:25 +0000
commit729598cb00d791bbdfe23ebe0023d3a1c3962f83 (patch)
treeffe1b87705a0541998b8d7c44ea75dc4702dc515 /win/rfb_win32/Threading.cxx
parentb30ae7facbdf8273f34f5d67d3d2e9c81db75576 (diff)
downloadtigervnc-729598cb00d791bbdfe23ebe0023d3a1c3962f83.tar.gz
tigervnc-729598cb00d791bbdfe23ebe0023d3a1c3962f83.zip
Migrating to new directory structure adopted from the RealVNC's source tree. More changes will follow.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@591 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'win/rfb_win32/Threading.cxx')
-rw-r--r--win/rfb_win32/Threading.cxx151
1 files changed, 151 insertions, 0 deletions
diff --git a/win/rfb_win32/Threading.cxx b/win/rfb_win32/Threading.cxx
new file mode 100644
index 00000000..c41ac38b
--- /dev/null
+++ b/win/rfb_win32/Threading.cxx
@@ -0,0 +1,151 @@
+/* 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(%lx)", action, t->getName(), t);
+}
+
+inline void logError(Thread* t, const char* err) {
+ vlog.error("%-16.16s %s(%lx):%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_) : name(strDup("Native")), sig(0), deleteAfterRun(false),
+ thread(thread_), thread_id(thread_id_) {
+ 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;
+}