Changeset: d370f5eaddbb for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d370f5eaddbb
Modified Files:
        gdk/gdk_system.c
        gdk/gdk_system_private.h
        gdk/gdk_utils.c
Branch: Apr2019
Log Message:

Make Windows and Posix thread handling more similar.
Removed MT_exit_thread(); create list of all threads in system (not
just detachable ones); use thread-specific (a.k.a. thread-local) data
to find thread record (and thread name); for Posix, create our own
thread ID instead of using version-dependent hack that dismembers a
pthread_t value; log errors.


diffs (truncated from 758 to 300 lines):

diff --git a/gdk/gdk_system.c b/gdk/gdk_system.c
--- a/gdk/gdk_system.c
+++ b/gdk/gdk_system.c
@@ -42,7 +42,7 @@
 #endif
 
 #include <signal.h>
-
+#include <string.h>            /* for strerror */
 #include <unistd.h>            /* for sysconf symbols */
 
 MT_Lock MT_system_lock MT_LOCK_INITIALIZER("MT_system_lock");
@@ -159,25 +159,23 @@ static struct winthread {
        DWORD tid;
        void (*func) (void *);
        void *arg;
-       int flags;
+       bool exited:1, detached:1, waiting:1;
        const char *threadname;
 } *winthreads = NULL;
-#define EXITED         1
-#define DETACHED       2
-#define WAITING                4
+
 static CRITICAL_SECTION winthread_cs;
-static DWORD threadnameslot = TLS_OUT_OF_INDEXES;
+static DWORD threadslot = TLS_OUT_OF_INDEXES;
 
 bool
 MT_thread_init(void)
 {
-       if (threadnameslot == TLS_OUT_OF_INDEXES) {
-               threadnameslot = TlsAlloc();
-               if (threadnameslot == TLS_OUT_OF_INDEXES)
+       if (threadslot == TLS_OUT_OF_INDEXES) {
+               threadslot = TlsAlloc();
+               if (threadslot == TLS_OUT_OF_INDEXES)
                        return false;
-               if (TlsSetValue(threadnameslot, "main thread") == 0) {
-                       TlsFree(threadnameslot);
-                       threadnameslot = TLS_OUT_OF_INDEXES;
+               if (TlsSetValue(threadslot, NULL) == 0) {
+                       TlsFree(threadslot);
+                       threadslot = TLS_OUT_OF_INDEXES;
                        return false;
                }
                InitializeCriticalSection(&winthread_cs);
@@ -185,26 +183,13 @@ MT_thread_init(void)
        return true;
 }
 
-const char *
-MT_thread_name(void)
-{
-       const char *name = TlsGetValue(threadnameslot);
-       return name ? name : "unknown thread";
-}
-
-void
-MT_thread_setname(const char *name)
+static inline struct winthread *
+find_winthread_locked(DWORD tid)
 {
-       TlsSetValue(threadnameslot, (LPVOID) name);
-}
-
-void
-gdk_system_reset(void)
-{
-       assert(threadnameslot != TLS_OUT_OF_INDEXES);
-       TlsFree(threadnameslot);
-       threadnameslot = TLS_OUT_OF_INDEXES;
-       DeleteCriticalSection(&winthread_cs);
+       for (struct winthread *w = winthreads; w; w = w->next)
+               if (w->tid == tid)
+                       return w;
+       return NULL;
 }
 
 static struct winthread *
@@ -213,13 +198,39 @@ find_winthread(DWORD tid)
        struct winthread *w;
 
        EnterCriticalSection(&winthread_cs);
-       for (w = winthreads; w; w = w->next)
-               if (w->tid == tid)
-                       break;
+       w = find_winthread_locked(tid);
        LeaveCriticalSection(&winthread_cs);
        return w;
 }
 
+const char *
+MT_thread_name(void)
+{
+       struct winthread *w = TlsGetValue(threadslot);
+       return w ? w->threadname ? w->threadname : "unknown thread" : "main 
thread";
+}
+
+void
+MT_thread_setname(const char *name)
+{
+       struct winthread *w = TlsGetValue(threadslot);
+
+       if (w) {
+               EnterCriticalSection(&winthread_cs);
+               w->threadname = name;
+               LeaveCriticalSection(&winthread_cs);
+       }
+}
+
+void
+gdk_system_reset(void)
+{
+       assert(threadslot != TLS_OUT_OF_INDEXES);
+       TlsFree(threadslot);
+       threadslot = TLS_OUT_OF_INDEXES;
+       DeleteCriticalSection(&winthread_cs);
+}
+
 static void
 rm_winthread(struct winthread *w)
 {
@@ -237,10 +248,13 @@ rm_winthread(struct winthread *w)
 static DWORD WINAPI
 thread_starter(LPVOID arg)
 {
-       TlsSetValue(threadnameslot,
-                   (LPVOID) ((struct winthread *) arg)->threadname);
-       (*((struct winthread *) arg)->func)(((struct winthread *) arg)->arg);
-       ((struct winthread *) arg)->flags |= EXITED;
+       struct winthread *w = (struct winthread *) arg;
+
+       TlsSetValue(threadslot, w);
+       (*w->func)(w->arg);
+       EnterCriticalSection(&winthread_cs);
+       w->exited = true;
+       LeaveCriticalSection(&winthread_cs);
        ExitThread(0);
        return TRUE;
 }
@@ -248,15 +262,14 @@ thread_starter(LPVOID arg)
 static void
 join_threads(void)
 {
-       struct winthread *w;
        bool waited;
 
+       EnterCriticalSection(&winthread_cs);
        do {
                waited = false;
-               EnterCriticalSection(&winthread_cs);
-               for (w = winthreads; w; w = w->next) {
-                       if ((w->flags & (EXITED | DETACHED | WAITING)) == 
(EXITED | DETACHED)) {
-                               w->flags |= WAITING;
+               for (struct winthread *w = winthreads; w; w = w->next) {
+                       if (w->exited && w->detached && !w->waiting) {
+                               w->waiting = true;
                                LeaveCriticalSection(&winthread_cs);
                                WaitForSingleObject(w->hdl, INFINITE);
                                CloseHandle(w->hdl);
@@ -266,22 +279,21 @@ join_threads(void)
                                break;
                        }
                }
-               LeaveCriticalSection(&winthread_cs);
        } while (waited);
+       LeaveCriticalSection(&winthread_cs);
 }
 
 void
 join_detached_threads(void)
 {
-       struct winthread *w;
        bool waited;
 
+       EnterCriticalSection(&winthread_cs);
        do {
                waited = false;
-               EnterCriticalSection(&winthread_cs);
-               for (w = winthreads; w; w = w->next) {
-                       if ((w->flags & (DETACHED | WAITING)) == DETACHED) {
-                               w->flags |= WAITING;
+               for (struct winthread *w = winthreads; w; w = w->next) {
+                       if (w->detached && !w->waiting) {
+                               w->waiting = true;
                                LeaveCriticalSection(&winthread_cs);
                                WaitForSingleObject(w->hdl, INFINITE);
                                CloseHandle(w->hdl);
@@ -291,8 +303,8 @@ join_detached_threads(void)
                                break;
                        }
                }
-               LeaveCriticalSection(&winthread_cs);
        } while (waited);
+       LeaveCriticalSection(&winthread_cs);
 }
 
 int
@@ -305,16 +317,19 @@ MT_create_thread(MT_Id *t, void (*f) (vo
 
        join_threads();
        w->func = f;
+       w->hdl = NULL;
+       w->tid = 0;
        w->arg = arg;
-       w->flags = 0;
-       if (d == MT_THR_DETACHED)
-               w->flags |= DETACHED;
+       w->exited = false;
+       w->waiting = false;
+       w->detached = (d == MT_THR_DETACHED);
+       w->threadname = threadname;
        EnterCriticalSection(&winthread_cs);
        w->next = winthreads;
        winthreads = w;
        LeaveCriticalSection(&winthread_cs);
-       w->threadname = threadname;
-       w->hdl = CreateThread(NULL, THREAD_STACK_SIZE, thread_starter, w, 0, 
&w->tid);
+       w->hdl = CreateThread(NULL, THREAD_STACK_SIZE, thread_starter, w,
+                             0, &w->tid);
        if (w->hdl == NULL) {
                rm_winthread(w);
                return -1;
@@ -323,28 +338,21 @@ MT_create_thread(MT_Id *t, void (*f) (vo
        return 0;
 }
 
+MT_Id
+MT_getpid(void)
+{
+       return (MT_Id) GetCurrentThreadId();
+}
+
 void
 MT_exiting_thread(void)
 {
-       struct winthread *w;
-
-       if ((w = find_winthread(GetCurrentThreadId())) != NULL)
-               w->flags |= EXITED;
-}
+       struct winthread *w = TlsGetValue(threadslot);
 
-/* coverity[+kill] */
-void
-MT_exit_thread(int s)
-{
-       EnterCriticalSection(&winthread_cs);
-       if (winthreads) {
+       if (w) {
+               EnterCriticalSection(&winthread_cs);
+               w->exited = true;
                LeaveCriticalSection(&winthread_cs);
-               MT_exiting_thread();
-               ExitThread(s);
-       } else {
-               LeaveCriticalSection(&winthread_cs);
-               /* no threads started yet, so this is a global exit */
-               MT_global_exit(s);
        }
 }
 
@@ -455,63 +463,69 @@ pthread_sema_down(pthread_sema_t *s)
 
 static struct posthread {
        struct posthread *next;
-       pthread_t tid;
        void (*func)(void *);
        void *arg;
-       int exited;
-       const char *name;
+       const char *threadname;
+       pthread_t tid;
+       MT_Id mtid;
+       bool exited:1, detached:1, waiting:1;
 } *posthreads = NULL;
 static pthread_mutex_t posthread_lock = PTHREAD_MUTEX_INITIALIZER;
+static MT_Id MT_thread_id = 0;
 
-static pthread_key_t threadnamekey;
+static pthread_key_t threadkey;
 
 bool
 MT_thread_init(void)
 {
-       if (pthread_key_create(&threadnamekey, NULL) != 0)
+       int ret;
+
+       if ((ret = pthread_key_create(&threadkey, NULL)) != 0) {
+               fprintf(stderr,
+                       "#MT_thread_init: creating specific key for thread "
+                       "failed: %s\n", strerror(ret));
                return false;
-       pthread_setspecific(threadnamekey, "main thread");
+       }
+       if ((ret = pthread_setspecific(threadkey, NULL)) != 0) {
+               fprintf(stderr,
+                       "#MT_thread_init: setting specific value failed: %s\n",
+                       strerror(ret));
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to