]> git.pond.sub.org Git - empserver/blobdiff - src/lib/empthread/ntthread.c
Update copyright notice
[empserver] / src / lib / empthread / ntthread.c
index e7d4886646a30e45e81311b1590b4b7b16544c05..b1c66b2bc34114d4542ccb6373d8a3c33e3ef34b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *  Copyright (C) 1986-2009, Dave Pare, Jeff Bailey, Thomas Ruschak,
  *                           Ken Stevens, Steve McClure
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -26,7 +26,7 @@
  *  ---
  *
  *  ntthread.c: Interface from Empire threads to Windows NT threads
- * 
+ *
  *  Known contributors to this file:
  *     Doug Hay, 1998
  *     Steve McClure, 1998
@@ -73,7 +73,7 @@
 struct loc_Thread {
 
     /* The thread name, passed in at create time. */
-    char szName[17];
+    char *szName;
 
     /* True if this is the main line, and not a real thread. */
     BOOL bMainThread;
@@ -135,7 +135,7 @@ struct loc_Thread {
  *
  */
 struct loc_RWLock {
-    char name[17];     /* The thread name, passed in at create time. */
+    char *name;                /* The lock name, passed in at create time. */
     HANDLE can_read;   /* Manual event -- allows read locks */
     HANDLE can_write;  /* Auto-reset event -- allows write locks */
     int nread;         /* number of active readers */
@@ -224,6 +224,8 @@ loc_FreeThreadInfo(empth_t *pThread)
     if (pThread) {
        if (pThread->hThreadEvent)
            CloseHandle(pThread->hThreadEvent);
+       if (pThread->szName != NULL)
+           free(pThread->szName);
        memset(pThread, 0, sizeof(*pThread));
        free(pThread);
     }
@@ -302,12 +304,12 @@ loc_BlockThisThread(void)
 static BOOL WINAPI
 loc_Exit_Handler(DWORD fdwCtrlType)
 {
-    switch (fdwCtrlType) { 
+    switch (fdwCtrlType) {
         case CTRL_C_EVENT:
         case CTRL_CLOSE_EVENT:
-        case CTRL_BREAK_EVENT: 
-        case CTRL_LOGOFF_EVENT: 
-        case CTRL_SHUTDOWN_EVENT: 
+        case CTRL_BREAK_EVENT:
+        case CTRL_LOGOFF_EVENT:
+        case CTRL_SHUTDOWN_EVENT:
            empth_request_shutdown();
             return TRUE;
         default:
@@ -403,7 +405,7 @@ empth_init(void **ctx_ptr, int flags)
     }
     memset(pThread, 0, sizeof(*pThread));
 
-    strncpy(pThread->szName, "Main", sizeof(pThread->szName) - 1);
+    pThread->szName = strdup("Main");
     pThread->ulThreadID = GetCurrentThreadId();
     pThread->bMainThread = TRUE;
 
@@ -446,7 +448,7 @@ empth_create(void (*entry)(void *), int size, int flags,
     }
     memset(pThread, 0, sizeof(*pThread));
 
-    strncpy(pThread->szName, name, sizeof(pThread->szName) - 1);
+    pThread->szName = strdup(name);
     pThread->pvUserData = ud;
     pThread->pfnEntry = entry;
     pThread->bMainThread = FALSE;
@@ -458,7 +460,7 @@ empth_create(void (*entry)(void *), int size, int flags,
        size = loc_MIN_THREAD_STACK;
 
     pThread->ulThreadID = _beginthread(empth_threadMain, size, pThread);
-    if (pThread->ulThreadID == 1L) {
+    if (pThread->ulThreadID == 1L || pThread->ulThreadID == 0L) {
        logerror("can not create thread: %s: %s", name, strerror(errno));
        goto bad;
     }
@@ -490,9 +492,9 @@ empth_self(void)
  * empth_name
  */
 char *
-empth_name(void)
+empth_name(empth_t *thread)
 {
-    return empth_self()->szName;
+    return thread->szName;
 }
 
 /************************
@@ -500,11 +502,11 @@ empth_name(void)
  * Set the thread name
  */
 void
-empth_set_name(char *name)
+empth_set_name(empth_t *thread, char *name)
 {
-    empth_t *pThread = TlsGetValue(dwTLSIndex);
-
-    strncpy(pThread->szName, name, sizeof(pThread->szName) - 1);
+    if (thread->szName != NULL)
+       free(thread->szName);
+    thread->szName = strdup(name);
 }
 
 /************************
@@ -558,12 +560,15 @@ empth_terminate(empth_t *pThread)
  *
  * This would be one of the main functions used within gen\io.c
  */
-void
-empth_select(int fd, int flags)
+int
+empth_select(int fd, int flags, struct timeval *timeout)
 {
     int handle;
     WSAEVENT hEventObject[2];
+    long events;
+    DWORD result, msec;
     empth_t *pThread = TlsGetValue(dwTLSIndex);
+    int res;
 
     loc_debug("%s select on %d",
              flags == EMPTH_FD_READ ? "read" : "write", fd);
@@ -575,22 +580,37 @@ empth_select(int fd, int flags)
     handle = posix_fd2socket(fd);
     CANT_HAPPEN(handle < 0);
 
-    if (flags == EMPTH_FD_READ)
-       WSAEventSelect(handle, hEventObject[0], FD_READ | FD_ACCEPT | FD_CLOSE);
-    else if (flags == EMPTH_FD_WRITE)
-       WSAEventSelect(handle, hEventObject[0], FD_WRITE | FD_CLOSE);
-    else {
-       logerror("bad flag %d passed to empth_select", flags);
-       empth_exit();
+    events = 0;
+    if (flags & EMPTH_FD_READ)
+       events |= FD_READ | FD_ACCEPT | FD_CLOSE;
+    if (flags & EMPTH_FD_WRITE)
+       events |= FD_WRITE | FD_CLOSE;
+    WSAEventSelect(handle, hEventObject[0], events);
+
+    if (timeout)
+       msec = timeout->tv_sec * 1000L + timeout->tv_usec / 1000L;
+    else
+       msec = WSA_INFINITE;
+    result = WSAWaitForMultipleEvents(2, hEventObject, FALSE, msec, FALSE);
+
+    switch (result) {
+    case WSA_WAIT_TIMEOUT:
+       res = 0;
+       break;
+    case WSA_WAIT_FAILED:
+       errno = WSAGetLastError();
+       res = -1;
+       break;
+    default:
+       res = 1;
     }
 
-    WSAWaitForMultipleEvents(2, hEventObject, FALSE, WSA_INFINITE, FALSE);
-
     WSAEventSelect(handle, hEventObject[0], 0);
 
     WSACloseEvent(hEventObject[0]);
 
     loc_RunThisThread(NULL);
+    return res;
 }
 
 /************************
@@ -615,11 +635,11 @@ empth_wakeup(empth_t *pThread)
 int
 empth_sleep(time_t until)
 {
-    long lSec;
+    long lSec = until - time(0) > 0 ? until - time(0) : 0;
     empth_t *pThread = TlsGetValue(dwTLSIndex);
     int iReturn = 0;
 
-    while (!iReturn && ((lSec = until - time(0)) > 0)) {
+    do {
        loc_BlockThisThread();
        loc_debug("going to sleep %ld sec", lSec);
 
@@ -629,7 +649,8 @@ empth_sleep(time_t until)
 
        loc_debug("sleep done. Waiting to run.");
        loc_RunThisThread(NULL);
-    }
+    } while (!iReturn && ((lSec = until - time(0)) > 0));
+
     return iReturn;
 }
 
@@ -663,11 +684,12 @@ empth_rwlock_create(char *name)
        return NULL;
 
     memset(rwlock, 0, sizeof(*rwlock));
-    strncpy(rwlock->name, name, sizeof(rwlock->name) - 1);
+    rwlock->name = strdup(name);
 
     if ((rwlock->can_read = CreateEvent(NULL, TRUE, TRUE, NULL)) == NULL) {
        logerror("rwlock_create: failed to create reader event %s at %s:%d",
            name, __FILE__, __LINE__);
+       free(rwlock->name);
        free(rwlock);
        return NULL;
     }
@@ -675,6 +697,7 @@ empth_rwlock_create(char *name)
     if ((rwlock->can_write = CreateEvent(NULL, FALSE, TRUE, NULL)) == NULL) {
        logerror("rwlock_create: failed to create writer event %s at %s:%d",
            name, __FILE__, __LINE__);
+       free(rwlock->name);
        CloseHandle(rwlock->can_read);
        free(rwlock);
        return NULL;
@@ -687,6 +710,8 @@ empth_rwlock_destroy(empth_rwlock_t *rwlock)
 {
     if (CANT_HAPPEN(rwlock->nread || rwlock->nwrite))
        return;
+    if (rwlock->name != NULL)
+       free(rwlock->name);
     CloseHandle(rwlock->can_read);
     CloseHandle(rwlock->can_write);
     free(rwlock);