Module: xenomai-forge
Branch: next
Commit: c237b51600f7fdb93675095a9474e9b6ae52bfe8
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=c237b51600f7fdb93675095a9474e9b6ae52bfe8

Author: Philippe Gerum <r...@xenomai.org>
Date:   Wed Jul  2 11:46:13 2014 +0200

lib/cobalt: introduce mechanism for adding supplemental TSD

Some APIs may need to install their own TSD as part of the Cobalt
thread creation process. To this end, libraries may register TSD
creation handlers from their contructor routine by calling the new
cobalt_register_tsd_hook() service.

Each new emerging thread will call the registered handlers in turn.
The base Cobalt TSD is guaranteed to be installed before the handlers
run.

---

 lib/cobalt/current.c  |   32 ++++++++++++++++++++++++++++++--
 lib/cobalt/internal.h |    9 +++++++++
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/lib/cobalt/current.c b/lib/cobalt/current.c
index 061685d..5c4ce85 100644
--- a/lib/cobalt/current.c
+++ b/lib/cobalt/current.c
@@ -20,9 +20,12 @@
 #include <string.h>
 #include <pthread.h>
 #include <asm/xenomai/syscall.h>
+#include <boilerplate/list.h>
 #include "current.h"
 #include "internal.h"
 
+static DEFINE_PRIVATE_LIST(tsd_hooks);
+
 static void child_fork_handler(void);
 
 #ifdef HAVE_TLS
@@ -96,8 +99,17 @@ static void init_current_keys(void)
 
 static void child_fork_handler(void)
 {
-       if (cobalt_get_current() != XN_NO_HANDLE)
-               __cobalt_clear_tsd();
+       struct cobalt_tsd_hook *th;
+
+       if (cobalt_get_current() == XN_NO_HANDLE)
+               return;
+
+       __cobalt_clear_tsd();
+
+       if (!pvlist_empty(&tsd_hooks)) {
+               pvlist_for_each_entry(th, &tsd_hooks, next)
+                       th->delete_tsd();
+       }
 }
 
 xnhandle_t cobalt_get_current_slow(void)
@@ -112,6 +124,7 @@ xnhandle_t cobalt_get_current_slow(void)
 
 void cobalt_set_tsd(unsigned long u_winoff)
 {
+       struct cobalt_tsd_hook *th;
        xnhandle_t current;
        int ret;
 
@@ -123,6 +136,11 @@ void cobalt_set_tsd(unsigned long u_winoff)
        }
 
        __cobalt_set_tsd(current, u_winoff);
+
+       if (!pvlist_empty(&tsd_hooks)) {
+               pvlist_for_each_entry(th, &tsd_hooks, next)
+                       th->create_tsd();
+       }
 }
 
 void cobalt_init_current_keys(void)
@@ -130,3 +148,13 @@ void cobalt_init_current_keys(void)
        static pthread_once_t cobalt_init_current_keys_once = PTHREAD_ONCE_INIT;
        pthread_once(&cobalt_init_current_keys_once, init_current_keys);
 }
+
+void cobalt_register_tsd_hook(struct cobalt_tsd_hook *th)
+{
+       /*
+        * CAUTION: we assume inherently mt-safe conditions. Unless
+        * multiple dlopen() ends up loading extension libs
+        * concurrently, we should be ok.
+        */
+       pvlist_append(&th->next, &tsd_hooks);
+}
diff --git a/lib/cobalt/internal.h b/lib/cobalt/internal.h
index 72ed6af..89ee62d 100644
--- a/lib/cobalt/internal.h
+++ b/lib/cobalt/internal.h
@@ -35,6 +35,7 @@
 #include <cobalt/uapi/sem.h>
 #include <cobalt/cobalt.h>
 #include <xeno_config.h>
+#include <boilerplate/list.h>
 #include "current.h"
 
 #define report_error(fmt, args...) \
@@ -43,6 +44,12 @@
 #define report_error_cont(fmt, args...) \
        __STD(fprintf(stderr, "                " fmt "\n", ##args))
 
+struct cobalt_tsd_hook {
+       void (*create_tsd)(void);
+       void (*delete_tsd)(void);
+       struct pvholder next;
+};
+
 extern unsigned long cobalt_sem_heap[2];
 
 void cobalt_sigshadow_install_once(void);
@@ -134,6 +141,8 @@ void cobalt_default_mutexattr_init(void);
 
 void cobalt_default_condattr_init(void);
 
+void cobalt_register_tsd_hook(struct cobalt_tsd_hook *th);
+
 struct xnfeatinfo;
 
 void cobalt_check_features(struct xnfeatinfo *finfo);


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to