From d73c485f23db1c221b3fe61b116efdd82a1a359f Mon Sep 17 00:00:00 2001 From: rti Date: Sat, 8 Jan 2011 01:17:13 +0100 Subject: [PATCH] Fixed #1227: Implement static IThread* IThread::getCurrentThread for pthread based systems --- code/nel/include/nel/misc/thread.h | 1 - code/nel/src/misc/p_thread.cpp | 47 +++++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/code/nel/include/nel/misc/thread.h b/code/nel/include/nel/misc/thread.h index 1db92cbff..82ef78a13 100644 --- a/code/nel/include/nel/misc/thread.h +++ b/code/nel/include/nel/misc/thread.h @@ -87,7 +87,6 @@ public: /** * Return a pointer on the current thread. * Implemented in the derived class. - * Not implemented under Linux. */ static IThread *getCurrentThread (); diff --git a/code/nel/src/misc/p_thread.cpp b/code/nel/src/misc/p_thread.cpp index 9b246e89d..23e406300 100644 --- a/code/nel/src/misc/p_thread.cpp +++ b/code/nel/src/misc/p_thread.cpp @@ -26,6 +26,44 @@ namespace NLMISC { +/* Key for thread specific storage holding IThread pointer. */ +static pthread_key_t threadSpecificKey; + +/* Hand crafted IThread representing the main thread. */ +struct CPMainThread : public CPThread +{ + CPMainThread() : CPThread(NULL, 0) + { + if(pthread_setspecific(threadSpecificKey, this)) + nlerror("cannot set main thread ptr in thread specific storage."); + } +}; + +/* Holds the IThread instance pointer representing the main thread. */ +static CPMainThread* mainThread = NULL; + +/* Init/Release routines for thread specific storage key, main thread object. */ +struct CPThreadStaticInit +{ + CPThreadStaticInit() + { + if(pthread_key_create(&threadSpecificKey, NULL)) + nlerror("cannot create thread specific storage key."); + + mainThread = new CPMainThread; + } + + ~CPThreadStaticInit() + { + if(pthread_key_delete(threadSpecificKey)) + nlerror("cannot delete thread specific storage key."); + + delete mainThread; + } +}; + +/* Run init/release routines at static construction/destruction time. */ +static CPThreadStaticInit pThreadStaticInit = CPThreadStaticInit(); /* * The IThread static creator @@ -35,15 +73,12 @@ IThread *IThread::create( IRunnable *runnable, uint32 stackSize) return new CPThread( runnable, stackSize ); } - -CPThread CurrentThread(NULL, 0); - /* * Get the current thread */ IThread *IThread::getCurrentThread () { - return &CurrentThread; + return (IThread *)pthread_getspecific(threadSpecificKey); } /* @@ -53,6 +88,10 @@ static void *ProxyFunc( void *arg ) { CPThread *parent = (CPThread*)arg; + // Set this thread's thread specific storage to IThread instance pointer + if(pthread_setspecific(threadSpecificKey, parent)) + nlerror("cannot set thread ptr in thread specific storage."); + // Allow to terminate the thread without cancellation point pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);