[omniORB] omnithread thread-local storage problem
Luke Deller
ldeller at xplantechnology.com
Thu Apr 1 16:19:38 BST 2004
Just a follow-up to my last email... I don't believe that omnithread's
thread-local storage can be implemented as a wrapper around win32
thread-local storage calls, because win32 does not support destructors
for thread-local values.
Also the diff I attached to my last email had an error in remove_value;
the corrected patch is attached.
Luke.
Luke Deller wrote:
> Hi,
>
> I encountered a problem with using omni_thread::get_value when I tried
> moving to the native posix thread library (NPTL) supported by the 2.6
> kernel series.
>
> I'm working with an application which provides its own replacement for
> malloc and new. It seems that with nptl, malloc is being called by a
> thread after the corresponding omni_thread has been deleted. Thus when
> malloc calls omni_thread::self()->get_value(..), it can get a rubbish
> value.
>
> This led me to wonder: why does omnithread use its own implementation of
> thread-local storage? Why doesn't it simply wrap the system thread
> library's implementation?
>
> (I tried doing this myself for posix threads, and it fixes my problem
> because omni_thread::get_value no longer depends upon omni_thread
> instance data. The cvs diff is attached if you're interested. It
> should be easy enough to do the same thing for win32 thread calls).
>
> Regards,
> Luke.
-------------- next part --------------
Index: include/omnithread.h
===================================================================
RCS file: /cvsroot/omniorb/omni/include/Attic/omnithread.h,v
retrieving revision 1.21.2.17
diff -u -r1.21.2.17 omnithread.h
--- include/omnithread.h 6 Feb 2004 16:16:29 -0000 1.21.2.17
+++ include/omnithread.h 1 Apr 2004 04:34:26 -0000
@@ -182,6 +182,10 @@
#error "Implementation header file incomplete"
#endif
+#ifndef OMNI_THREAD_KEY_T
+# define OMNI_THREAD_KEY_T unsigned int
+#endif
+
//
// This exception is thrown in the event of a fatal error.
@@ -488,7 +492,7 @@
// careful about setting/getting data in a different thread to the
// current thread.
- typedef unsigned int key_t;
+ typedef OMNI_THREAD_KEY_T key_t;
static key_t allocate_key();
class value_t {
Index: include/omnithread/posix.h
===================================================================
RCS file: /cvsroot/omniorb/omni/include/omnithread/Attic/posix.h,v
retrieving revision 1.7.2.2
diff -u -r1.7.2.2 posix.h
--- include/omnithread/posix.h 8 Sep 2002 21:58:54 -0000 1.7.2.2
+++ include/omnithread/posix.h 1 Apr 2004 04:34:26 -0000
@@ -73,4 +73,6 @@
static int posix_priority(priority_t); \
friend void* omni_thread_wrapper(void* ptr);
+#define OMNI_THREAD_KEY_T pthread_key_t
+
#endif
Index: src/lib/omnithread/posix.cc
===================================================================
RCS file: /cvsroot/omniorb/omni/src/lib/omnithread/Attic/posix.cc,v
retrieving revision 1.27.2.11
diff -u -r1.27.2.11 posix.cc
--- src/lib/omnithread/posix.cc 9 Jun 2003 11:59:26 -0000 1.27.2.11
+++ src/lib/omnithread/posix.cc 1 Apr 2004 04:34:26 -0000
@@ -949,7 +949,44 @@
delete dummy;
}
+static void
+value_destructor(void *value)
+{
+ delete (omni_thread::value_t*)value;
+}
+
+omni_thread::key_t
+omni_thread::allocate_key()
+{
+ pthread_key_t key;
+ THROW_ERRORS(pthread_key_create(&key, value_destructor));
+ return key;
+}
+
+omni_thread::value_t*
+omni_thread::set_value(key_t k, value_t* v)
+{
+ int err;
+ err = pthread_setspecific(k, v);
+ if (err==0)
+ return v;
+ else if (err==EINVAL)
+ return 0; /* invalid key */
+ else
+ throw omni_thread_fatal(err);
+}
+
+omni_thread::value_t*
+omni_thread::get_value(key_t k)
+{
+ return (value_t*)pthread_getspecific(k);
+}
+
+omni_thread::value_t*
+omni_thread::remove_value(key_t k)
+{
+ value_t * v = (value_t*)pthread_getspecific(k);
+ pthread_key_delete(k);
+ return v;
+}
-#define INSIDE_THREAD_IMPL_CC
-#include "threaddata.cc"
-#undef INSIDE_THREAD_IMPL_CC
More information about the omniORB-list
mailing list