yate: Call pthread_key_create when the key is first accessed 120/head
authorRobert Högberg <robert.hogberg@gmail.com>
Fri, 9 Sep 2016 17:55:24 +0000 (19:55 +0200)
committerRobert Högberg <robert.hogberg@gmail.com>
Fri, 9 Sep 2016 17:55:24 +0000 (19:55 +0200)
pthread_key_create used to be called when a specific static key object was
initialized, but if another static object was initialized earlier and this
other object needed the key during its initialization yate would crash.

Fixes #99

Signed-off-by: Robert Högberg <robert.hogberg@gmail.com>
net/yate/patches/120-create-thread-key-on-access.patch [new file with mode: 0644]

diff --git a/net/yate/patches/120-create-thread-key-on-access.patch b/net/yate/patches/120-create-thread-key-on-access.patch
new file mode 100644 (file)
index 0000000..500dc5a
--- /dev/null
@@ -0,0 +1,49 @@
+--- a/engine/Thread.cpp
++++ b/engine/Thread.cpp
+@@ -106,21 +106,18 @@ static DWORD getTls()
+     return tls_index;
+ }
+ #else /* _WINDOWS */
+-static pthread_key_t current_key;
+-
+-class ThreadPrivateKeyAlloc
++static pthread_key_t& current_key()
+ {
+-public:
+-    ThreadPrivateKeyAlloc()
+-    {
+-      if (::pthread_key_create(&current_key,ThreadPrivate::destroyFunc)) {
++    static pthread_key_t* current_key = NULL;
++    if (!current_key) {
++      current_key = new pthread_key_t;
++      if (::pthread_key_create(current_key, ThreadPrivate::destroyFunc)) {
+           abortOnBug(true);
+           Debug(DebugFail,"Failed to create current thread key!");
+       }
+     }
+-};
+-
+-static ThreadPrivateKeyAlloc keyAllocator;
++    return *current_key;
++}
+ #endif /* _WINDOWS */
+ static TokenDict s_prio[] = {
+@@ -309,7 +306,7 @@ void ThreadPrivate::run()
+ #ifdef _WINDOWS
+     ::TlsSetValue(getTls(),this);
+ #else
+-    ::pthread_setspecific(current_key,this);
++    ::pthread_setspecific(current_key(),this);
+     pthread_cleanup_push(cleanupFunc,this);
+ #ifdef PTHREAD_CANCEL_ASYNCHRONOUS
+     ::pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,0);
+@@ -421,7 +418,7 @@ ThreadPrivate* ThreadPrivate::current()
+ #ifdef _WINDOWS
+     return reinterpret_cast<ThreadPrivate *>(::TlsGetValue(getTls()));
+ #else
+-    return reinterpret_cast<ThreadPrivate *>(::pthread_getspecific(current_key));
++    return reinterpret_cast<ThreadPrivate *>(::pthread_getspecific(current_key()));
+ #endif
+ }