From 8e133b25005947879113a46cc33414dfbcce6123 Mon Sep 17 00:00:00 2001 From: Christian Mauderer Date: Fri, 21 Mar 2014 14:17:19 +0100 Subject: librpc: Use POSIX key instead of task variables --- cpukit/librpc/src/rpc/rtems_rpc.c | 60 +++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 15 deletions(-) (limited to 'cpukit/librpc/src/rpc') diff --git a/cpukit/librpc/src/rpc/rtems_rpc.c b/cpukit/librpc/src/rpc/rtems_rpc.c index 5d31f12d49..b1efb61e66 100644 --- a/cpukit/librpc/src/rpc/rtems_rpc.c +++ b/cpukit/librpc/src/rpc/rtems_rpc.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include /* * RPC variables for single-thread @@ -61,35 +63,63 @@ static const struct _rtems_rpc_task_variables rpc_init = { /* * Per-task pointer to RPC data */ -struct _rtems_rpc_task_variables *rtems_rpc_task_variables = &rpc_default; +static pthread_once_t rtems_rpc_task_variable_once = PTHREAD_ONCE_INIT; +static pthread_key_t rtems_rpc_task_variable_key; + +/* + * Return the current task variable pointer. + */ +struct _rtems_rpc_task_variables *rtems_rpc_task_variables_get (void) +{ + void *ptr = pthread_getspecific(rtems_rpc_task_variable_key); + if (ptr == NULL) { + ptr = &rpc_default; + } + return (struct _rtems_rpc_task_variables *) ptr; +} + +/* + * Key create function for task_variable_key. + */ +static void rtems_rpc_task_variable_make_key (void) +{ + int eno = pthread_key_create(&rtems_rpc_task_variable_key, NULL); + assert (eno == 0); + /* + * FIXME: Should have destructor which cleans up + * all RPC stuff: + * - Close all files + * - Go through and free linked list elements + * - Free other allocated memory (e.g. clnt_perror_buf) + */ +} /* * Set up per-task RPC variables */ int rtems_rpc_task_init (void) { - rtems_status_code sc; struct _rtems_rpc_task_variables *tvp; + int eno = 0; + + eno = pthread_once( + &rtems_rpc_task_variable_once, + rtems_rpc_task_variable_make_key + ); + assert (eno == 0); - if (rtems_rpc_task_variables == &rpc_default) { + tvp = pthread_getspecific (rtems_rpc_task_variable_key); + if (tvp == NULL) { tvp = malloc (sizeof *tvp); if (tvp == NULL) return RTEMS_NO_MEMORY; - /* - * FIXME: Should have destructor which cleans up - * all RPC stuff: - * - Close all files - * - Go through and free linked list elements - * - Free other allocated memory (e.g. clnt_perror_buf) - */ - sc = rtems_task_variable_add ( - RTEMS_SELF, (void *)&rtems_rpc_task_variables, NULL); - if (sc != RTEMS_SUCCESSFUL) { + + eno = pthread_setspecific (rtems_rpc_task_variable_key, (void *) tvp); + if (eno != 0) { free (tvp); - return sc; + return RTEMS_INTERNAL_ERROR; } *tvp = rpc_init; - rtems_rpc_task_variables = tvp; } return RTEMS_SUCCESSFUL; } -- cgit v1.2.3