(svn r12529) [NoAI] -Change: split thread.cpp into 4 files, one for each OS noai
authortruebrain
Tue, 01 Apr 2008 13:40:36 +0000
branchnoai
changeset 9857 7adb6a846add
parent 9856 6a0dcee9f8e4
child 9858 b385c3ee0926
(svn r12529) [NoAI] -Change: split thread.cpp into 4 files, one for each OS
configure
projects/openttd_vs80.vcproj
projects/openttd_vs90.vcproj
source.list
src/thread.cpp
src/thread_none.cpp
src/thread_os2.cpp
src/thread_pthread.cpp
src/thread_win32.cpp
--- a/configure	Tue Apr 01 13:28:55 2008 +0000
+++ b/configure	Tue Apr 01 13:40:36 2008 +0000
@@ -96,7 +96,7 @@
 		if ($0 == "MSVC"        && "'$os'" != "MSVC")              { next; }
 		if ($0 == "DIRECTMUSIC" && "'$with_direct_music'" == "0")  { next; }
 		if ($0 == "LIBTIMIDITY" && "'$libtimidity'" == "" )        { next; }
-		if ($0 == "NO_THREADS"  && "'$with_threads'" == "0")       { next; }
+		if ($0 == "HAVE_THREAD" && "'$with_threads'" == "0")       { next; }
 
 		skip += 1;
 
--- a/projects/openttd_vs80.vcproj	Tue Apr 01 13:28:55 2008 +0000
+++ b/projects/openttd_vs80.vcproj	Tue Apr 01 13:40:36 2008 +0000
@@ -744,7 +744,7 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\thread.cpp"
+				RelativePath=".\..\src\thread_win32.cpp"
 				>
 			</File>
 			<File
--- a/projects/openttd_vs90.vcproj	Tue Apr 01 13:28:55 2008 +0000
+++ b/projects/openttd_vs90.vcproj	Tue Apr 01 13:40:36 2008 +0000
@@ -741,7 +741,7 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\thread.cpp"
+				RelativePath=".\..\src\thread_win32.cpp"
 				>
 			</File>
 			<File
--- a/source.list	Tue Apr 01 13:28:55 2008 +0000
+++ b/source.list	Tue Apr 01 13:40:36 2008 +0000
@@ -79,7 +79,19 @@
 squirrel_std.cpp
 texteff.cpp
 tgp.cpp
-thread.cpp
+#if HAVE_THREAD
+	#if WIN32
+	thread_win32.cpp
+	#else
+		#if OS2
+			thread_os2.cpp
+		#else
+			thread_pthread.cpp
+		#endif
+	#endif
+#else
+	thread_none.cpp
+#endif
 tile_map.cpp
 #if WIN32
 #else
@@ -458,7 +470,7 @@
 # AI Core
 ai/ai.cpp
 ai/ai.h
-#if NO_THREADS
+#if HAVE_THREAD
 ai/ai_factory.hpp
 ai/ai_gui.cpp
 ai/ai_gui.hpp
--- a/src/thread.cpp	Tue Apr 01 13:28:55 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,486 +0,0 @@
-/* $Id$ */
-
-/** @file thread.cpp */
-
-#include "stdafx.h"
-#include "thread.h"
-#include "debug.h"
-#include "core/alloc_func.hpp"
-#include <stdlib.h>
-
-#if defined(__AMIGA__) || defined(__MORPHOS__) || defined(PSP) || defined(NO_THREADS)
-OTTDThread *OTTDCreateThread(OTTDThreadFunc function, void *arg) { return NULL; }
-void *OTTDJoinThread(OTTDThread *t) { return NULL; }
-void OTTDExitThread() { NOT_REACHED(); };
-
-#elif defined(__OS2__)
-
-#define INCL_DOS
-#include <os2.h>
-#include <process.h>
-
-struct OTTDThread {
-	TID thread;
-	OTTDThreadFunc func;
-	void *arg;
-	void *ret;
-};
-
-static void Proxy(void *arg)
-{
-	OTTDThread *t = (OTTDThread *)arg;
-	t->ret = t->func(t->arg);
-}
-
-OTTDThread *OTTDCreateThread(OTTDThreadFunc function, void *arg)
-{
-	OTTDThread *t = MallocT<OTTDThread>(1);
-
-	if (t == NULL) return NULL;
-
-	t->func = function;
-	t->arg  = arg;
-	t->thread = _beginthread(Proxy, NULL, 32768, t);
-	if (t->thread != (TID)-1) {
-		return t;
-	} else {
-		free(t);
-		return NULL;
-	}
-}
-
-void *OTTDJoinThread(OTTDThread *t)
-{
-	void *ret;
-
-	if (t == NULL) return NULL;
-
-	DosWaitThread(&t->thread, DCWW_WAIT);
-	ret = t->ret;
-	free(t);
-	return ret;
-}
-
-void OTTDExitThread()
-{
-	_endthread();
-}
-
-#elif defined(UNIX)
-
-#include <pthread.h>
-#include <semaphore.h>
-#include <unistd.h>
-
-struct OTTDThread {
-	pthread_t thread;
-};
-
-OTTDThread *OTTDCreateThread(OTTDThreadFunc function, void *arg)
-{
-	OTTDThread *t = MallocT<OTTDThread>(1);
-
-	if (t == NULL) return NULL;
-
-	if (pthread_create(&t->thread, NULL, function, arg) == 0) {
-		return t;
-	} else {
-		free(t);
-		return NULL;
-	}
-}
-
-void *OTTDJoinThread(OTTDThread *t)
-{
-	void* ret;
-
-	if (t == NULL) return NULL;
-
-	pthread_join(t->thread, &ret);
-	free(t);
-	return ret;
-}
-
-void OTTDExitThread()
-{
-	pthread_exit(NULL);
-}
-
-
-/**
- * POSIX pthread version for ThreadObject.
- */
-class ThreadObject_pthread : public ThreadObject {
-private:
-	pthread_t m_thr;             ///< System thread identifier.
-	OTTDThreadFunc m_proc;       ///< External thread procedure.
-	void     *m_param;           ///< Parameter for the external thread procedure.
-	bool      m_attached;        ///< True if the ThreadObject was attached to an existing thread.
-	sem_t     m_sem_start;       ///< Here the new thread waits before it starts.
-	sem_t     m_sem_stop;        ///< Here the other thread can wait for this thread to end.
-
-public:
-	/**
-	 * Create a pthread and start it, calling proc(param).
-	 */
-	ThreadObject_pthread(OTTDThreadFunc proc, void *param) :
-		m_thr(0),
-		m_proc(proc),
-		m_param(param),
-		m_attached(false)
-	{
-		sem_init(&m_sem_start, 0, 0);
-		sem_init(&m_sem_stop, 0, 0);
-
-		pthread_create(&m_thr, NULL, &stThreadProc, this);
-		sem_post(&m_sem_start);
-	}
-
-	/**
-	 * Create a pthread and attach current thread to it.
-	 */
-	ThreadObject_pthread() :
-		m_thr(0),
-		m_proc(NULL),
-		m_param(0),
-		m_attached(true)
-	{
-		sem_init(&m_sem_start, 0, 0);
-		sem_init(&m_sem_stop, 0, 0);
-
-		m_thr = pthread_self();
-	}
-
-	/* virtual */ ~ThreadObject_pthread()
-	{
-		sem_destroy(&m_sem_stop);
-		sem_destroy(&m_sem_start);
-	};
-
-	/* virtual */ bool IsRunning()
-	{
-		return m_thr != 0;
-	}
-
-	/* virtual */ bool WaitForStop()
-	{
-		/* You can't wait on yourself */
-		assert(!IsCurrent());
-		/* If the thread is not running, waiting is over */
-		if (!IsRunning()) return true;
-
-		int ret = sem_wait(&m_sem_stop);
-		if (ret == 0) {
-			/* We have passed semaphore so increment it again */
-			sem_post(&m_sem_stop);
-			return true;
-		}
-		return false;
-	}
-
-	/* virtual */ bool IsCurrent()
-	{
-		return pthread_self() == m_thr;
-	}
-
-	/* virtual */ uint GetId()
-	{
-		return (uint)m_thr;
-	}
-
-private:
-	/**
-	 * On thread creation, this function is called, which calls the real startup
-	 *  function. This to get back into the correct instance again.
-	 */
-	static void *stThreadProc(void *thr)
-	{
-		return ((ThreadObject_pthread*)thr)->ThreadProc();
-	}
-
-	/**
-	 * A new thread is created, and this function is called. Call the custom
-	 *  function of the creator of the thread.
-	 */
-	void *ThreadProc()
-	{
-		/* The new thread stops here so the calling thread can complete pthread_create() call */
-		sem_wait(&m_sem_start);
-
-		/* Call the proc of the creator to continue this thread */
-		try {
-			m_proc(m_param);
-		} catch (...) {
-			DEBUG(misc, 0, "Exception in thread %u!", GetId());
-		}
-		/* The thread died, so we are no longer valid */
-		m_thr = 0;
-
-		/* Notify threads waiting for our completion */
-		sem_post(&m_sem_stop);
-		return NULL;
-	}
-};
-
-/* static */ ThreadObject *ThreadObject::New(OTTDThreadFunc proc, void *param)
-{
-	return new ThreadObject_pthread(proc, param);
-}
-
-/* static */ ThreadObject *ThreadObject::AttachCurrent()
-{
-	return new ThreadObject_pthread();
-}
-
-/* static */ uint ThreadObject::CurrentId()
-{
-	return (uint)pthread_self();
-}
-
-
-/**
- * POSIX pthread version of ThreadSemaphore.
- */
-struct ThreadSemaphore_pthread : public ThreadSemaphore {
-private:
-	sem_t m_sem;
-
-public:
-	ThreadSemaphore_pthread()
-	{
-		sem_init(&m_sem, 0, 0);
-	}
-
-	/* virtual */ ~ThreadSemaphore_pthread()
-	{
-		sem_destroy(&m_sem);
-	}
-
-	/* virtual */ void Set()
-	{
-		int val = 0;
-		if (sem_getvalue(&m_sem, &val) == 0 && val == 0) sem_post(&m_sem);
-	}
-
-	/* virtual */ void Wait()
-	{
-		sem_wait(&m_sem);
-	}
-};
-
-/* static */ ThreadSemaphore *ThreadSemaphore::New()
-{
-	return new ThreadSemaphore_pthread();
-}
-
-#elif defined(WIN32)
-
-#include <windows.h>
-#include <process.h>
-
-struct OTTDThread {
-	HANDLE thread;
-	uint   thread_id;
-	OTTDThreadFunc func;
-	void *arg;
-	void *ret;
-};
-
-static unsigned WINAPI Proxy(LPVOID arg)
-{
-	OTTDThread *t = (OTTDThread *)arg;
-	t->ret = t->func(t->arg);
-	return 0;
-}
-
-OTTDThread *OTTDCreateThread(OTTDThreadFunc function, void *arg)
-{
-	OTTDThread *t = MallocT<OTTDThread>(1);
-
-	if (t == NULL) return NULL;
-
-	t->func = function;
-	t->arg  = arg;
-	t->thread = (HANDLE)_beginthreadex(NULL, 0, Proxy, t, 0, &t->thread_id);
-
-	if (t->thread != NULL) {
-		return t;
-	} else {
-		free(t);
-		return NULL;
-	}
-}
-
-void *OTTDJoinThread(OTTDThread *t)
-{
-	void *ret;
-
-	if (t == NULL) return NULL;
-
-	WaitForSingleObject(t->thread, INFINITE);
-	CloseHandle(t->thread);
-	ret = t->ret;
-	free(t);
-	return ret;
-}
-
-void OTTDExitThread()
-{
-	_endthreadex(0);
-}
-
-/**
- * Win32 thread version for ThreadObject.
- */
-struct ThreadObject_Win32 : public ThreadObject {
-	uint     m_id_thr;
-	HANDLE   m_h_thr;
-	OTTDThreadFunc m_proc;
-	void     *m_param;
-	bool     m_attached;
-
-	/**
-	 * Create a win32 thread and start it, calling proc(param).
-	 */
-	ThreadObject_Win32(OTTDThreadFunc proc, void *param) :
-		m_id_thr(0),
-		m_h_thr(NULL),
-		m_proc(proc),
-		m_param(param),
-		m_attached(false)
-	{
-		m_h_thr = (HANDLE)_beginthreadex(NULL, 0, &stThreadProc, this, CREATE_SUSPENDED, &m_id_thr);
-		if (m_h_thr == NULL) return;
-		ResumeThread(m_h_thr);
-	}
-
-	/**
-	 * Create a win32 thread and attach current thread to it.
-	 */
-	ThreadObject_Win32() :
-		m_id_thr(0),
-		m_h_thr(NULL),
-		m_proc(NULL),
-		m_param(NULL),
-		m_attached(false)
-	{
-		BOOL ret = DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &m_h_thr, 0, FALSE, DUPLICATE_SAME_ACCESS);
-		if (!ret) return;
-		m_id_thr = GetCurrentThreadId();
-	}
-
-	/* virtual */ ~ThreadObject_Win32()
-	{
-		if (m_h_thr != NULL) {
-			CloseHandle(m_h_thr);
-			m_h_thr = NULL;
-		}
-	}
-
-	/* virtual */ bool IsRunning()
-	{
-		if (m_h_thr == NULL) return false;
-		DWORD exit_code = 0;
-		if (!GetExitCodeThread(m_h_thr, &exit_code)) return false;
-		return (exit_code == STILL_ACTIVE);
-	}
-
-	/* virtual */ bool WaitForStop()
-	{
-		/* You can't wait on yourself */
-		assert(!IsCurrent());
-		/* If the thread is not running, waiting is over */
-		if (!IsRunning()) return true;
-
-		DWORD res = WaitForSingleObject(m_h_thr, INFINITE);
-		return res == WAIT_OBJECT_0;
-	}
-
-	/* virtual */ bool IsCurrent()
-	{
-		DWORD id_cur = GetCurrentThreadId();
-		return id_cur == m_id_thr;
-	}
-
-	/* virtual */ uint GetId()
-	{
-		return m_id_thr;
-	}
-
-private:
-	/**
-	 * On thread creation, this function is called, which calls the real startup
-	 *  function. This to get back into the correct instance again.
-	 */
-	static uint CALLBACK stThreadProc(void *thr)
-	{
-		return ((ThreadObject_Win32*)thr)->ThreadProc();
-	}
-
-	/**
-	 * A new thread is created, and this function is called. Call the custom
-	 *  function of the creator of the thread.
-	 */
-	uint ThreadProc()
-	{
-		try {
-			m_proc(m_param);
-		} catch (...) {
-			DEBUG(misc, 0, "Exception in thread %d!", m_id_thr);
-		}
-
-		return 0;
-	}
-};
-
-/* static */ ThreadObject *ThreadObject::New(OTTDThreadFunc proc, void *param)
-{
-	return new ThreadObject_Win32(proc, param);
-}
-
-/* static */ ThreadObject* ThreadObject::AttachCurrent()
-{
-	return new ThreadObject_Win32();
-}
-
-/* static */ uint ThreadObject::CurrentId()
-{
-	return GetCurrentThreadId();
-}
-
-
-/**
- * Win32 thread version of ThreadSemaphore.
- */
-struct ThreadSemaphore_Win32 : public ThreadSemaphore {
-private:
-	HANDLE m_handle;
-
-public:
-	ThreadSemaphore_Win32()
-	{
-		m_handle = ::CreateEvent(NULL, FALSE, FALSE, NULL);
-	}
-
-	/* virtual */ ~ThreadSemaphore_Win32()
-	{
-		::CloseHandle(m_handle);
-	}
-
-	/* virtual */ void Set()
-	{
-		::SetEvent(m_handle);
-	}
-
-	/* virtual */ void Wait()
-	{
-		::WaitForSingleObject(m_handle, INFINITE);
-	}
-};
-
-/* static */ ThreadSemaphore *ThreadSemaphore::New()
-{
-	return new ThreadSemaphore_Win32();
-}
-
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/thread_none.cpp	Tue Apr 01 13:40:36 2008 +0000
@@ -0,0 +1,18 @@
+/* $Id$ */
+
+/** @file thread_none.cpp No-Threads-Available implementation of Threads */
+
+#include "stdafx.h"
+#include "thread.h"
+
+OTTDThread *OTTDCreateThread(OTTDThreadFunc function, void *arg) {
+	return NULL;
+}
+
+void *OTTDJoinThread(OTTDThread *t) {
+	return NULL;
+}
+
+void OTTDExitThread() {
+	NOT_REACHED();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/thread_os2.cpp	Tue Apr 01 13:40:36 2008 +0000
@@ -0,0 +1,60 @@
+/* $Id$ */
+
+/** @file thread_os2.cpp OS2 implementation of Threads. */
+
+#include "stdafx.h"
+#include "thread.h"
+#include "debug.h"
+#include "core/alloc_func.hpp"
+#include <stdlib.h>
+
+#define INCL_DOS
+#include <os2.h>
+#include <process.h>
+
+struct OTTDThread {
+	TID thread;
+	OTTDThreadFunc func;
+	void *arg;
+	void *ret;
+};
+
+static void Proxy(void *arg)
+{
+	OTTDThread *t = (OTTDThread *)arg;
+	t->ret = t->func(t->arg);
+}
+
+OTTDThread *OTTDCreateThread(OTTDThreadFunc function, void *arg)
+{
+	OTTDThread *t = MallocT<OTTDThread>(1);
+
+	if (t == NULL) return NULL;
+
+	t->func = function;
+	t->arg  = arg;
+	t->thread = _beginthread(Proxy, NULL, 32768, t);
+	if (t->thread != (TID)-1) {
+		return t;
+	} else {
+		free(t);
+		return NULL;
+	}
+}
+
+void *OTTDJoinThread(OTTDThread *t)
+{
+	void *ret;
+
+	if (t == NULL) return NULL;
+
+	DosWaitThread(&t->thread, DCWW_WAIT);
+	ret = t->ret;
+	free(t);
+	return ret;
+}
+
+void OTTDExitThread()
+{
+	_endthread();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/thread_pthread.cpp	Tue Apr 01 13:40:36 2008 +0000
@@ -0,0 +1,213 @@
+/* $Id$ */
+
+/** @file thread_pthread.cpp POSIX pthread implementation of Threads. */
+
+#include "stdafx.h"
+#include "thread.h"
+#include "debug.h"
+#include "core/alloc_func.hpp"
+#include <stdlib.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <unistd.h>
+
+struct OTTDThread {
+	pthread_t thread;
+};
+
+OTTDThread *OTTDCreateThread(OTTDThreadFunc function, void *arg)
+{
+	OTTDThread *t = MallocT<OTTDThread>(1);
+
+	if (t == NULL) return NULL;
+
+	if (pthread_create(&t->thread, NULL, function, arg) == 0) {
+		return t;
+	} else {
+		free(t);
+		return NULL;
+	}
+}
+
+void *OTTDJoinThread(OTTDThread *t)
+{
+	void* ret;
+
+	if (t == NULL) return NULL;
+
+	pthread_join(t->thread, &ret);
+	free(t);
+	return ret;
+}
+
+void OTTDExitThread()
+{
+	pthread_exit(NULL);
+}
+
+
+/**
+ * POSIX pthread version for ThreadObject.
+ */
+class ThreadObject_pthread : public ThreadObject {
+private:
+	pthread_t m_thr;             ///< System thread identifier.
+	OTTDThreadFunc m_proc;       ///< External thread procedure.
+	void     *m_param;           ///< Parameter for the external thread procedure.
+	bool      m_attached;        ///< True if the ThreadObject was attached to an existing thread.
+	sem_t     m_sem_start;       ///< Here the new thread waits before it starts.
+	sem_t     m_sem_stop;        ///< Here the other thread can wait for this thread to end.
+
+public:
+	/**
+	 * Create a pthread and start it, calling proc(param).
+	 */
+	ThreadObject_pthread(OTTDThreadFunc proc, void *param) :
+		m_thr(0),
+		m_proc(proc),
+		m_param(param),
+		m_attached(false)
+	{
+		sem_init(&m_sem_start, 0, 0);
+		sem_init(&m_sem_stop, 0, 0);
+
+		pthread_create(&m_thr, NULL, &stThreadProc, this);
+		sem_post(&m_sem_start);
+	}
+
+	/**
+	 * Create a pthread and attach current thread to it.
+	 */
+	ThreadObject_pthread() :
+		m_thr(0),
+		m_proc(NULL),
+		m_param(0),
+		m_attached(true)
+	{
+		sem_init(&m_sem_start, 0, 0);
+		sem_init(&m_sem_stop, 0, 0);
+
+		m_thr = pthread_self();
+	}
+
+	/* virtual */ ~ThreadObject_pthread()
+	{
+		sem_destroy(&m_sem_stop);
+		sem_destroy(&m_sem_start);
+	};
+
+	/* virtual */ bool IsRunning()
+	{
+		return m_thr != 0;
+	}
+
+	/* virtual */ bool WaitForStop()
+	{
+		/* You can't wait on yourself */
+		assert(!IsCurrent());
+		/* If the thread is not running, waiting is over */
+		if (!IsRunning()) return true;
+
+		int ret = sem_wait(&m_sem_stop);
+		if (ret == 0) {
+			/* We have passed semaphore so increment it again */
+			sem_post(&m_sem_stop);
+			return true;
+		}
+		return false;
+	}
+
+	/* virtual */ bool IsCurrent()
+	{
+		return pthread_self() == m_thr;
+	}
+
+	/* virtual */ uint GetId()
+	{
+		return (uint)m_thr;
+	}
+
+private:
+	/**
+	 * On thread creation, this function is called, which calls the real startup
+	 *  function. This to get back into the correct instance again.
+	 */
+	static void *stThreadProc(void *thr)
+	{
+		return ((ThreadObject_pthread*)thr)->ThreadProc();
+	}
+
+	/**
+	 * A new thread is created, and this function is called. Call the custom
+	 *  function of the creator of the thread.
+	 */
+	void *ThreadProc()
+	{
+		/* The new thread stops here so the calling thread can complete pthread_create() call */
+		sem_wait(&m_sem_start);
+
+		/* Call the proc of the creator to continue this thread */
+		try {
+			m_proc(m_param);
+		} catch (...) {
+			DEBUG(misc, 0, "Exception in thread %u!", GetId());
+		}
+		/* The thread died, so we are no longer valid */
+		m_thr = 0;
+
+		/* Notify threads waiting for our completion */
+		sem_post(&m_sem_stop);
+		return NULL;
+	}
+};
+
+/* static */ ThreadObject *ThreadObject::New(OTTDThreadFunc proc, void *param)
+{
+	return new ThreadObject_pthread(proc, param);
+}
+
+/* static */ ThreadObject *ThreadObject::AttachCurrent()
+{
+	return new ThreadObject_pthread();
+}
+
+/* static */ uint ThreadObject::CurrentId()
+{
+	return (uint)pthread_self();
+}
+
+
+/**
+ * POSIX pthread version of ThreadSemaphore.
+ */
+class ThreadSemaphore_pthread : public ThreadSemaphore {
+private:
+	sem_t m_sem;
+
+public:
+	ThreadSemaphore_pthread()
+	{
+		sem_init(&m_sem, 0, 0);
+	}
+
+	/* virtual */ ~ThreadSemaphore_pthread()
+	{
+		sem_destroy(&m_sem);
+	}
+
+	/* virtual */ void Set()
+	{
+		int val = 0;
+		if (sem_getvalue(&m_sem, &val) == 0 && val == 0) sem_post(&m_sem);
+	}
+
+	/* virtual */ void Wait()
+	{
+		sem_wait(&m_sem);
+	}
+};
+
+/* static */ ThreadSemaphore *ThreadSemaphore::New()
+{
+	return new ThreadSemaphore_pthread();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/thread_win32.cpp	Tue Apr 01 13:40:36 2008 +0000
@@ -0,0 +1,216 @@
+/* $Id$ */
+
+/** @file thread_win32.cpp Win32 thread implementation of Threads. */
+
+#include "stdafx.h"
+#include "thread.h"
+#include "debug.h"
+#include "core/alloc_func.hpp"
+#include <stdlib.h>
+#include <windows.h>
+#include <process.h>
+
+struct OTTDThread {
+	HANDLE thread;
+	uint   thread_id;
+	OTTDThreadFunc func;
+	void *arg;
+	void *ret;
+};
+
+static unsigned WINAPI Proxy(LPVOID arg)
+{
+	OTTDThread *t = (OTTDThread *)arg;
+	t->ret = t->func(t->arg);
+	return 0;
+}
+
+OTTDThread *OTTDCreateThread(OTTDThreadFunc function, void *arg)
+{
+	OTTDThread *t = MallocT<OTTDThread>(1);
+
+	if (t == NULL) return NULL;
+
+	t->func = function;
+	t->arg  = arg;
+	t->thread = (HANDLE)_beginthreadex(NULL, 0, Proxy, t, 0, &t->thread_id);
+
+	if (t->thread != NULL) {
+		return t;
+	} else {
+		free(t);
+		return NULL;
+	}
+}
+
+void *OTTDJoinThread(OTTDThread *t)
+{
+	void *ret;
+
+	if (t == NULL) return NULL;
+
+	WaitForSingleObject(t->thread, INFINITE);
+	CloseHandle(t->thread);
+	ret = t->ret;
+	free(t);
+	return ret;
+}
+
+void OTTDExitThread()
+{
+	_endthreadex(0);
+}
+
+/**
+ * Win32 thread version for ThreadObject.
+ */
+class ThreadObject_Win32 : public ThreadObject {
+	uint     m_id_thr;
+	HANDLE   m_h_thr;
+	OTTDThreadFunc m_proc;
+	void     *m_param;
+	bool     m_attached;
+
+	/**
+	 * Create a win32 thread and start it, calling proc(param).
+	 */
+	ThreadObject_Win32(OTTDThreadFunc proc, void *param) :
+		m_id_thr(0),
+		m_h_thr(NULL),
+		m_proc(proc),
+		m_param(param),
+		m_attached(false)
+	{
+		m_h_thr = (HANDLE)_beginthreadex(NULL, 0, &stThreadProc, this, CREATE_SUSPENDED, &m_id_thr);
+		if (m_h_thr == NULL) return;
+		ResumeThread(m_h_thr);
+	}
+
+	/**
+	 * Create a win32 thread and attach current thread to it.
+	 */
+	ThreadObject_Win32() :
+		m_id_thr(0),
+		m_h_thr(NULL),
+		m_proc(NULL),
+		m_param(NULL),
+		m_attached(false)
+	{
+		BOOL ret = DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &m_h_thr, 0, FALSE, DUPLICATE_SAME_ACCESS);
+		if (!ret) return;
+		m_id_thr = GetCurrentThreadId();
+	}
+
+	/* virtual */ ~ThreadObject_Win32()
+	{
+		if (m_h_thr != NULL) {
+			CloseHandle(m_h_thr);
+			m_h_thr = NULL;
+		}
+	}
+
+	/* virtual */ bool IsRunning()
+	{
+		if (m_h_thr == NULL) return false;
+		DWORD exit_code = 0;
+		if (!GetExitCodeThread(m_h_thr, &exit_code)) return false;
+		return (exit_code == STILL_ACTIVE);
+	}
+
+	/* virtual */ bool WaitForStop()
+	{
+		/* You can't wait on yourself */
+		assert(!IsCurrent());
+		/* If the thread is not running, waiting is over */
+		if (!IsRunning()) return true;
+
+		DWORD res = WaitForSingleObject(m_h_thr, INFINITE);
+		return res == WAIT_OBJECT_0;
+	}
+
+	/* virtual */ bool IsCurrent()
+	{
+		DWORD id_cur = GetCurrentThreadId();
+		return id_cur == m_id_thr;
+	}
+
+	/* virtual */ uint GetId()
+	{
+		return m_id_thr;
+	}
+
+private:
+	/**
+	 * On thread creation, this function is called, which calls the real startup
+	 *  function. This to get back into the correct instance again.
+	 */
+	static uint CALLBACK stThreadProc(void *thr)
+	{
+		return ((ThreadObject_Win32*)thr)->ThreadProc();
+	}
+
+	/**
+	 * A new thread is created, and this function is called. Call the custom
+	 *  function of the creator of the thread.
+	 */
+	uint ThreadProc()
+	{
+		try {
+			m_proc(m_param);
+		} catch (...) {
+			DEBUG(misc, 0, "Exception in thread %d!", m_id_thr);
+		}
+
+		return 0;
+	}
+};
+
+/* static */ ThreadObject *ThreadObject::New(OTTDThreadFunc proc, void *param)
+{
+	return new ThreadObject_Win32(proc, param);
+}
+
+/* static */ ThreadObject* ThreadObject::AttachCurrent()
+{
+	return new ThreadObject_Win32();
+}
+
+/* static */ uint ThreadObject::CurrentId()
+{
+	return GetCurrentThreadId();
+}
+
+
+/**
+ * Win32 thread version of ThreadSemaphore.
+ */
+class ThreadSemaphore_Win32 : public ThreadSemaphore {
+private:
+	HANDLE m_handle;
+
+public:
+	ThreadSemaphore_Win32()
+	{
+		m_handle = ::CreateEvent(NULL, FALSE, FALSE, NULL);
+	}
+
+	/* virtual */ ~ThreadSemaphore_Win32()
+	{
+		::CloseHandle(m_handle);
+	}
+
+	/* virtual */ void Set()
+	{
+		::SetEvent(m_handle);
+	}
+
+	/* virtual */ void Wait()
+	{
+		::WaitForSingleObject(m_handle, INFINITE);
+	}
+};
+
+/* static */ ThreadSemaphore *ThreadSemaphore::New()
+{
+	return new ThreadSemaphore_Win32();
+}