00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "threadableobject.h"
00010
00011
00012 #ifdef _SOLARIS
00013 #include <signal.h>
00014 #endif
00015
00016 #pragma package(smart_init)
00017
00018 TMutex * ThreadableObject::ThatMutex = NULL;
00019 ThreadableObject * ThreadableObject::That = NULL;
00020
00021
00022 #ifdef _SOLARIS
00023
00024
00025
00026
00027
00028
00029 static void ThreadableSigHandler( int p_sig )
00030 {
00031 void * status;
00032
00033 switch (p_sig)
00034 {
00035 case SIGUSR1:
00036
00037
00038
00039
00040 thr_exit( status );
00041 }
00042 }
00043 #endif
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 static void StartObjectThread( void * p_argument )
00059 {
00060 if ( ThreadableObject::GetThat() != NULL )
00061 {
00062 ThreadableObject::GetThat()->StartThreadFunc(p_argument);
00063 }
00064 }
00065
00066
00067 WORM_STATUS_CODE ThreadableObject::StartThreadWithArg( TO_STACK_SIZE p_stack_size
00068 , TO_THREAD_ID * thread_id
00069 , void * p_parameters
00070 #ifdef _SOLARIS
00071 , bool p_isdaemon = false
00072 #endif
00073 )
00074 {
00075 #if defined(_WINNT) || defined(_Windows)
00076 long tid = -1;
00077
00078
00079 ThatMutex->RequestLock();
00080 That = this;
00081 tid = _beginthread( StartObjectThread, p_stack_size, p_parameters );
00082 ThatMutex->ReleaseLock();
00083
00084 if ( tid == -1 )
00085 {
00086
00087 return WORM_STAT_FAILURE;
00088 }
00089
00090 #elif defined(_SOLARIS)
00091
00092 int rc;
00093 TO_THREAD_ID tid;
00094
00095
00096
00097 sigset( SIGUSR1, &ThreadableSigHandler );
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 ThatMutex->RequestLock();
00108 That = this;
00109 rc = thr_create( (void *)0
00110 , p_stack_size
00111 , StartObjectThread
00112 , p_parameters
00113 , THR_DETACHED|THR_NEW_LWP|(p_isdaemon ? THR_DAEMON : 0)
00114 , &tid
00115 );
00116 ThatMutex->ReleaseLock();
00117
00118 if ( rc != 0 )
00119 {
00120
00121 return WORM_STAT_FAILURE;
00122 }
00123 #endif
00124
00125 *thread_id = (TO_THREAD_ID)tid;
00126
00127 return WORM_STAT_SUCCESS;
00128 }
00129
00130 void ThreadableObject::KillSelfThread( void )
00131 {
00132 #if defined(_WINNT) || defined(_Windows)
00133 _endthread();
00134 #elif defined(_SOLARIS)
00135 thr_exit( (void *)NULL );
00136 #endif
00137 }
00138
00139 int ThreadableObject::WaitForThread( TO_THREAD_ID * thread_id )
00140 {
00141 #if defined(_WINNT) || defined(_Windows)
00142 if ( WaitForSingleObject((HANDLE)(*thread_id), INFINITE ) == WAIT_FAILED )
00143 {
00144 return WORM_STAT_FAILURE;
00145 }
00146 #elif defined(_SOLARIS)
00147
00148 #endif
00149 return WORM_STAT_SUCCESS;
00150 }
00151
00152 int ThreadableObject::KillThread( TO_THREAD_ID tid )
00153 {
00154 #if defined(_WINNT) || defined(_Windows)
00155 const DWORD exit_code = 0;
00156
00157 if ( TerminateThread( (HANDLE)tid, exit_code ) == 0 )
00158 {
00159 return WORM_STAT_FAILURE;
00160 }
00161 return WORM_STAT_SUCCESS;
00162 #elif defined(_SOLARIS)
00163 return( thr_kill( (thread_t) tid, SIGUSR1 ) );
00164 #endif
00165 }
00166