reSIProcate/rutil  9694
Public Types | Public Member Functions | Static Public Member Functions | Protected Attributes | Private Member Functions
resip::ThreadIf Class Reference

A wrapper class to create and spawn a thread. More...

#include <ThreadIf.hxx>

Inheritance diagram for resip::ThreadIf:
Inheritance graph
[legend]
Collaboration diagram for resip::ThreadIf:
Collaboration graph
[legend]

List of all members.

Public Types

typedef pthread_t Id
typedef pthread_key_t TlsKey
typedef void TlsDestructor (void *)

Public Member Functions

 ThreadIf ()
virtual ~ThreadIf ()
virtual void run ()
void join ()
void detach ()
virtual void shutdown ()
virtual bool waitForShutdown (int ms) const
bool isShutdown () const
virtual void thread ()=0

Static Public Member Functions

static Id selfId ()
static int tlsKeyCreate (TlsKey &key, TlsDestructor *destructor)
 This function follows pthread_key_create() signature.
static int tlsKeyDelete (TlsKey key)
 This function follows pthread_key_delete() signature.
static int tlsSetValue (TlsKey key, const void *val)
 This function follows pthread_setspecific() signature.
static void * tlsGetValue (TlsKey key)
 This function follows pthread_getspecific() signature.

Protected Attributes

Id mId
bool mShutdown
Mutex mShutdownMutex
Condition mShutdownCondition

Private Member Functions

 ThreadIf (const ThreadIf &)
const ThreadIfoperator= (const ThreadIf &)

Detailed Description

A wrapper class to create and spawn a thread.

It is a base class. ThreadIf::thread() is a pure virtual method .

To use this class, derive from it and override the thread() method. To start the thread, call the run() method. The code in thread() will run in a separate thread.

Call shutdown() from the constructing thread to shut down the code. This will set the bool shutdown_ to true. The code in thread() should react properly to shutdown_ being set, by returning. Call join() to join the code.

Sample:

   DerivedThreadIf thread;
   thread.run();
   // ... do stuff ...
   thread.shutdown();
   thread.join();

Definition at line 44 of file ThreadIf.hxx.


Member Typedef Documentation

typedef pthread_t resip::ThreadIf::Id

Definition at line 73 of file ThreadIf.hxx.

typedef void resip::ThreadIf::TlsDestructor(void *)

Definition at line 82 of file ThreadIf.hxx.

typedef pthread_key_t resip::ThreadIf::TlsKey

Definition at line 80 of file ThreadIf.hxx.


Constructor & Destructor Documentation

ThreadIf::ThreadIf ( )

Definition at line 87 of file ThreadIf.cxx.

                   : 
#ifdef WIN32
   mThread(0),
#endif
   mId(0), mShutdown(false), mShutdownMutex()
{
}
ThreadIf::~ThreadIf ( ) [virtual]

Definition at line 96 of file ThreadIf.cxx.

References join(), and shutdown().

{
   shutdown();
   join();
}

Here is the call graph for this function:

resip::ThreadIf::ThreadIf ( const ThreadIf ) [private]

Member Function Documentation

void ThreadIf::detach ( )

Definition at line 199 of file ThreadIf.cxx.

References mId.

{
#if !defined(WIN32)
   pthread_detach(mId);
#else
   if(mThread)
   {
      CloseHandle(mThread);
      mThread = 0;
   }
#endif
   mId = 0;
}
bool ThreadIf::isShutdown ( ) const

Definition at line 306 of file ThreadIf.cxx.

References mShutdown, and mShutdownMutex.

Referenced by resip::DnsThread::thread().

{
   Lock lock(mShutdownMutex);
   (void)lock;
   return ( mShutdown );
}
void ThreadIf::join ( )

Definition at line 143 of file ThreadIf.cxx.

References mId, and WarningLog.

Referenced by doThreadedTest(), main(), testThreadLocalLoggers(), and ~ThreadIf().

{
   // !kh!
   // perhaps assert instead of returning when join()ed already?
   // programming error?
   //assert(mId == 0);

   if (mId == 0)
   {
      return;
   }

#if defined(WIN32)
   DWORD exitCode;
   while (true)
   {
      if (GetExitCodeThread(mThread,&exitCode) != 0)
      {
         if (exitCode != STILL_ACTIVE)
         {
            break;
         }
         else
         {
            WaitForSingleObject(mThread,INFINITE);
         }
      }
      else
      {
         // log something here
         break;
      }
   }

   //  !kh!
   CloseHandle(mThread);
   mThread=0;
#else
   void* stat;
   if (mId != pthread_self())
   {
      int r = pthread_join( mId , &stat );
      if ( r != 0 )
      {
         WarningLog( << "Internal error: pthread_join() returned " << r );
         assert(0);
         // TODO
      }
   }
   
#endif

   mId = 0;
}
const ThreadIf& resip::ThreadIf::operator= ( const ThreadIf ) [private]
void ThreadIf::run ( ) [virtual]

Definition at line 103 of file ThreadIf.cxx.

References mId, and threadIfThreadWrapper().

Referenced by doThreadedTest(), main(), and testThreadLocalLoggers().

{
   assert(mId == 0);

#if defined(WIN32)
   // !kh!
   // Why _beginthreadex() instead of CreateThread():
   //   http://support.microsoft.com/support/kb/articles/Q104/6/41.ASP
   // Example of using _beginthreadex() mixed with WaitForSingleObject() and CloseHandle():
   //   http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__beginthread.2c_._beginthreadex.asp
   
   mThread =
#ifdef _WIN32_WCE
       // there is no _beginthreadex() for WINCE
       CreateThread
#else
       (HANDLE)_beginthreadex 
#endif // _WIN32_WCE
         (
         NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes,  // pointer to security attributes
         0, // DWORD dwStackSize,                         // initial thread stack size
         RESIP_THREAD_START_ROUTINE
         (threadIfThreadWrapper), // LPTHREAD_START_ROUTINE lpStartAddress,     // pointer to thread function
         this, //LPVOID lpParameter,                        // argument for new thread
         0, //DWORD dwCreationFlags,                     // creation flags
         (unsigned*)&mId// LPDWORD lpThreadId                         // pointer to receive thread ID
         );
   assert( mThread != 0 );
#else
   // spawn the thread
   if ( int retval = pthread_create( &mId, 0, threadIfThreadWrapper, this) )
   {
      std::cerr << "Failed to spawn thread: " << retval << std::endl;
      assert(0);
      // TODO - ADD LOGING HERE
   }
#endif
}

Here is the call graph for this function:

ThreadIf::Id ThreadIf::selfId ( ) [static]

Definition at line 214 of file ThreadIf.cxx.

Referenced by resip::Random::getSimpleSeed(), resip::Log::getThreadSetting(), and resip::Log::setThreadSetting().

{
#if defined(WIN32)
   return GetCurrentThreadId();
#else
   return pthread_self();
#endif
}
void ThreadIf::shutdown ( ) [virtual]

Definition at line 284 of file ThreadIf.cxx.

References mShutdown, mShutdownCondition, mShutdownMutex, and resip::Condition::signal().

Referenced by main(), testThreadLocalLoggers(), and ~ThreadIf().

Here is the call graph for this function:

virtual void resip::ThreadIf::thread ( ) [pure virtual]
void * ThreadIf::tlsGetValue ( TlsKey  key) [static]

This function follows pthread_getspecific() signature.

Definition at line 273 of file ThreadIf.cxx.

Referenced by resip::Log::getLoggerData(), resip::Random::getRandom(), resip::Log::getThreadSetting(), and resip::Log::setThreadLocalLogger().

{
#if defined(WIN32)
   return TlsGetValue(key);
#else
   return pthread_getspecific(key);
#endif
}
int ThreadIf::tlsKeyCreate ( TlsKey key,
TlsDestructor destructor 
) [static]

This function follows pthread_key_create() signature.

Definition at line 224 of file ThreadIf.cxx.

Referenced by resip::Random::initialize(), and resip::LogStaticInitializer::LogStaticInitializer().

{
#if defined(WIN32)
   key = TlsAlloc();
   if (key!=TLS_OUT_OF_INDEXES)
   {
      Lock lock(*mTlsDestructorsMutex);
      (*mTlsDestructors)[key] = destructor;
      return 0;
   }
   else
   {
      return GetLastError();
   }
#else
   return pthread_key_create(&key, destructor);
#endif
}
int ThreadIf::tlsKeyDelete ( TlsKey  key) [static]

This function follows pthread_key_delete() signature.

Definition at line 244 of file ThreadIf.cxx.

Referenced by resip::LogStaticInitializer::~LogStaticInitializer().

{
#if defined(WIN32)
   if (TlsFree(key)>0)
   {
      Lock lock(*mTlsDestructorsMutex);
      mTlsDestructors->erase(key);
      return 0;
   }
   else
   {
      return GetLastError();
   }
#else
   return pthread_key_delete(key);
#endif
}
int ThreadIf::tlsSetValue ( TlsKey  key,
const void *  val 
) [static]

This function follows pthread_setspecific() signature.

Definition at line 263 of file ThreadIf.cxx.

Referenced by resip::Random::getRandom(), resip::Log::setThreadLocalLogger(), and resip::Log::setThreadSetting().

{
#if defined(WIN32)
   return TlsSetValue(key, (LPVOID)val)>0?0:GetLastError();
#else
   return pthread_setspecific(key, val);
#endif
}
bool ThreadIf::waitForShutdown ( int  ms) const [virtual]

Definition at line 295 of file ThreadIf.cxx.

References mShutdown, mShutdownCondition, mShutdownMutex, and resip::Condition::wait().

Here is the call graph for this function:


Member Data Documentation

Id resip::ThreadIf::mId [protected]

Reimplemented in LogThread.

Definition at line 113 of file ThreadIf.hxx.

Referenced by detach(), join(), and run().

bool resip::ThreadIf::mShutdown [protected]

Definition at line 117 of file ThreadIf.hxx.

Referenced by shutdown(), and waitForShutdown().

Mutex resip::ThreadIf::mShutdownMutex [mutable, protected]

Definition at line 116 of file ThreadIf.hxx.

Referenced by isShutdown(), shutdown(), and waitForShutdown().


The documentation for this class was generated from the following files: