Fixed #1227: Implement static IThread* IThread::getCurrentThread for pthread based systems

This commit is contained in:
rti 2011-01-08 01:17:13 +01:00
parent 2e95cfce39
commit 9e71d5c502
2 changed files with 43 additions and 5 deletions

View file

@ -87,7 +87,6 @@ public:
/** /**
* Return a pointer on the current thread. * Return a pointer on the current thread.
* Implemented in the derived class. * Implemented in the derived class.
* Not implemented under Linux.
*/ */
static IThread *getCurrentThread (); static IThread *getCurrentThread ();

View file

@ -26,6 +26,44 @@
namespace NLMISC { 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 * The IThread static creator
@ -35,15 +73,12 @@ IThread *IThread::create( IRunnable *runnable, uint32 stackSize)
return new CPThread( runnable, stackSize ); return new CPThread( runnable, stackSize );
} }
CPThread CurrentThread(NULL, 0);
/* /*
* Get the current thread * Get the current thread
*/ */
IThread *IThread::getCurrentThread () IThread *IThread::getCurrentThread ()
{ {
return &CurrentThread; return (IThread *)pthread_getspecific(threadSpecificKey);
} }
/* /*
@ -53,6 +88,10 @@ static void *ProxyFunc( void *arg )
{ {
CPThread *parent = (CPThread*)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 // Allow to terminate the thread without cancellation point
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);