Implement __cxa_thread_atexit to support C++11 thread_local scope. The
authorkettenis <kettenis@openbsd.org>
Tue, 5 Dec 2017 13:45:31 +0000 (13:45 +0000)
committerkettenis <kettenis@openbsd.org>
Tue, 5 Dec 2017 13:45:31 +0000 (13:45 +0000)
interface is also made available as __cxa_thread_atexit_impl to satisfy the
needs of GNU libstdc++.

ok guenther@, millert@

lib/libc/Symbols.list
lib/libc/include/thread_private.h
lib/libc/shlib_version
lib/libc/stdlib/atexit.c
lib/libc/stdlib/atexit.h
lib/libc/thread/rthread.c

index d634604..63420fa 100644 (file)
@@ -1466,6 +1466,8 @@ random
 /* stdlib */
 _Exit
 __cxa_atexit
+__cxa_thread_atexit
+__cxa_thread_atexit_impl
 __cxa_finalize
 __isthreaded
 a64l
index fd530d7..ae8d554 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: thread_private.h,v 1.32 2017/11/04 22:53:57 jca Exp $ */
+/* $OpenBSD: thread_private.h,v 1.33 2017/12/05 13:45:31 kettenis Exp $ */
 
 /* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */
 
@@ -394,6 +394,7 @@ void        _spinunlock(volatile _atomic_lock_t *);
 void   _rthread_debug(int, const char *, ...)
                __attribute__((__format__ (printf, 2, 3)));
 pid_t  _thread_dofork(pid_t (*_sys_fork)(void));
+void   _thread_finalize(void);
 
 /*
  * Threading syscalls not declared in system headers
index 7fe672d..858859a 100644 (file)
@@ -1,4 +1,4 @@
 major=92
-minor=0
+minor=1
 # note: If changes were made to include/thread_private.h or if system
 # calls were added/changed then librthread/shlib_version also be updated.
index 83cc128..dc117a3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: atexit.c,v 1.24 2015/11/10 04:14:03 guenther Exp $ */
+/*     $OpenBSD: atexit.c,v 1.25 2017/12/05 13:45:31 kettenis Exp $ */
 /*
  * Copyright (c) 2002 Daniel Hartmeier
  * All rights reserved.
 
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <dlfcn.h>
+#include <elf.h>
+#pragma weak _DYNAMIC
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include "atexit.h"
 #include "atfork.h"
 #include "thread_private.h"
+#include "tib.h"
+
+typeof(dlctl) dlctl asm("_dlctl") __attribute__((weak));
+
+struct thread_atexit_fn {
+       void (*func)(void *);
+       void *arg;
+       struct thread_atexit_fn *next;
+};
 
 struct atexit *__atexit;
 static int restartloop;
@@ -121,6 +133,43 @@ atexit(void (*fn)(void))
 }
 DEF_STRONG(atexit);
 
+__weak_alias(__cxa_thread_atexit, __cxa_thread_atexit_impl);
+
+int
+__cxa_thread_atexit_impl(void (*func)(void *), void *arg, void *dso)
+{
+       struct thread_atexit_fn *fnp;
+       struct tib *tib = TIB_GET();
+
+       fnp = calloc(1, sizeof(struct thread_atexit_fn));
+       if (fnp == NULL)
+               return -1;
+
+       if (_DYNAMIC)
+               dlctl(NULL, DL_REFERENCE, dso);
+
+       fnp->func = func;
+       fnp->arg = arg;
+       fnp->next = tib->tib_atexit;
+       tib->tib_atexit = fnp;
+
+       return 0;
+}
+DEF_STRONG(__cxa_thread_atexit_impl);
+
+void
+_thread_finalize(void)
+{
+       struct tib *tib = TIB_GET();
+
+       while (tib->tib_atexit) {
+               struct thread_atexit_fn *fnp = tib->tib_atexit;
+               tib->tib_atexit = fnp->next;
+               fnp->func(fnp->arg);
+               free(fnp);
+       }
+}
+
 /*
  * Call all handlers registered with __cxa_atexit() for the shared
  * object owning 'dso'.
@@ -134,6 +183,9 @@ __cxa_finalize(void *dso)
        int n, pgsize = getpagesize();
        static int call_depth;
 
+       if (dso == NULL)
+               _thread_finalize();
+
        _ATEXIT_LOCK();
        call_depth++;
 
index e2e821d..d9bfed8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: atexit.h,v 1.10 2015/10/25 18:01:24 guenther Exp $ */
+/*     $OpenBSD: atexit.h,v 1.11 2017/12/05 13:45:31 kettenis Exp $ */
 
 /*
  * Copyright (c) 2002 Daniel Hartmeier
@@ -46,7 +46,9 @@ extern struct atexit *__atexit;               /* points to head of LIFO stack */
 __END_HIDDEN_DECLS
 
 int    __cxa_atexit(void (*)(void *), void *, void *);
+int    __cxa_thread_atexit(void (*)(void *), void *, void *);
 void   __cxa_finalize(void *);
 
 PROTO_NORMAL(__cxa_atexit);
+PROTO_STD_DEPRECATED(__cxa_thread_atexit);
 PROTO_NORMAL(__cxa_finalize);
index 66405cf..f26e85f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rthread.c,v 1.6 2017/11/04 22:53:57 jca Exp $ */
+/*     $OpenBSD: rthread.c,v 1.7 2017/12/05 13:45:31 kettenis Exp $ */
 /*
  * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
  * All Rights Reserved.
@@ -137,6 +137,7 @@ pthread_exit(void *retval)
                oclfn->fn(oclfn->arg);
                free(oclfn);
        }
+       _thread_finalize();
        _rthread_tls_destructors(thread);
 
        if (_thread_cb.tc_thread_release != NULL)