00001 #include "global.h"
00002 #include "MercuryThreads.h"
00003
00004 #if defined( WIN32 )
00005 #include <windows.h>
00006 #endif
00007
00008 MercuryThread::MercuryThread()
00009 :m_name("(null)"), m_thread(0)
00010 {
00011 }
00012
00013 MercuryThread::MercuryThread( const MString &name )
00014 :m_name(name), m_thread(0)
00015 {
00016 }
00017
00018 MercuryThread::~MercuryThread( )
00019 {
00020 Close();
00021 }
00022
00023 #if defined( WIN32 )
00024 struct StartThreadData
00025 {
00026 void * (*m_pFunc)( void *pData );
00027 void *m_pData;
00028 };
00029
00030 static DWORD WINAPI StartThread( LPVOID pData )
00031 {
00032 StartThreadData * in = (StartThreadData *)pData;
00033 DWORD ret = (DWORD)in->m_pFunc( in->m_pData );
00034 delete in;
00035 return ret;
00036 }
00037 #endif
00038
00039 int MercuryThread::Create( void * (*fn)(void *), void *data )
00040 {
00041 #if defined( WIN32 )
00042 StartThreadData *k = new StartThreadData;
00043 k->m_pData = data;
00044 k->m_pFunc = fn;
00045 m_thread = CreateThread( NULL, 0, &StartThread, k, 0, NULL );
00046 return m_thread != NULL;
00047 #else
00048 pthread_attr_t pthread_custom_attr;
00049 pthread_attr_init(&pthread_custom_attr);
00050 if ( pthread_create( &m_thread, &pthread_custom_attr, fn, data ) )
00051 return false;
00052 else
00053 return true;
00054 #endif
00055 }
00056
00057 int MercuryThread::Halt( bool kill )
00058 {
00059 #if defined( WIN32 )
00060 if ( kill )
00061 return TerminateThread( m_thread, 0 );
00062 else
00063 return SuspendThread( m_thread );
00064 #else
00065 pthread_cancel( m_thread );
00066 return 0;
00067 #endif
00068 }
00069
00070 int MercuryThread::Resume( )
00071 {
00072 #if defined( WIN32 )
00073 return ResumeThread( m_thread );
00074 #else
00075 return 0;
00076 #endif
00077 }
00078
00079 int MercuryThread::Wait( long lMilliseconds )
00080 {
00081 #if defined( WIN32 )
00082 return WaitForSingleObject( m_thread, lMilliseconds ) == 0;
00083 #else
00084 pthread_join( m_thread, NULL );
00085 return 0;
00086 #endif
00087 }
00088
00089 void MercuryThread::Close( )
00090 {
00091 if ( m_thread )
00092 {
00093 Halt( true );
00094
00095 #if defined( WIN32 )
00096 CloseHandle( m_thread );
00097 m_thread = NULL;
00098 #else
00099 #endif
00100 }
00101 }
00102
00103
00104 MercuryMutex::MercuryMutex( )
00105 :m_name("(null)")
00106 {
00107 Open( );
00108 UnLock();
00109 }
00110
00111 MercuryMutex::MercuryMutex( const MString &name )
00112 :m_name(name)
00113 {
00114 Open( );
00115 UnLock();
00116 }
00117
00118 MercuryMutex::~MercuryMutex( )
00119 {
00120 Close( );
00121 }
00122
00123 int MercuryMutex::Wait( long lMilliseconds )
00124 {
00125 #if defined( WIN32 )
00126 return WaitForSingleObject( m_mutex, lMilliseconds );
00127 #else
00128
00129
00130
00131
00132
00133
00134
00135 pthread_mutex_lock( &m_mutex );
00136 return 0;
00137 #endif
00138 }
00139
00140 int MercuryMutex::UnLock( )
00141 {
00142 #if defined( WIN32 )
00143 return ReleaseMutex( m_mutex );
00144 #else
00145 pthread_mutex_unlock( &m_mutex );
00146 return 0;
00147 #endif
00148 }
00149
00150 int MercuryMutex::Open( )
00151 {
00152 #if defined( WIN32 )
00153 SECURITY_ATTRIBUTES *p = ( SECURITY_ATTRIBUTES* ) malloc( sizeof( SECURITY_ATTRIBUTES ) );
00154 p->nLength = sizeof( SECURITY_ATTRIBUTES );
00155 p->bInheritHandle = true;
00156 p->lpSecurityDescriptor = NULL;
00157 m_mutex = CreateMutex( p, true, m_name.c_str() );
00158 free( p );
00159 return (int)m_mutex;
00160 #else
00161 pthread_mutexattr_t attr;
00162 pthread_mutexattr_init( &attr );
00163 pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
00164 pthread_mutex_init( &m_mutex, &attr );
00165 return 0;
00166 #endif
00167 }
00168
00169 int MercuryMutex::Close( )
00170 {
00171 #if defined( WIN32 )
00172 return CloseHandle( m_mutex );
00173 #else
00174 pthread_mutex_destroy( &m_mutex );
00175 return 0;
00176 #endif
00177 }