/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2005, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
*
* ---
*
- * See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
- * related information and legal notices. It is expected that any future
- * projects/authors will amend these files as needed.
+ * See files README, COPYING and CREDITS in the root of the source
+ * tree for related information and legal notices. It is expected
+ * that future projects/authors will amend these files as needed.
*
* ---
*
* Known contributors to this file:
* Doug Hay, 1998
* Steve McClure, 1998
+ * Ron Koenderink, 2004-2005
*/
/*
* WIN32 has a full pre-emptive threading environment. But Empire can
* not handle pre-emptive threading. Thus, we will use the threads,
* but limit the preemption using a Mutex semaphore.
- *
*/
+#include <config.h>
+
+#include <errno.h>
+#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
-#include "misc.h"
-#include "empthread.h"
-#include "prototypes.h"
-
-#if defined(_WIN32) && defined(_EMPTH_WIN32)
+#include <time.h>
#define WIN32
#include <winsock2.h>
#undef NS_ALL
#include <windows.h>
#include <process.h>
+#include "misc.h"
+#include "empthread.h"
+#include "prototypes.h"
#define loc_MIN_THREAD_STACK 16384
/************************
* loc_FreeThreadInfo
- *
*/
static void
loc_FreeThreadInfo(empth_t *pThread)
* info, and the thread owns the MUTEX sem.
*/
static void
-loc_RunThisThread()
+loc_RunThisThread(void)
{
empth_t *pThread = TlsGetValue(dwTLSIndex);
* This thread was running. It no longer wants to.
*/
static void
-loc_BlockThisThread()
+loc_BlockThisThread(void)
{
empth_t *pThread = TlsGetValue(dwTLSIndex);
static BOOL
loc_Exit_Handler(DWORD fdwCtrlType)
{
- switch (fdwCtrlType)
- {
+ switch (fdwCtrlType) {
case CTRL_C_EVENT:
case CTRL_CLOSE_EVENT:
case CTRL_BREAK_EVENT:
}
}
-/************************
- * empth_request_shutdown
- *
- * This wakes up the main thread so shutdown can proceed.
- * This is done by signalling hShutdownEvent.
- */
-void
-empth_request_shutdown(void)
-{
- SetEvent(hShutdownEvent);
-}
-
-/************************
- * loc_BlockMainThread
- *
- * This blocks up the main thread. loc_WakeupMainThread() is used
- * wakeup the main so shutdown can proceed.
- */
-static void
-loc_BlockMainThread(void)
-{
- /* Get the MUTEX semaphore, wait the number of MS */
- WaitForSingleObject(hShutdownEvent, INFINITE);
-}
-
/************************
* empth_threadMain
*
* This is the main line of each thread.
* This is really a static local func....
*/
-void
+static void
empth_threadMain(void *pvData)
{
time_t now;
/* seed the rand() function */
time(&now);
- srand(now ^ (unsigned int)pThread);
+ srand(now ^ (unsigned)pThread);
/* Switch to this thread context */
loc_RunThisThread();
/* Initally unowned. */
hThreadMutex = CreateMutex(NULL, FALSE, NULL);
if (!hThreadMutex) {
- logerror("Failed to create mutex %d", GetLastError());
+ logerror("Failed to create mutex %lu", GetLastError());
return 0;
}
/* Automatic state reset. */
hThreadStartEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!hThreadStartEvent) {
- logerror("Failed to create start event %d", GetLastError());
+ logerror("Failed to create start event %lu", GetLastError());
return 0;
}
/* Manual reset */
hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!hShutdownEvent) {
- logerror("Failed to create shutdown event %d", GetLastError());
+ logerror("Failed to create shutdown event %lu", GetLastError());
return 0;
}
SetConsoleCtrlHandler((PHANDLER_ROUTINE)loc_Exit_Handler, TRUE);
pThread = malloc(sizeof(*pThread));
if (!pThread) {
- logerror("not enough memory to create thread: %s (%s)", name,
- desc);
+ logerror("not enough memory to create thread: %s (%s)",
+ name, desc);
return NULL;
}
memset(pThread, 0, sizeof(*pThread));
pThread->ulThreadID = _beginthread(empth_threadMain, size, pThread);
if (pThread->ulThreadID == -1) {
- logerror("can not create thread: %s (%s): %s", name, desc,
- strerror(errno));
+ logerror("can not create thread: %s (%s): %s",
+ name, desc, strerror(errno));
goto bad;
}
loc_debug("new thread id is %ld", pThread->ulThreadID);
+ empth_yield();
return pThread;
bad:
{
empth_t *pThread = TlsGetValue(dwTLSIndex);
- loc_BlockThisThread();
-
loc_debug("empth_exit");
+ loc_BlockThisThread();
- if (pThread->bMainThread) {
- loc_BlockMainThread();
- loc_RunThisThread();
- shutdwn(0);
- } else {
- TlsSetValue(dwTLSIndex, NULL);
- loc_FreeThreadInfo(pThread);
- _endthread();
- }
+ TlsSetValue(dwTLSIndex, NULL);
+ loc_FreeThreadInfo(pThread);
+ _endthread();
}
/************************
loc_RunThisThread();
}
-/************************
- * empth_alarm
- */
-void
-empth_alarm(int sig)
-{
- empth_t *pThread = TlsGetValue(dwTLSIndex);
-
- loc_debug("got alarm signal %d", sig);
-
- /* Let it run if it is blocked like... */
- SetEvent(pThread->hThreadEvent);
-}
-
/************************
* empth_wakeup
*
loc_RunThisThread();
}
+/************************
+ * empth_request_shutdown
+ *
+ * This wakes up empth_wait_for_signal() so shutdown can proceed.
+ * This is done by signalling hShutdownEvent.
+ */
+void
+empth_request_shutdown(void)
+{
+ SetEvent(hShutdownEvent);
+}
+
+int
+empth_wait_for_signal(void)
+{
+ loc_BlockThisThread();
+
+ /* Get the MUTEX semaphore, wait the number of MS */
+ WaitForSingleObject(hShutdownEvent, INFINITE);
+
+ loc_RunThisThread();
+ return 0;
+}
/************************
* empth_sem_create
loc_RunThisThread();
}
-
-#endif /* _WIN32 */