summaryrefslogtreecommitdiffstats
path: root/cpukit/librpc/src/rpc
diff options
context:
space:
mode:
authorChristian Mauderer <Christian.Mauderer@embedded-brains.de>2014-03-21 14:17:19 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-03-24 08:31:48 +0100
commit8e133b25005947879113a46cc33414dfbcce6123 (patch)
tree1cc7df3a36117fe345536d647524f25cd9345050 /cpukit/librpc/src/rpc
parentscore: Start thread dispatch profiling later (diff)
downloadrtems-8e133b25005947879113a46cc33414dfbcce6123.tar.bz2
librpc: Use POSIX key instead of task variables
Diffstat (limited to 'cpukit/librpc/src/rpc')
-rw-r--r--cpukit/librpc/src/rpc/rtems_rpc.c60
1 files changed, 45 insertions, 15 deletions
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 <rpc/rpc.h>
#include <rtems.h>
#include <stdlib.h>
+#include <pthread.h>
+#include <assert.h>
/*
* 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;
}