From 07d2af338e237889ff453a3a774522b9b0021439 Mon Sep 17 00:00:00 2001 From: rubidium Date: Tue, 1 Sep 2009 10:07:22 +0000 Subject: (svn r17339) -Codechange: move thread related files to their own directory (like done for video, music, sound, etc) --- Makefile.bundle.in | 4 +- projects/openttd_vs80.vcproj | 20 ++-- projects/openttd_vs90.vcproj | 20 ++-- source.list | 38 ++++---- src/genworld.cpp | 2 +- src/genworld_gui.cpp | 2 +- src/gfx.cpp | 2 +- src/network/core/tcp_connect.cpp | 2 +- src/network/network_gamelist.cpp | 2 +- src/network/network_udp.cpp | 2 +- src/openttd.cpp | 2 +- src/saveload/saveload.cpp | 2 +- src/thread.h | 73 -------------- src/thread/thread.h | 73 ++++++++++++++ src/thread/thread_morphos.cpp | 199 +++++++++++++++++++++++++++++++++++++++ src/thread/thread_none.cpp | 31 ++++++ src/thread/thread_os2.cpp | 123 ++++++++++++++++++++++++ src/thread/thread_pthread.cpp | 124 ++++++++++++++++++++++++ src/thread/thread_win32.cpp | 136 ++++++++++++++++++++++++++ src/thread_morphos.cpp | 199 --------------------------------------- src/thread_none.cpp | 31 ------ src/thread_os2.cpp | 123 ------------------------ src/thread_pthread.cpp | 124 ------------------------ src/thread_win32.cpp | 136 -------------------------- 24 files changed, 740 insertions(+), 730 deletions(-) delete mode 100644 src/thread.h create mode 100644 src/thread/thread.h create mode 100644 src/thread/thread_morphos.cpp create mode 100644 src/thread/thread_none.cpp create mode 100644 src/thread/thread_os2.cpp create mode 100644 src/thread/thread_pthread.cpp create mode 100644 src/thread/thread_win32.cpp delete mode 100644 src/thread_morphos.cpp delete mode 100644 src/thread_none.cpp delete mode 100644 src/thread_os2.cpp delete mode 100644 src/thread_pthread.cpp delete mode 100644 src/thread_win32.cpp diff --git a/Makefile.bundle.in b/Makefile.bundle.in index b7c8d2f8d..d9cf9467e 100644 --- a/Makefile.bundle.in +++ b/Makefile.bundle.in @@ -151,8 +151,8 @@ bundle_exe: all @echo '[BUNDLE] Creating $(BUNDLE_NAME).exe' $(Q)mkdir -p "$(BUNDLES_DIR)" $(Q)unix2dos "$(ROOT_DIR)/docs/"* "$(ROOT_DIR)/readme.txt" "$(ROOT_DIR)/COPYING" "$(ROOT_DIR)/changelog.txt" "$(ROOT_DIR)/known-bugs.txt" - $(Q)cd $(ROOT_DIR)/os/win32/installer && makensis.exe //DVERSION_INCLUDE=version_$(PLATFORM).txt install.nsi - $(Q)mv $(ROOT_DIR)/os/win32/installer/*$(PLATFORM).exe "$(BUNDLES_DIR)/$(BUNDLE_NAME).exe" + $(Q)cd $(ROOT_DIR)/os/windows/installer && makensis.exe //DVERSION_INCLUDE=version_$(PLATFORM).txt install.nsi + $(Q)mv $(ROOT_DIR)/os/windows/installer/*$(PLATFORM).exe "$(BUNDLES_DIR)/$(BUNDLE_NAME).exe" ifdef OSXAPP install: diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj index 566353e7b..a9d20174d 100644 --- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -735,10 +735,6 @@ RelativePath=".\..\src\tgp.cpp" > - - @@ -1503,10 +1499,6 @@ RelativePath=".\..\src\tgp.h" > - - @@ -3580,6 +3572,18 @@ > + + + + + + - - @@ -1500,10 +1496,6 @@ RelativePath=".\..\src\tgp.h" > - - @@ -3577,6 +3569,18 @@ > + + + + + + . - */ - -/** @file thread.h Base of all threads. */ - -#ifndef THREAD_H -#define THREAD_H - -typedef void (*OTTDThreadFunc)(void *); - -class OTTDThreadExitSignal { }; - -/** - * A Thread Object which works on all our supported OSes. - */ -class ThreadObject { -public: - /** - * Virtual destructor to allow 'delete' operator to work properly. - */ - virtual ~ThreadObject() {}; - - /** - * Exit this thread. - */ - virtual bool Exit() = 0; - - /** - * Join this thread. - */ - virtual void Join() = 0; - - /** - * Create a thread; proc will be called as first function inside the thread, - * with optinal params. - * @param proc The procedure to call inside the thread. - * @param param The params to give with 'proc'. - * @param thread Place to store a pointer to the thread in. May be NULL. - * @return True if the thread was started correctly. - */ - static bool New(OTTDThreadFunc proc, void *param, ThreadObject **thread = NULL); -}; - -/** - * Cross-platform Mutex - */ -class ThreadMutex { -public: - static ThreadMutex *New(); - - /** - * Virtual Destructor to avoid compiler warnings. - */ - virtual ~ThreadMutex() {}; - - /** - * Begin the critical section - */ - virtual void BeginCritical() = 0; - - /** - * End of the critical section - */ - virtual void EndCritical() = 0; -}; - -#endif /* THREAD_H */ diff --git a/src/thread/thread.h b/src/thread/thread.h new file mode 100644 index 000000000..22873bee5 --- /dev/null +++ b/src/thread/thread.h @@ -0,0 +1,73 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file thread.h Base of all threads. */ + +#ifndef THREAD_H +#define THREAD_H + +typedef void (*OTTDThreadFunc)(void *); + +class OTTDThreadExitSignal { }; + +/** + * A Thread Object which works on all our supported OSes. + */ +class ThreadObject { +public: + /** + * Virtual destructor to allow 'delete' operator to work properly. + */ + virtual ~ThreadObject() {}; + + /** + * Exit this thread. + */ + virtual bool Exit() = 0; + + /** + * Join this thread. + */ + virtual void Join() = 0; + + /** + * Create a thread; proc will be called as first function inside the thread, + * with optinal params. + * @param proc The procedure to call inside the thread. + * @param param The params to give with 'proc'. + * @param thread Place to store a pointer to the thread in. May be NULL. + * @return True if the thread was started correctly. + */ + static bool New(OTTDThreadFunc proc, void *param, ThreadObject **thread = NULL); +}; + +/** + * Cross-platform Mutex + */ +class ThreadMutex { +public: + static ThreadMutex *New(); + + /** + * Virtual Destructor to avoid compiler warnings. + */ + virtual ~ThreadMutex() {}; + + /** + * Begin the critical section + */ + virtual void BeginCritical() = 0; + + /** + * End of the critical section + */ + virtual void EndCritical() = 0; +}; + +#endif /* THREAD_H */ diff --git a/src/thread/thread_morphos.cpp b/src/thread/thread_morphos.cpp new file mode 100644 index 000000000..abf2cf0cc --- /dev/null +++ b/src/thread/thread_morphos.cpp @@ -0,0 +1,199 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file thread_morphos.cpp MorphOS implementation of Threads. */ + +#include "../stdafx.h" +#include "thread.h" +#include "../debug.h" +#include "../core/alloc_func.hpp" +#include +#include + +#include +#include +#include + +#include +#include + +/** + * avoid name clashes with MorphOS API functions + */ +#undef Exit +#undef Wait + + +/** + * NOTE: this code heavily depends on latest libnix updates. So make + * sure you link with new stuff which supports semaphore locking of + * the IO resources, else it will just go foobar. + */ + + +struct OTTDThreadStartupMessage { + struct Message msg; ///< standard exec.library message (MUST be the first thing in the message struct!) + OTTDThreadFunc func; ///< function the thread will execute + void *arg; ///< functions arguments for the thread function +}; + + +/** + * Default OpenTTD STDIO/ERR debug output is not very useful for this, so we + * utilize serial/ramdebug instead. + */ +#ifndef NO_DEBUG_MESSAGES +void KPutStr(CONST_STRPTR format) +{ + RawDoFmt(format, NULL, (void (*)())RAWFMTFUNC_SERIAL, NULL); +} +#else +#define KPutStr(x) +#endif + + +/** + * MorphOS version for ThreadObject. + */ +class ThreadObject_MorphOS : public ThreadObject { +private: + APTR m_thr; ///< System thread identifier. + struct MsgPort *m_replyport; + struct OTTDThreadStartupMessage m_msg; + bool self_destruct; + +public: + /** + * Create a sub process and start it, calling proc(param). + */ + ThreadObject_MorphOS(OTTDThreadFunc proc, void *param, self_destruct) : + m_thr(0), self_destruct(self_destruct) + { + struct Task *parent; + + KPutStr("[OpenTTD] Create thread...\n"); + + parent = FindTask(NULL); + + /* Make sure main thread runs with sane priority */ + SetTaskPri(parent, 0); + + /* Things we'll pass down to the child by utilizing NP_StartupMsg */ + m_msg.func = proc; + m_msg.arg = param; + + m_replyport = CreateMsgPort(); + + if (m_replyport != NULL) { + struct Process *child; + + m_msg.msg.mn_Node.ln_Type = NT_MESSAGE; + m_msg.msg.mn_ReplyPort = m_replyport; + m_msg.msg.mn_Length = sizeof(struct OTTDThreadStartupMessage); + + child = CreateNewProcTags( + NP_CodeType, CODETYPE_PPC, + NP_Entry, ThreadObject_MorphOS::Proxy, + NP_StartupMsg, (IPTR)&m_msg, + NP_Priority, 5UL, + NP_Name, (IPTR)"OpenTTD Thread", + NP_PPCStackSize, 131072UL, + TAG_DONE); + + m_thr = (APTR) child; + + if (child != NULL) { + KPutStr("[OpenTTD] Child process launched.\n"); + } else { + KPutStr("[OpenTTD] Couldn't create child process. (constructors never fail, yeah!)\n"); + DeleteMsgPort(m_replyport); + } + } + } + + /* virtual */ ~ThreadObject_MorphOS() + { + } + + /* virtual */ bool Exit() + { + struct OTTDThreadStartupMessage *msg; + + /* You can only exit yourself */ + assert(IsCurrent()); + + KPutStr("[Child] Aborting...\n"); + + if (NewGetTaskAttrs(NULL, &msg, sizeof(struct OTTDThreadStartupMessage *), TASKINFOTYPE_STARTUPMSG, TAG_DONE) && msg != NULL) { + /* For now we terminate by throwing an error, gives much cleaner cleanup */ + throw OTTDThreadExitSignal(); + } + + return true; + } + + /* virtual */ void Join() + { + struct OTTDThreadStartupMessage *reply; + + /* You cannot join yourself */ + assert(!IsCurrent()); + + KPutStr("[OpenTTD] Join threads...\n"); + KPutStr("[OpenTTD] Wait for child to quit...\n"); + WaitPort(m_replyport); + + GetMsg(m_replyport); + DeleteMsgPort(m_replyport); + m_thr = 0; + } + + /* virtual */ bool IsCurrent() + { + return FindTask(NULL) == 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 Proxy() + { + struct Task *child = FindTask(NULL); + struct OTTDThreadStartupMessage *msg; + + /* Make sure, we don't block the parent. */ + SetTaskPri(child, -5); + + KPutStr("[Child] Progressing...\n"); + + if (NewGetTaskAttrs(NULL, &msg, sizeof(struct OTTDThreadStartupMessage *), TASKINFOTYPE_STARTUPMSG, TAG_DONE) && msg != NULL) { + try { + msg->func(msg->arg); + } catch(OTTDThreadExitSignal e) { + KPutStr("[Child] Returned to main()\n"); + } catch(...) { + NOT_REACHED(); + } + } + + /* Quit the child, exec.library will reply the startup msg internally. */ + KPutStr("[Child] Done.\n"); + + if (self_destruct) delete this; + } +}; + +/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread) +{ + ThreadObject *to = new ThreadObject_MorphOS(proc, param, thread == NULL); + if (thread != NULL) *thread = to; + return true; +} diff --git a/src/thread/thread_none.cpp b/src/thread/thread_none.cpp new file mode 100644 index 000000000..861f2cfd6 --- /dev/null +++ b/src/thread/thread_none.cpp @@ -0,0 +1,31 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file thread_none.cpp No-Threads-Available implementation of Threads */ + +#include "../stdafx.h" +#include "thread.h" + +/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread) +{ + if (thread != NULL) *thread = NULL; + return false; +} + +/** Mutex that doesn't do locking because it ain't needed when there're no threads */ +class ThreadMutex_None : public ThreadMutex { +public: + virtual void BeginCritical() {} + virtual void EndCritical() {} +}; + +/* static */ ThreadMutex *ThreadMutex::New() +{ + return new ThreadMutex_None(); +} diff --git a/src/thread/thread_os2.cpp b/src/thread/thread_os2.cpp new file mode 100644 index 000000000..1145e8e41 --- /dev/null +++ b/src/thread/thread_os2.cpp @@ -0,0 +1,123 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file thread_os2.cpp OS/2 implementation of Threads. */ + +#include "../stdafx.h" +#include "thread.h" + +#define INCL_DOS +#include +#include + +/** + * OS/2 version for ThreadObject. + */ +class ThreadObject_OS2 : public ThreadObject { +private: + TID thread; ///< System thread identifier. + OTTDThreadFunc proc; ///< External thread procedure. + void *param; ///< Parameter for the external thread procedure. + bool self_destruct; ///< Free ourselves when done? + +public: + /** + * Create a thread and start it, calling proc(param). + */ + ThreadObject_OS2(OTTDThreadFunc proc, void *param, bool self_destruct) : + thread(0), + proc(proc), + param(param), + self_destruct(self_destruct) + { + thread = _beginthread(stThreadProc, NULL, 32768, this); + } + + /* virtual */ bool Exit() + { + _endthread(); + return true; + } + + /* virtual */ void Join() + { + DosWaitThread(&this->thread, DCWW_WAIT); + this->thread = 0; + } +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) + { + ((ThreadObject_OS2 *)thr)->ThreadProc(); + } + + /** + * A new thread is created, and this function is called. Call the custom + * function of the creator of the thread. + */ + void ThreadProc() + { + /* Call the proc of the creator to continue this thread */ + try { + this->proc(this->param); + } catch (OTTDThreadExitSignal e) { + } catch (...) { + NOT_REACHED(); + } + + if (self_destruct) { + this->Exit(); + delete this; + } + } +}; + +/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread) +{ + ThreadObject *to = new ThreadObject_OS2(proc, param, thread == NULL); + if (thread != NULL) *thread = to; + return true; +} + +/** + * OS/2 version of ThreadMutex. + */ +class ThreadMutex_OS2 : public ThreadMutex { +private: + HMTX mutex; + +public: + ThreadMutex_OS2() + { + DosCreateMutexSem(NULL, &mutex, 0, FALSE); + } + + /* virtual */ ~ThreadMutex_OS2() + { + DosCloseMutexSem(mutex); + } + + /* virtual */ void BeginCritical() + { + DosRequestMutexSem(mutex, (unsigned long) SEM_INDEFINITE_WAIT); + } + + /* virtual */ void EndCritical() + { + DosReleaseMutexSem(mutex); + } +}; + +/* static */ ThreadMutex *ThreadMutex::New() +{ + return new ThreadMutex_OS2(); +} diff --git a/src/thread/thread_pthread.cpp b/src/thread/thread_pthread.cpp new file mode 100644 index 000000000..483b71c0f --- /dev/null +++ b/src/thread/thread_pthread.cpp @@ -0,0 +1,124 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file thread_pthread.cpp POSIX pthread implementation of Threads. */ + +#include "../stdafx.h" +#include "thread.h" +#include + +/** + * POSIX pthread version for ThreadObject. + */ +class ThreadObject_pthread : public ThreadObject { +private: + pthread_t thread; ///< System thread identifier. + OTTDThreadFunc proc; ///< External thread procedure. + void *param; ///< Parameter for the external thread procedure. + bool self_destruct; ///< Free ourselves when done? + +public: + /** + * Create a pthread and start it, calling proc(param). + */ + ThreadObject_pthread(OTTDThreadFunc proc, void *param, bool self_destruct) : + thread(0), + proc(proc), + param(param), + self_destruct(self_destruct) + { + pthread_create(&this->thread, NULL, &stThreadProc, this); + } + + /* virtual */ bool Exit() + { + assert(pthread_self() == this->thread); + /* For now we terminate by throwing an error, gives much cleaner cleanup */ + throw OTTDThreadExitSignal(); + } + + /* virtual */ void Join() + { + /* You cannot join yourself */ + assert(pthread_self() != this->thread); + pthread_join(this->thread, NULL); + this->thread = 0; + } +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) + { + ((ThreadObject_pthread *)thr)->ThreadProc(); + pthread_exit(NULL); + } + + /** + * A new thread is created, and this function is called. Call the custom + * function of the creator of the thread. + */ + void ThreadProc() + { + /* Call the proc of the creator to continue this thread */ + try { + this->proc(this->param); + } catch (OTTDThreadExitSignal e) { + } catch (...) { + NOT_REACHED(); + } + + if (self_destruct) { + pthread_detach(pthread_self()); + delete this; + } + } +}; + +/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread) +{ + ThreadObject *to = new ThreadObject_pthread(proc, param, thread == NULL); + if (thread != NULL) *thread = to; + return true; +} + +/** + * POSIX pthread version of ThreadMutex. + */ +class ThreadMutex_pthread : public ThreadMutex { +private: + pthread_mutex_t mutex; + +public: + ThreadMutex_pthread() + { + pthread_mutex_init(&this->mutex, NULL); + } + + /* virtual */ ~ThreadMutex_pthread() + { + pthread_mutex_destroy(&this->mutex); + } + + /* virtual */ void BeginCritical() + { + pthread_mutex_lock(&this->mutex); + } + + /* virtual */ void EndCritical() + { + pthread_mutex_unlock(&this->mutex); + } +}; + +/* static */ ThreadMutex *ThreadMutex::New() +{ + return new ThreadMutex_pthread(); +} diff --git a/src/thread/thread_win32.cpp b/src/thread/thread_win32.cpp new file mode 100644 index 000000000..e752de1ae --- /dev/null +++ b/src/thread/thread_win32.cpp @@ -0,0 +1,136 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file thread_win32.cpp Win32 thread implementation of Threads. */ + +#include "../stdafx.h" +#include "thread.h" +#include "../debug.h" +#include "../core/alloc_func.hpp" +#include +#include +#include + +/** + * Win32 thread version for ThreadObject. + */ +class ThreadObject_Win32 : public ThreadObject { +private: + HANDLE thread; ///< System thread identifier. + uint id; ///< Thread identifier. + OTTDThreadFunc proc; ///< External thread procedure. + void *param; ///< Parameter for the external thread procedure. + bool self_destruct; ///< Free ourselves when done? + +public: + /** + * Create a win32 thread and start it, calling proc(param). + */ + ThreadObject_Win32(OTTDThreadFunc proc, void *param, bool self_destruct) : + thread(NULL), + id(0), + proc(proc), + param(param), + self_destruct(self_destruct) + { + this->thread = (HANDLE)_beginthreadex(NULL, 0, &stThreadProc, this, CREATE_SUSPENDED, &this->id); + if (this->thread == NULL) return; + ResumeThread(this->thread); + } + + /* virtual */ ~ThreadObject_Win32() + { + if (this->thread != NULL) { + CloseHandle(this->thread); + this->thread = NULL; + } + } + + /* virtual */ bool Exit() + { + assert(GetCurrentThreadId() == this->id); + /* For now we terminate by throwing an error, gives much cleaner cleanup */ + throw OTTDThreadExitSignal(); + } + + /* virtual */ void Join() + { + /* You cannot join yourself */ + assert(GetCurrentThreadId() != this->id); + WaitForSingleObject(this->thread, INFINITE); + } + +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) + { + ((ThreadObject_Win32 *)thr)->ThreadProc(); + return 0; + } + + /** + * A new thread is created, and this function is called. Call the custom + * function of the creator of the thread. + */ + void ThreadProc() + { + try { + this->proc(this->param); + } catch (OTTDThreadExitSignal) { + } catch (...) { + NOT_REACHED(); + } + + if (self_destruct) delete this; + } +}; + +/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread) +{ + ThreadObject *to = new ThreadObject_Win32(proc, param, thread == NULL); + if (thread != NULL) *thread = to; + return true; +} + +/** + * Win32 thread version of ThreadMutex. + */ +class ThreadMutex_Win32 : public ThreadMutex { +private: + CRITICAL_SECTION critical_section; + +public: + ThreadMutex_Win32() + { + InitializeCriticalSection(&this->critical_section); + } + + /* virtual */ ~ThreadMutex_Win32() + { + DeleteCriticalSection(&this->critical_section); + } + + /* virtual */ void BeginCritical() + { + EnterCriticalSection(&this->critical_section); + } + + /* virtual */ void EndCritical() + { + LeaveCriticalSection(&this->critical_section); + } +}; + +/* static */ ThreadMutex *ThreadMutex::New() +{ + return new ThreadMutex_Win32(); +} diff --git a/src/thread_morphos.cpp b/src/thread_morphos.cpp deleted file mode 100644 index 5248a7837..000000000 --- a/src/thread_morphos.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* $Id$ */ - -/* - * This file is part of OpenTTD. - * OpenTTD 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, version 2. - * OpenTTD 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 OpenTTD. If not, see . - */ - -/** @file thread_morphos.cpp MorphOS implementation of Threads. */ - -#include "stdafx.h" -#include "thread.h" -#include "debug.h" -#include "core/alloc_func.hpp" -#include -#include - -#include -#include -#include - -#include -#include - -/** - * avoid name clashes with MorphOS API functions - */ -#undef Exit -#undef Wait - - -/** - * NOTE: this code heavily depends on latest libnix updates. So make - * sure you link with new stuff which supports semaphore locking of - * the IO resources, else it will just go foobar. - */ - - -struct OTTDThreadStartupMessage { - struct Message msg; ///< standard exec.library message (MUST be the first thing in the message struct!) - OTTDThreadFunc func; ///< function the thread will execute - void *arg; ///< functions arguments for the thread function -}; - - -/** - * Default OpenTTD STDIO/ERR debug output is not very useful for this, so we - * utilize serial/ramdebug instead. - */ -#ifndef NO_DEBUG_MESSAGES -void KPutStr(CONST_STRPTR format) -{ - RawDoFmt(format, NULL, (void (*)())RAWFMTFUNC_SERIAL, NULL); -} -#else -#define KPutStr(x) -#endif - - -/** - * MorphOS version for ThreadObject. - */ -class ThreadObject_MorphOS : public ThreadObject { -private: - APTR m_thr; ///< System thread identifier. - struct MsgPort *m_replyport; - struct OTTDThreadStartupMessage m_msg; - bool self_destruct; - -public: - /** - * Create a sub process and start it, calling proc(param). - */ - ThreadObject_MorphOS(OTTDThreadFunc proc, void *param, self_destruct) : - m_thr(0), self_destruct(self_destruct) - { - struct Task *parent; - - KPutStr("[OpenTTD] Create thread...\n"); - - parent = FindTask(NULL); - - /* Make sure main thread runs with sane priority */ - SetTaskPri(parent, 0); - - /* Things we'll pass down to the child by utilizing NP_StartupMsg */ - m_msg.func = proc; - m_msg.arg = param; - - m_replyport = CreateMsgPort(); - - if (m_replyport != NULL) { - struct Process *child; - - m_msg.msg.mn_Node.ln_Type = NT_MESSAGE; - m_msg.msg.mn_ReplyPort = m_replyport; - m_msg.msg.mn_Length = sizeof(struct OTTDThreadStartupMessage); - - child = CreateNewProcTags( - NP_CodeType, CODETYPE_PPC, - NP_Entry, ThreadObject_MorphOS::Proxy, - NP_StartupMsg, (IPTR)&m_msg, - NP_Priority, 5UL, - NP_Name, (IPTR)"OpenTTD Thread", - NP_PPCStackSize, 131072UL, - TAG_DONE); - - m_thr = (APTR) child; - - if (child != NULL) { - KPutStr("[OpenTTD] Child process launched.\n"); - } else { - KPutStr("[OpenTTD] Couldn't create child process. (constructors never fail, yeah!)\n"); - DeleteMsgPort(m_replyport); - } - } - } - - /* virtual */ ~ThreadObject_MorphOS() - { - } - - /* virtual */ bool Exit() - { - struct OTTDThreadStartupMessage *msg; - - /* You can only exit yourself */ - assert(IsCurrent()); - - KPutStr("[Child] Aborting...\n"); - - if (NewGetTaskAttrs(NULL, &msg, sizeof(struct OTTDThreadStartupMessage *), TASKINFOTYPE_STARTUPMSG, TAG_DONE) && msg != NULL) { - /* For now we terminate by throwing an error, gives much cleaner cleanup */ - throw OTTDThreadExitSignal(); - } - - return true; - } - - /* virtual */ void Join() - { - struct OTTDThreadStartupMessage *reply; - - /* You cannot join yourself */ - assert(!IsCurrent()); - - KPutStr("[OpenTTD] Join threads...\n"); - KPutStr("[OpenTTD] Wait for child to quit...\n"); - WaitPort(m_replyport); - - GetMsg(m_replyport); - DeleteMsgPort(m_replyport); - m_thr = 0; - } - - /* virtual */ bool IsCurrent() - { - return FindTask(NULL) == 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 Proxy() - { - struct Task *child = FindTask(NULL); - struct OTTDThreadStartupMessage *msg; - - /* Make sure, we don't block the parent. */ - SetTaskPri(child, -5); - - KPutStr("[Child] Progressing...\n"); - - if (NewGetTaskAttrs(NULL, &msg, sizeof(struct OTTDThreadStartupMessage *), TASKINFOTYPE_STARTUPMSG, TAG_DONE) && msg != NULL) { - try { - msg->func(msg->arg); - } catch(OTTDThreadExitSignal e) { - KPutStr("[Child] Returned to main()\n"); - } catch(...) { - NOT_REACHED(); - } - } - - /* Quit the child, exec.library will reply the startup msg internally. */ - KPutStr("[Child] Done.\n"); - - if (self_destruct) delete this; - } -}; - -/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread) -{ - ThreadObject *to = new ThreadObject_MorphOS(proc, param, thread == NULL); - if (thread != NULL) *thread = to; - return true; -} diff --git a/src/thread_none.cpp b/src/thread_none.cpp deleted file mode 100644 index 1893aebd2..000000000 --- a/src/thread_none.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* $Id$ */ - -/* - * This file is part of OpenTTD. - * OpenTTD 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, version 2. - * OpenTTD 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 OpenTTD. If not, see . - */ - -/** @file thread_none.cpp No-Threads-Available implementation of Threads */ - -#include "stdafx.h" -#include "thread.h" - -/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread) -{ - if (thread != NULL) *thread = NULL; - return false; -} - -/** Mutex that doesn't do locking because it ain't needed when there're no threads */ -class ThreadMutex_None : public ThreadMutex { -public: - virtual void BeginCritical() {} - virtual void EndCritical() {} -}; - -/* static */ ThreadMutex *ThreadMutex::New() -{ - return new ThreadMutex_None(); -} diff --git a/src/thread_os2.cpp b/src/thread_os2.cpp deleted file mode 100644 index 18122fe15..000000000 --- a/src/thread_os2.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* $Id$ */ - -/* - * This file is part of OpenTTD. - * OpenTTD 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, version 2. - * OpenTTD 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 OpenTTD. If not, see . - */ - -/** @file thread_os2.cpp OS/2 implementation of Threads. */ - -#include "stdafx.h" -#include "thread.h" - -#define INCL_DOS -#include -#include - -/** - * OS/2 version for ThreadObject. - */ -class ThreadObject_OS2 : public ThreadObject { -private: - TID thread; ///< System thread identifier. - OTTDThreadFunc proc; ///< External thread procedure. - void *param; ///< Parameter for the external thread procedure. - bool self_destruct; ///< Free ourselves when done? - -public: - /** - * Create a thread and start it, calling proc(param). - */ - ThreadObject_OS2(OTTDThreadFunc proc, void *param, bool self_destruct) : - thread(0), - proc(proc), - param(param), - self_destruct(self_destruct) - { - thread = _beginthread(stThreadProc, NULL, 32768, this); - } - - /* virtual */ bool Exit() - { - _endthread(); - return true; - } - - /* virtual */ void Join() - { - DosWaitThread(&this->thread, DCWW_WAIT); - this->thread = 0; - } -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) - { - ((ThreadObject_OS2 *)thr)->ThreadProc(); - } - - /** - * A new thread is created, and this function is called. Call the custom - * function of the creator of the thread. - */ - void ThreadProc() - { - /* Call the proc of the creator to continue this thread */ - try { - this->proc(this->param); - } catch (OTTDThreadExitSignal e) { - } catch (...) { - NOT_REACHED(); - } - - if (self_destruct) { - this->Exit(); - delete this; - } - } -}; - -/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread) -{ - ThreadObject *to = new ThreadObject_OS2(proc, param, thread == NULL); - if (thread != NULL) *thread = to; - return true; -} - -/** - * OS/2 version of ThreadMutex. - */ -class ThreadMutex_OS2 : public ThreadMutex { -private: - HMTX mutex; - -public: - ThreadMutex_OS2() - { - DosCreateMutexSem(NULL, &mutex, 0, FALSE); - } - - /* virtual */ ~ThreadMutex_OS2() - { - DosCloseMutexSem(mutex); - } - - /* virtual */ void BeginCritical() - { - DosRequestMutexSem(mutex, (unsigned long) SEM_INDEFINITE_WAIT); - } - - /* virtual */ void EndCritical() - { - DosReleaseMutexSem(mutex); - } -}; - -/* static */ ThreadMutex *ThreadMutex::New() -{ - return new ThreadMutex_OS2(); -} diff --git a/src/thread_pthread.cpp b/src/thread_pthread.cpp deleted file mode 100644 index 9edfd4e14..000000000 --- a/src/thread_pthread.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* $Id$ */ - -/* - * This file is part of OpenTTD. - * OpenTTD 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, version 2. - * OpenTTD 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 OpenTTD. If not, see . - */ - -/** @file thread_pthread.cpp POSIX pthread implementation of Threads. */ - -#include "stdafx.h" -#include "thread.h" -#include - -/** - * POSIX pthread version for ThreadObject. - */ -class ThreadObject_pthread : public ThreadObject { -private: - pthread_t thread; ///< System thread identifier. - OTTDThreadFunc proc; ///< External thread procedure. - void *param; ///< Parameter for the external thread procedure. - bool self_destruct; ///< Free ourselves when done? - -public: - /** - * Create a pthread and start it, calling proc(param). - */ - ThreadObject_pthread(OTTDThreadFunc proc, void *param, bool self_destruct) : - thread(0), - proc(proc), - param(param), - self_destruct(self_destruct) - { - pthread_create(&this->thread, NULL, &stThreadProc, this); - } - - /* virtual */ bool Exit() - { - assert(pthread_self() == this->thread); - /* For now we terminate by throwing an error, gives much cleaner cleanup */ - throw OTTDThreadExitSignal(); - } - - /* virtual */ void Join() - { - /* You cannot join yourself */ - assert(pthread_self() != this->thread); - pthread_join(this->thread, NULL); - this->thread = 0; - } -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) - { - ((ThreadObject_pthread *)thr)->ThreadProc(); - pthread_exit(NULL); - } - - /** - * A new thread is created, and this function is called. Call the custom - * function of the creator of the thread. - */ - void ThreadProc() - { - /* Call the proc of the creator to continue this thread */ - try { - this->proc(this->param); - } catch (OTTDThreadExitSignal e) { - } catch (...) { - NOT_REACHED(); - } - - if (self_destruct) { - pthread_detach(pthread_self()); - delete this; - } - } -}; - -/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread) -{ - ThreadObject *to = new ThreadObject_pthread(proc, param, thread == NULL); - if (thread != NULL) *thread = to; - return true; -} - -/** - * POSIX pthread version of ThreadMutex. - */ -class ThreadMutex_pthread : public ThreadMutex { -private: - pthread_mutex_t mutex; - -public: - ThreadMutex_pthread() - { - pthread_mutex_init(&this->mutex, NULL); - } - - /* virtual */ ~ThreadMutex_pthread() - { - pthread_mutex_destroy(&this->mutex); - } - - /* virtual */ void BeginCritical() - { - pthread_mutex_lock(&this->mutex); - } - - /* virtual */ void EndCritical() - { - pthread_mutex_unlock(&this->mutex); - } -}; - -/* static */ ThreadMutex *ThreadMutex::New() -{ - return new ThreadMutex_pthread(); -} diff --git a/src/thread_win32.cpp b/src/thread_win32.cpp deleted file mode 100644 index 8b1d11544..000000000 --- a/src/thread_win32.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* $Id$ */ - -/* - * This file is part of OpenTTD. - * OpenTTD 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, version 2. - * OpenTTD 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 OpenTTD. If not, see . - */ - -/** @file thread_win32.cpp Win32 thread implementation of Threads. */ - -#include "stdafx.h" -#include "thread.h" -#include "debug.h" -#include "core/alloc_func.hpp" -#include -#include -#include - -/** - * Win32 thread version for ThreadObject. - */ -class ThreadObject_Win32 : public ThreadObject { -private: - HANDLE thread; ///< System thread identifier. - uint id; ///< Thread identifier. - OTTDThreadFunc proc; ///< External thread procedure. - void *param; ///< Parameter for the external thread procedure. - bool self_destruct; ///< Free ourselves when done? - -public: - /** - * Create a win32 thread and start it, calling proc(param). - */ - ThreadObject_Win32(OTTDThreadFunc proc, void *param, bool self_destruct) : - thread(NULL), - id(0), - proc(proc), - param(param), - self_destruct(self_destruct) - { - this->thread = (HANDLE)_beginthreadex(NULL, 0, &stThreadProc, this, CREATE_SUSPENDED, &this->id); - if (this->thread == NULL) return; - ResumeThread(this->thread); - } - - /* virtual */ ~ThreadObject_Win32() - { - if (this->thread != NULL) { - CloseHandle(this->thread); - this->thread = NULL; - } - } - - /* virtual */ bool Exit() - { - assert(GetCurrentThreadId() == this->id); - /* For now we terminate by throwing an error, gives much cleaner cleanup */ - throw OTTDThreadExitSignal(); - } - - /* virtual */ void Join() - { - /* You cannot join yourself */ - assert(GetCurrentThreadId() != this->id); - WaitForSingleObject(this->thread, INFINITE); - } - -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) - { - ((ThreadObject_Win32 *)thr)->ThreadProc(); - return 0; - } - - /** - * A new thread is created, and this function is called. Call the custom - * function of the creator of the thread. - */ - void ThreadProc() - { - try { - this->proc(this->param); - } catch (OTTDThreadExitSignal) { - } catch (...) { - NOT_REACHED(); - } - - if (self_destruct) delete this; - } -}; - -/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread) -{ - ThreadObject *to = new ThreadObject_Win32(proc, param, thread == NULL); - if (thread != NULL) *thread = to; - return true; -} - -/** - * Win32 thread version of ThreadMutex. - */ -class ThreadMutex_Win32 : public ThreadMutex { -private: - CRITICAL_SECTION critical_section; - -public: - ThreadMutex_Win32() - { - InitializeCriticalSection(&this->critical_section); - } - - /* virtual */ ~ThreadMutex_Win32() - { - DeleteCriticalSection(&this->critical_section); - } - - /* virtual */ void BeginCritical() - { - EnterCriticalSection(&this->critical_section); - } - - /* virtual */ void EndCritical() - { - LeaveCriticalSection(&this->critical_section); - } -}; - -/* static */ ThreadMutex *ThreadMutex::New() -{ - return new ThreadMutex_Win32(); -} -- cgit v1.2.3-54-g00ecf