Changeset - r12839:daeca5b0e6db
[Not reviewed]
master
6 12 6
rubidium - 15 years ago 2009-09-01 10:07:22
rubidium@openttd.org
(svn r17339) -Codechange: move thread related files to their own directory (like done for video, music, sound, etc)
24 files changed with 740 insertions and 730 deletions:
0 comments (0 inline, 0 general)
Makefile.bundle.in
Show inline comments
 
@@ -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:
projects/openttd_vs80.vcproj
Show inline comments
 
@@ -736,10 +736,6 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\thread_win32.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tile_map.cpp"
 
				>
 
			</File>
 
@@ -1504,10 +1500,6 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\thread.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tile_cmd.h"
 
				>
 
			</File>
 
@@ -3581,6 +3573,18 @@
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="Threading"
 
			>
 
			<File
 
				RelativePath=".\..\src\thread\thread.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\thread\thread_win32.cpp"
 
				>
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="64-bit Specific Files"
 
			Filter="asm"
 
			>
projects/openttd_vs90.vcproj
Show inline comments
 
@@ -733,10 +733,6 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\thread_win32.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tile_map.cpp"
 
				>
 
			</File>
 
@@ -1501,10 +1497,6 @@
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\thread.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tile_cmd.h"
 
				>
 
			</File>
 
@@ -3578,6 +3570,18 @@
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="Threading"
 
			>
 
			<File
 
				RelativePath=".\..\src\thread\thread.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\thread\thread_win32.cpp"
 
				>
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="64-bit Specific Files"
 
			Filter="asm"
 
			>
source.list
Show inline comments
 
@@ -76,23 +76,6 @@ strings.cpp
 
subsidy.cpp
 
texteff.cpp
 
tgp.cpp
 
#if HAVE_THREAD
 
	#if WIN32
 
		thread_win32.cpp
 
	#else
 
		#if OS2
 
			thread_os2.cpp
 
		#else
 
			#if MORPHOS
 
				thread_morphos.cpp
 
			#else
 
				thread_pthread.cpp
 
			#end
 
		#end
 
	#end
 
#else
 
	thread_none.cpp
 
#end
 
tile_map.cpp
 
#if WIN32
 
#else
 
@@ -304,7 +287,6 @@ terraform_gui.h
 
textbuf_gui.h
 
texteff.hpp
 
tgp.h
 
thread.h
 
tile_cmd.h
 
tile_type.h
 
tilehighlight_func.h
 
@@ -940,3 +922,23 @@ sound/null_s.cpp
 
		os/macosx/splash.cpp
 
	#end
 
#end
 

	
 
# Threading
 
thread/thread.h
 
#if HAVE_THREAD
 
	#if WIN32
 
		thread/thread_win32.cpp
 
	#else
 
		#if OS2
 
			thread/thread_os2.cpp
 
		#else
 
			#if MORPHOS
 
				thread/thread_morphos.cpp
 
			#else
 
				thread/thread_pthread.cpp
 
			#end
 
		#end
 
	#end
 
#else
 
	thread/thread_none.cpp
 
#end
src/genworld.cpp
Show inline comments
 
@@ -14,7 +14,7 @@
 
#include "landscape.h"
 
#include "company_func.h"
 
#include "variables.h"
 
#include "thread.h"
 
#include "thread/thread.h"
 
#include "command_func.h"
 
#include "genworld.h"
 
#include "gfxinit.h"
src/genworld_gui.cpp
Show inline comments
 
@@ -32,7 +32,7 @@
 
#include "landscape_type.h"
 
#include "querystring_gui.h"
 
#include "town.h"
 
#include "thread.h"
 
#include "thread/thread.h"
 
#include "settings_func.h"
 

	
 
#include "table/strings.h"
src/gfx.cpp
Show inline comments
 
@@ -26,7 +26,7 @@
 
#include "landscape_type.h"
 
#include "network/network_func.h"
 
#include "core/smallvec_type.hpp"
 
#include "thread.h"
 
#include "thread/thread.h"
 
#include "window_func.h"
 

	
 
#include "table/palettes.h"
src/network/core/tcp_connect.cpp
Show inline comments
 
@@ -16,7 +16,7 @@
 
#include "../../stdafx.h"
 
#include "../../debug.h"
 
#include "../../core/smallvec_type.hpp"
 
#include "../../thread.h"
 
#include "../../thread/thread.h"
 

	
 
#include "tcp.h"
 

	
src/network/network_gamelist.cpp
Show inline comments
 
@@ -17,7 +17,7 @@
 
#include "../stdafx.h"
 
#include "../debug.h"
 
#include "../core/alloc_func.hpp"
 
#include "../thread.h"
 
#include "../thread/thread.h"
 
#include "../string_func.h"
 
#include "network_internal.h"
 
#include "network_udp.h"
src/network/network_udp.cpp
Show inline comments
 
@@ -28,7 +28,7 @@
 
#include "../string_func.h"
 
#include "../company_base.h"
 
#include "../settings_type.h"
 
#include "../thread.h"
 
#include "../thread/thread.h"
 
#include "../rev.h"
 

	
 
#include "core/udp.h"
src/openttd.cpp
Show inline comments
 
@@ -60,7 +60,7 @@
 
#include "elrail_func.h"
 
#include "rev.h"
 
#include "highscore.h"
 
#include "thread.h"
 
#include "thread/thread.h"
 
#include "station_base.h"
 

	
 
#include "newgrf_commons.h"
src/saveload/saveload.cpp
Show inline comments
 
@@ -24,7 +24,7 @@
 
#include "../openttd.h"
 
#include "../debug.h"
 
#include "../station_base.h"
 
#include "../thread.h"
 
#include "../thread/thread.h"
 
#include "../town.h"
 
#include "../network/network.h"
 
#include "../variables.h"
src/thread.h
Show inline comments
 
deleted file
src/thread/thread.h
Show inline comments
 
new file 100644
 
/* $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 <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @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 */
src/thread/thread_morphos.cpp
Show inline comments
 
new file 100644
 
/* $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 <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file thread_morphos.cpp MorphOS implementation of Threads. */
 

	
 
#include "../stdafx.h"
 
#include "thread.h"
 
#include "../debug.h"
 
#include "../core/alloc_func.hpp"
 
#include <stdlib.h>
 
#include <unistd.h>
 

	
 
#include <exec/types.h>
 
#include <exec/rawfmt.h>
 
#include <dos/dostags.h>
 

	
 
#include <proto/dos.h>
 
#include <proto/exec.h>
 

	
 
/**
 
 *  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;
 
}
src/thread/thread_none.cpp
Show inline comments
 
new file 100644
 
/* $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 <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @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();
 
}
src/thread/thread_os2.cpp
Show inline comments
 
new file 100644
 
/* $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 <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file thread_os2.cpp OS/2 implementation of Threads. */
 

	
 
#include "../stdafx.h"
 
#include "thread.h"
 

	
 
#define INCL_DOS
 
#include <os2.h>
 
#include <process.h>
 

	
 
/**
 
 * 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();
 
}
src/thread/thread_pthread.cpp
Show inline comments
 
new file 100644
 
/* $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 <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file thread_pthread.cpp POSIX pthread implementation of Threads. */
 

	
 
#include "../stdafx.h"
 
#include "thread.h"
 
#include <pthread.h>
 

	
 
/**
 
 * 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();
 
}
src/thread/thread_win32.cpp
Show inline comments
 
new file 100644
 
/* $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 <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @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>
 

	
 
/**
 
 * 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();
 
}
src/thread_morphos.cpp
Show inline comments
 
deleted file
src/thread_none.cpp
Show inline comments
 
deleted file
src/thread_os2.cpp
Show inline comments
 
deleted file
src/thread_pthread.cpp
Show inline comments
 
deleted file
src/thread_win32.cpp
Show inline comments
 
deleted file
0 comments (0 inline, 0 general)