Changeset: c5450ab6744a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/c5450ab6744a
Modified Files:
        clients/Tests/exports.stable.out
        gdk/gdk.h
        gdk/gdk_system.c
        gdk/gdk_system.h
        gdk/gdk_system_private.h
        gdk/gdk_utils.c
        tools/monetdbe/monetdbe.c
Branch: default
Log Message:

New functions MT_thread_(de)register to (de)register "foreign" threads.
These threads are extra threads, not created by the GDK, that do run GDK
code.  This can happen in monetdbe.


diffs (truncated from 354 to 300 lines):

diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -369,11 +369,13 @@ int MT_rename(const char *old, const cha
 int MT_rmdir(const char *dirname);
 void MT_sleep_ms(unsigned int ms);
 int MT_stat(const char *filename, struct stat *stb);
+void MT_thread_deregister(void);
 QryCtx *MT_thread_get_qry_ctx(void);
 const char *MT_thread_getalgorithm(void);
 void *MT_thread_getdata(void);
 const char *MT_thread_getname(void);
 bool MT_thread_init(void);
+bool MT_thread_register(void);
 void MT_thread_set_qry_ctx(QryCtx *ctx);
 void MT_thread_setalgorithm(const char *algo);
 void MT_thread_setdata(void *data);
@@ -406,7 +408,6 @@ Thread THRget(int tid);
 void *THRgetdata(int);
 int THRgettid(void);
 int THRhighwater(void);
-Thread THRnew(const char *name, MT_Id pid);
 void THRsetdata(int, void *);
 gdk_return TMsubcommit(BAT *bl) __attribute__((__warn_unused_result__));
 gdk_return TMsubcommit_list(bat *restrict subcommit, BUN *restrict sizes, int 
cnt, lng logno, lng transid) __attribute__((__warn_unused_result__));
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -2000,7 +2000,6 @@ typedef struct threadStruct {
 gdk_export int THRgettid(void);
 gdk_export Thread THRget(int tid);
 gdk_export MT_Id THRcreate(void (*f) (void *), void *arg, enum MT_thr_detach 
d, const char *name);
-gdk_export Thread THRnew(const char *name, MT_Id pid);
 gdk_export void THRdel(Thread t);
 gdk_export void THRsetdata(int, void *);
 gdk_export void *THRgetdata(int);
diff --git a/gdk/gdk_system.c b/gdk/gdk_system.c
--- a/gdk/gdk_system.c
+++ b/gdk/gdk_system.c
@@ -265,6 +265,72 @@ MT_thread_init(void)
        return true;
 }
 
+static void
+rm_winthread(struct winthread *w)
+{
+       struct winthread **wp;
+
+       EnterCriticalSection(&winthread_cs);
+       for (wp = &winthreads; *wp && *wp != w; wp = &(*wp)->next)
+               ;
+       if (*wp)
+               *wp = w->next;
+       LeaveCriticalSection(&winthread_cs);
+       ATOMIC_DESTROY(&w->exited);
+       free(w);
+}
+
+bool
+MT_thread_register(void)
+{
+       assert(threadslot != TLS_OUT_OF_INDEXES);
+       if (threadslot == TLS_OUT_OF_INDEXES)
+               return false;
+
+       struct winthread *w;
+
+       if ((w = TlsGetValue(threadslot)) != NULL)
+               return false;
+
+       w = malloc(sizeof(*w));
+       if (w == NULL)
+               return false;
+
+       EnterCriticalSection(&winthread_cs);
+       *w = (struct winthread) {
+               .detached = false,
+               .tid = GetCurrentThreadId(),
+       };
+       snprintf(w->threadname, sizeof(w->threadname),
+                "foreign %zu", (MT_Id) w->tid);
+       Thread t = THRnew(w->threadname, w->tid);
+       if (t == NULL) {
+               free(w);
+               LeaveCriticalSection(&winthread_cs);
+               return false;
+       }
+       w->data = t;
+       ATOMIC_INIT(&w->exited, 0);
+       TlsSetValue(threadslot, w);
+       w->next = winthreads;
+       winthreads = w;
+       LeaveCriticalSection(&winthread_cs);
+       return true;
+}
+
+void
+MT_thread_deregister(void)
+{
+       struct winthread *w;
+
+       if ((w = TlsGetValue(threadslot)) == NULL)
+               return;
+
+       THRdel(w->data);
+
+       rm_winthread(w);
+}
+
 static struct winthread *
 find_winthread(DWORD tid)
 {
@@ -459,21 +525,6 @@ MT_thread_override_limits(void)
        return w && w->limit_override;
 }
 
-static void
-rm_winthread(struct winthread *w)
-{
-       struct winthread **wp;
-
-       EnterCriticalSection(&winthread_cs);
-       for (wp = &winthreads; *wp && *wp != w; wp = &(*wp)->next)
-               ;
-       if (*wp)
-               *wp = w->next;
-       LeaveCriticalSection(&winthread_cs);
-       ATOMIC_DESTROY(&w->exited);
-       free(w);
-}
-
 static DWORD WINAPI
 thread_starter(LPVOID arg)
 {
@@ -696,6 +747,21 @@ static MT_Id MT_thread_id = 1;
 static pthread_key_t threadkey;
 static bool thread_initialized = false;
 
+static void
+rm_posthread(struct posthread *p)
+{
+       struct posthread **pp;
+
+       pthread_mutex_lock(&posthread_lock);
+       for (pp = &posthreads; *pp && *pp != p; pp = &(*pp)->next)
+               ;
+       if (*pp)
+               *pp = p->next;
+       ATOMIC_DESTROY(&p->exited);
+       free(p);
+       pthread_mutex_unlock(&posthread_lock);
+}
+
 void
 dump_threads(void)
 {
@@ -746,6 +812,57 @@ MT_thread_init(void)
        return true;
 }
 
+bool
+MT_thread_register(void)
+{
+       assert(thread_initialized);
+       if (!thread_initialized)
+               return false;
+
+       struct posthread *p;
+
+       if ((p = pthread_getspecific(threadkey)) != NULL)
+               return false;
+
+       p = malloc(sizeof(*p));
+       if (p == NULL)
+               return false;
+
+       pthread_mutex_lock(&posthread_lock);
+       *p = (struct posthread) {
+               .detached = false,
+               .mtid = ++MT_thread_id,
+               .tid = pthread_self(),
+       };
+       snprintf(p->threadname, sizeof(p->threadname), "foreign %zu", p->mtid);
+       Thread t = THRnew(p->threadname, p->mtid);
+       if (t == NULL) {
+               free(p);
+               pthread_mutex_unlock(&posthread_lock);
+               return false;
+       }
+       p->data = t;
+       ATOMIC_INIT(&p->exited, 0);
+       pthread_setspecific(threadkey, p);
+       p->next = posthreads;
+       posthreads = p;
+       pthread_mutex_unlock(&posthread_lock);
+       return true;
+}
+
+void
+MT_thread_deregister(void)
+{
+       struct posthread *p;
+
+       if ((p = pthread_getspecific(threadkey)) == NULL)
+               return;
+
+       THRdel(p->data);
+
+       rm_posthread(p);
+}
+
 static struct posthread *
 find_posthread(MT_Id tid)
 {
@@ -953,27 +1070,6 @@ MT_thread_sigmask(sigset_t *new_mask, si
 }
 #endif
 
-static void
-rm_posthread_locked(struct posthread *p)
-{
-       struct posthread **pp;
-
-       for (pp = &posthreads; *pp && *pp != p; pp = &(*pp)->next)
-               ;
-       if (*pp)
-               *pp = p->next;
-       ATOMIC_DESTROY(&p->exited);
-       free(p);
-}
-
-static void
-rm_posthread(struct posthread *p)
-{
-       pthread_mutex_lock(&posthread_lock);
-       rm_posthread_locked(p);
-       pthread_mutex_unlock(&posthread_lock);
-}
-
 static void *
 thread_starter(void *arg)
 {
@@ -1002,9 +1098,11 @@ join_threads(void)
                                p->waiting = true;
                                pthread_mutex_unlock(&posthread_lock);
                                TRC_DEBUG(THRD, "Join thread \"%s\"\n", 
p->threadname);
-                               if (self) self->joinwait = p;
+                               if (self)
+                                       self->joinwait = p;
                                pthread_join(p->tid, NULL);
-                               if (self) self->joinwait = NULL;
+                               if (self)
+                                       self->joinwait = NULL;
                                rm_posthread(p);
                                waited = true;
                                pthread_mutex_lock(&posthread_lock);
@@ -1029,9 +1127,11 @@ join_detached_threads(void)
                                p->waiting = true;
                                pthread_mutex_unlock(&posthread_lock);
                                TRC_DEBUG(THRD, "Join thread \"%s\"\n", 
p->threadname);
-                               if (self) self->joinwait = p;
+                               if (self)
+                                       self->joinwait = p;
                                pthread_join(p->tid, NULL);
-                               if (self) self->joinwait = NULL;
+                               if (self)
+                                       self->joinwait = NULL;
                                rm_posthread(p);
                                waited = true;
                                pthread_mutex_lock(&posthread_lock);
diff --git a/gdk/gdk_system.h b/gdk/gdk_system.h
--- a/gdk/gdk_system.h
+++ b/gdk/gdk_system.h
@@ -175,6 +175,8 @@ gdk_export bool MT_thread_init(void);
 gdk_export int MT_create_thread(MT_Id *t, void (*function) (void *),
                                void *arg, enum MT_thr_detach d,
                                const char *threadname);
+gdk_export bool MT_thread_register(void);
+gdk_export void MT_thread_deregister(void);
 gdk_export const char *MT_thread_getname(void);
 gdk_export void *MT_thread_getdata(void);
 gdk_export void MT_thread_setdata(void *data);
diff --git a/gdk/gdk_system_private.h b/gdk/gdk_system_private.h
--- a/gdk/gdk_system_private.h
+++ b/gdk/gdk_system_private.h
@@ -22,6 +22,8 @@ int MT_kill_thread(MT_Id t)
        __attribute__((__visibility__("hidden")));
 bool MT_thread_override_limits(void)
        __attribute__((__visibility__("hidden")));
+Thread THRnew(const char *name, MT_Id pid)
+       __attribute__((__visibility__("hidden")));
 #ifdef NATIVE_WIN32
 #define GDKwinerror(format, ...)                                       \
        do {                                                            \
diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c
--- a/gdk/gdk_utils.c
+++ b/gdk/gdk_utils.c
@@ -1669,6 +1669,7 @@ THRnew(const char *name, MT_Id pid)
                                  (size_t) s->sp);
                        TRC_DEBUG(PAR, "Number of threads: %d\n",
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to