Esempio n. 1
0
	/**
	 * 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;
	}
Esempio n. 2
0
	/* 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;
	}
Esempio n. 3
0
int vdebugf(const char *fmt, va_list args) {
	char buffer[256];

	int retval = vsnprintf(buffer, sizeof(buffer), fmt, args);
	KPutStr((CONST_STRPTR)buffer);

	return retval;
}
Esempio n. 4
0
	/**
	 * 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);
			}
		}
	}
Esempio n. 5
0
	/* 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;
	}
Esempio n. 6
0
int puts(const char *str) {
	KPutStr((CONST_STRPTR)str);
	return strlen(str);
}