src/thread_morphos.cpp
author truebrain
Mon, 30 Jun 2008 21:31:23 +0000
branchnoai
changeset 11111 1b984dab8cec
parent 11095 a0da321a39b3
permissions -rw-r--r--
(svn r13669) [NoAI] -Fix: allow clients only to join non-AI controlled companies in multiplayer
10455
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
     1
/* $Id$ */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
     2
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
     3
/** @file thread_morphos.cpp MorphOS implementation of Threads. */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
     4
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
     5
#include "stdafx.h"
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
     6
#include "thread.h"
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
     7
#include "debug.h"
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
     8
#include "core/alloc_func.hpp"
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
     9
#include <stdlib.h>
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    10
#include <unistd.h>
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    11
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    12
#include <exec/types.h>
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    13
#include <exec/rawfmt.h>
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    14
#include <dos/dostags.h>
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    15
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    16
#include <proto/dos.h>
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    17
#include <proto/exec.h>
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    18
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    19
/**
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    20
 *  avoid name clashes with MorphOS API functions
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    21
 */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    22
#undef Exit
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    23
#undef Wait
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    24
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    25
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    26
/**
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    27
 *  NOTE: this code heavily depends on latest libnix updates. So make
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    28
 *        sure you link with new stuff which supports semaphore locking of
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    29
 *        the IO resources, else it will just go foobar.
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    30
 */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    31
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    32
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    33
struct OTTDThreadStartupMessage {
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    34
	struct Message msg;  ///< standard exec.library message (MUST be the first thing in the message struct!)
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    35
	OTTDThreadFunc func; ///< function the thread will execute
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    36
	void *arg;           ///< functions arguments for the thread function
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    37
};
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    38
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    39
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    40
/**
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    41
 *  Default OpenTTD STDIO/ERR debug output is not very useful for this, so we
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    42
 *  utilize serial/ramdebug instead.
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    43
 */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    44
#ifndef NO_DEBUG_MESSAGES
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    45
void KPutStr(CONST_STRPTR format)
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    46
{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    47
	RawDoFmt(format, NULL, (void (*)())RAWFMTFUNC_SERIAL, NULL);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    48
}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    49
#else
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    50
#define KPutStr(x)
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    51
#endif
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    52
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    53
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    54
/**
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    55
 * MorphOS version for ThreadObject.
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    56
 */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    57
class ThreadObject_MorphOS : public ThreadObject {
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    58
private:
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    59
	APTR m_thr;                  ///< System thread identifier.
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    60
	struct MsgPort *m_replyport;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    61
	struct OTTDThreadStartupMessage m_msg;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    62
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    63
public:
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    64
	/**
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    65
	 * Create a sub process and start it, calling proc(param).
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    66
	 */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    67
	ThreadObject_MorphOS(OTTDThreadFunc proc, void *param) : m_thr(0)
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    68
	{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    69
		struct Task *parent;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    70
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    71
		KPutStr("[OpenTTD] Create thread...\n");
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    72
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    73
		parent = FindTask(NULL);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    74
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    75
		/* Make sure main thread runs with sane priority */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    76
		SetTaskPri(parent, 0);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    77
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    78
		/* Things we'll pass down to the child by utilizing NP_StartupMsg */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    79
		m_msg.func = proc;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    80
		m_msg.arg  = param;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    81
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    82
		m_replyport = CreateMsgPort();
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    83
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    84
		if (m_replyport != NULL) {
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    85
			struct Process *child;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    86
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    87
			m_msg.msg.mn_Node.ln_Type = NT_MESSAGE;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    88
			m_msg.msg.mn_ReplyPort    = m_replyport;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    89
			m_msg.msg.mn_Length       = sizeof(struct OTTDThreadStartupMessage);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    90
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    91
			child = CreateNewProcTags(
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    92
				NP_CodeType,     CODETYPE_PPC,
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    93
				NP_Entry,        ThreadObject_MorphOS::Proxy,
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    94
				NP_StartupMsg,   (IPTR)&m_msg,
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    95
				NP_Priority,     5UL,
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    96
				NP_Name,         (IPTR)"OpenTTD Thread",
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    97
				NP_PPCStackSize, 131072UL,
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    98
				TAG_DONE);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
    99
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   100
			m_thr = (APTR) child;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   101
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   102
			if (child != NULL) {
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   103
				KPutStr("[OpenTTD] Child process launched.\n");
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   104
			} else {
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   105
				KPutStr("[OpenTTD] Couldn't create child process. (constructors never fail, yeah!)\n");
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   106
				DeleteMsgPort(m_replyport);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   107
			}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   108
		}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   109
	}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   110
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   111
	/**
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   112
	 * Create a thread and attach current thread to it.
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   113
	 */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   114
	ThreadObject_MorphOS() : m_thr(0)
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   115
	{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   116
		m_thr = FindTask(NULL);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   117
	}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   118
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   119
	/* virtual */ ~ThreadObject_MorphOS()
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   120
	{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   121
	}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   122
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   123
	/* virtual */ bool IsRunning()
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   124
	{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   125
		return m_thr != 0;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   126
	}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   127
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   128
	/* virtual */ bool WaitForStop()
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   129
	{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   130
		/* You can't wait on yourself */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   131
		assert(!IsCurrent());
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   132
		/* If the thread is not running, waiting is over */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   133
		if (!IsRunning()) return true;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   134
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   135
		WaitPort(m_replyport);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   136
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   137
		GetMsg(m_replyport);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   138
		DeleteMsgPort(m_replyport);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   139
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   140
		return true;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   141
	}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   142
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   143
	/* virtual */ bool Exit()
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   144
	{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   145
		struct OTTDThreadStartupMessage *msg;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   146
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   147
		/* You can only exit yourself */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   148
		assert(IsCurrent());
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   149
		/* If the thread is not running, we are already closed */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   150
		if (!IsRunning()) return false;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   151
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   152
		KPutStr("[Child] Aborting...\n");
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   153
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   154
		if (NewGetTaskAttrs(NULL, &msg, sizeof(struct OTTDThreadStartupMessage *), TASKINFOTYPE_STARTUPMSG, TAG_DONE) && msg != NULL) {
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   155
			/* For now we terminate by throwing an error, gives much cleaner cleanup */
11095
a0da321a39b3 (svn r13652) [NoAI] -Fix: throw thread-exit-signal with a custom class, not with the value '0', which might be captured by a lot of other layers
truebrain
parents: 10867
diff changeset
   156
			throw OTTDThreadExitSignal();
10455
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   157
		}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   158
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   159
		return true;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   160
	}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   161
10867
5de2923d6e59 (svn r13418) [NoAI] -Sync: with trunk r13380:13417.
rubidium
parents: 10455
diff changeset
   162
	/* virtual */ void Join()
10455
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   163
	{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   164
		struct OTTDThreadStartupMessage *reply;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   165
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   166
		/* You cannot join yourself */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   167
		assert(!IsCurrent());
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   168
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   169
		KPutStr("[OpenTTD] Join threads...\n");
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   170
		KPutStr("[OpenTTD] Wait for child to quit...\n");
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   171
		WaitPort(m_replyport);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   172
10867
5de2923d6e59 (svn r13418) [NoAI] -Sync: with trunk r13380:13417.
rubidium
parents: 10455
diff changeset
   173
		GetMsg(m_replyport);
10455
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   174
		DeleteMsgPort(m_replyport);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   175
		m_thr = 0;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   176
	}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   177
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   178
	/* virtual */ bool IsCurrent()
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   179
	{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   180
		return FindTask(NULL) == m_thr;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   181
	}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   182
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   183
	/* virtual */ uint GetId()
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   184
	{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   185
		return (uint)m_thr;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   186
	}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   187
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   188
private:
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   189
	/**
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   190
	 * On thread creation, this function is called, which calls the real startup
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   191
	 *  function. This to get back into the correct instance again.
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   192
	 */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   193
	static void Proxy(void)
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   194
	{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   195
		struct Task *child = FindTask(NULL);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   196
		struct OTTDThreadStartupMessage *msg;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   197
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   198
		/* Make sure, we don't block the parent. */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   199
		SetTaskPri(child, -5);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   200
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   201
		KPutStr("[Child] Progressing...\n");
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   202
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   203
		if (NewGetTaskAttrs(NULL, &msg, sizeof(struct OTTDThreadStartupMessage *), TASKINFOTYPE_STARTUPMSG, TAG_DONE) && msg != NULL) {
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   204
			try {
10867
5de2923d6e59 (svn r13418) [NoAI] -Sync: with trunk r13380:13417.
rubidium
parents: 10455
diff changeset
   205
				msg->func(msg->arg);
11095
a0da321a39b3 (svn r13652) [NoAI] -Fix: throw thread-exit-signal with a custom class, not with the value '0', which might be captured by a lot of other layers
truebrain
parents: 10867
diff changeset
   206
			} catch(OTTDThreadExitSignal e) {
a0da321a39b3 (svn r13652) [NoAI] -Fix: throw thread-exit-signal with a custom class, not with the value '0', which might be captured by a lot of other layers
truebrain
parents: 10867
diff changeset
   207
				KPutStr("[Child] Returned to main()\n");
10455
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   208
			} catch(...) {
11095
a0da321a39b3 (svn r13652) [NoAI] -Fix: throw thread-exit-signal with a custom class, not with the value '0', which might be captured by a lot of other layers
truebrain
parents: 10867
diff changeset
   209
				NOT_REACHED();
10455
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   210
			}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   211
		}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   212
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   213
		/*  Quit the child, exec.library will reply the startup msg internally. */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   214
		KPutStr("[Child] Done.\n");
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   215
	}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   216
};
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   217
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   218
/* static */ ThreadObject *ThreadObject::New(OTTDThreadFunc proc, void *param)
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   219
{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   220
	return new ThreadObject_MorphOS(proc, param);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   221
}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   222
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   223
/* static */ ThreadObject *ThreadObject::AttachCurrent()
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   224
{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   225
	return new ThreadObject_MorphOS();
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   226
}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   227
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   228
/* static */ uint ThreadObject::CurrentId()
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   229
{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   230
	return (uint) FindTask(NULL);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   231
}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   232
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   233
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   234
/**
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   235
 * MorphOS version of ThreadSemaphore.
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   236
 */
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   237
class ThreadSemaphore_MorphOS : public ThreadSemaphore {
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   238
private:
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   239
	struct SignalSemaphore m_sem;
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   240
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   241
public:
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   242
	ThreadSemaphore_MorphOS()
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   243
	{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   244
		InitSemaphore(&m_sem);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   245
	}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   246
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   247
	/* virtual */ ~ThreadSemaphore_MorphOS()
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   248
	{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   249
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   250
	}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   251
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   252
	/* virtual */ void Set()
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   253
	{
10867
5de2923d6e59 (svn r13418) [NoAI] -Sync: with trunk r13380:13417.
rubidium
parents: 10455
diff changeset
   254
		/* Check if semaphore count is really important there. */
10455
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   255
		ReleaseSemaphore(&m_sem);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   256
	}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   257
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   258
	/* virtual */ void Wait()
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   259
	{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   260
		ObtainSemaphore(&m_sem);
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   261
	}
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   262
};
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   263
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   264
/* static */ ThreadSemaphore *ThreadSemaphore::New()
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   265
{
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   266
	return new ThreadSemaphore_MorphOS();
22c441f5adf9 (svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
diff changeset
   267
}