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