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