From: Christian Mauderer <christian.maude...@embedded-brains.de>

---
 cpukit/librpc/include/rpc/rpc.h   |  4 ++-
 cpukit/librpc/src/rpc/rtems_rpc.c | 65 +++++++++++++++++++++++++++++----------
 2 files changed, 51 insertions(+), 18 deletions(-)

diff --git a/cpukit/librpc/include/rpc/rpc.h b/cpukit/librpc/include/rpc/rpc.h
index 95df085..20065ef 100644
--- a/cpukit/librpc/include/rpc/rpc.h
+++ b/cpukit/librpc/include/rpc/rpc.h
@@ -104,7 +104,9 @@ struct _rtems_rpc_task_variables {
 
        struct authsvc *svc_auths_Auths;
 };
-extern struct _rtems_rpc_task_variables *rtems_rpc_task_variables;
+
+struct _rtems_rpc_task_variables *rtems_rpc_task_variables_get(void);
+#define rtems_rpc_task_variables rtems_rpc_task_variables_get()
 
 #define svc_maxfd (rtems_rpc_task_variables->svc_svc_maxfd)
 #define svc_fdset (rtems_rpc_task_variables->svc_svc_fdset)
diff --git a/cpukit/librpc/src/rpc/rtems_rpc.c 
b/cpukit/librpc/src/rpc/rtems_rpc.c
index 5d31f12..69d6c65 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,64 @@ 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)
+               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) {
-                       free (tvp);
-                       return sc;
                }
+
                *tvp = rpc_init;
-               rtems_rpc_task_variables = tvp;
+               eno = pthread_setspecific (rtems_rpc_task_variable_key, (void 
*) tvp);
+               if (eno != 0) {
+                       free (tvp);
+                       return RTEMS_INTERNAL_ERROR;
+    }
        }
        return RTEMS_SUCCESSFUL;
 }
-- 
1.8.4.5

_______________________________________________
rtems-devel mailing list
rtems-devel@rtems.org
http://www.rtems.org/mailman/listinfo/rtems-devel

Reply via email to