Go to the documentation of this file.00001 #ifndef __THREAD_ABSTRACTION_CPP__
00002 #define __THREAD_ABSTRACTION_CPP__
00003
00004 #include <string>
00005
00006 #include <system/thread_abstraction.h>
00007 #include <utilities/exception.h>
00008 #include <utilities/testing_utilities.h>
00009
00010 namespace nitro
00011 {
00012 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM )
00013 DWORD WinThreadFunction( LPVOID Data )
00014 {
00015 try
00016 {
00017 ( ( ThreadAbstraction * )Data )->ThreadFunction( ( ( ThreadAbstraction * )Data )->ThreadParam );
00018
00019 return( 0 );
00020 }
00021 catch( ... )
00022 {
00023 return( 1 );
00024 }
00025 }
00026 #endif
00027
00028 void ThreadAbstraction::CreateThread( void * ( * theThreadFunction )( void * ) , void * theThreadParam )
00029 {
00030 try
00031 {
00032 Release();
00033
00034 ThreadFunction = theThreadFunction;
00035
00036 ThreadParam = theThreadParam;
00037
00038 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM )
00039 ThreadData = ( void * )new HANDLE;
00040
00041 * ( ( HANDLE * ) ThreadData ) = ::CreateThread( 0 , 0 , ( LPTHREAD_START_ROUTINE )WinThreadFunction , this , 0 , 0 );
00042
00043 if( ! * ( ( HANDLE * ) ThreadData ) )
00044 {
00045 throw( nitro::exception( std::string( "An error occured while thread creation" ) , 0 ) );
00046 }
00047 #endif
00048
00049 #if defined( NIX_PLATFORM ) || defined( CYGWIN_PLATFORM )
00050 ThreadData = ( void * )new pthread_t;
00051
00052 if( pthread_create( ( pthread_t * )ThreadData , NULL , theThreadFunction , ( void * ) theThreadParam ) )
00053 {
00054 throw( nitro::exception( std::string( "An error occured while thread creation" ) , 0 ) );
00055 }
00056
00057 if( pthread_detach( * ( ( pthread_t * )ThreadData ) ) )
00058 {
00059 throw( nitro::exception( std::string( "An error occured while thread detaching" ) , 0 ) );
00060 }
00061 #endif
00062 }
00063 catch( nitro::exception e )
00064 {
00065 throw( nitro::exception( std::string( "ThreadAbstraction::CreateThread( void ( * theThreadFunction )( void * ) , void * theThreadParam )::" ) + e.what() , e.code() ) );
00066 }
00067 catch( ... )
00068 {
00069 throw( nitro::exception( std::string( "ThreadAbstraction::CreateThread( void ( * theThreadFunction )( void * ) , void * theThreadParam )::An error occured" ) , 0 ) );
00070 }
00071 }
00072
00073 void ThreadAbstraction::Release( void )
00074 {
00075 try
00076 {
00077 if( ThreadData != NULL )
00078 {
00079 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM )
00080 delete ( HANDLE * ) ThreadData;
00081 #endif
00082
00083 #if defined( NIX_PLATFORM ) || defined( CYGWIN_PLATFORM )
00084 delete ( pthread_t * ) ThreadData;
00085 #endif
00086 ThreadData = NULL;
00087 }
00088 }
00089 catch( nitro::exception e )
00090 {
00091 throw( nitro::exception( std::string( "ThreadAbstraction::Release( void )::" ) + e.what() , e.code() ) );
00092 }
00093 catch( ... )
00094 {
00095 throw( nitro::exception( std::string( "ThreadAbstraction::Release( void )::An error occured" ) , 0 ) );
00096 }
00097 }
00098
00099 void ThreadAbstraction::Sleep( std::size_t Milliseconds )
00100 {
00101 try
00102 {
00103 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM )
00104 ::Sleep( ( DWORD )Milliseconds );
00105 #endif
00106
00107 #if defined( NIX_PLATFORM ) || defined( CYGWIN_PLATFORM )
00108 if( usleep( Milliseconds * 1000 ) == -1 )
00109 {
00110 throw( nitro::exception( "An erro occured while usleep call" , 1 ) );
00111 }
00112 #endif
00113 }
00114 catch( nitro::exception e )
00115 {
00116 throw( nitro::exception( std::string( "ThreadAbstraction::Sleep( const std::size_t & Milliseconds )::" ) + e.what() , e.code() ) );
00117 }
00118 catch( ... )
00119 {
00120 throw( nitro::exception( std::string( "ThreadAbstraction::Sleep( const std::size_t & Milliseconds )::An error occured" ) , 0 ) );
00121 }
00122 }
00123
00124 ThreadAbstraction::ThreadAbstraction( void )
00125 {
00126 ThreadFunction = NULL;
00127
00128 ThreadData = NULL;
00129 }
00130
00131 ThreadAbstraction::~ThreadAbstraction()
00132 {
00133 try
00134 {
00135 Release();
00136 }
00137 catch( nitro::exception e )
00138 {
00139 }
00140 catch( ... )
00141 {
00142 }
00143 }
00144
00145
00146
00147
00148 BEGIN_TESTING_SECTION()
00149
00150 ENABLE_CLASS_TESTING( ThreadAbstraction )
00151
00152 #ifdef ENABLE_AUTOTESTING
00153 void * func1( void * )
00154 {
00155 std::cout<<"TEST PASSED"<<std::endl;
00156 return( NULL );
00157 }
00158 void * func2( void * )
00159 {
00160 for( ; true ; )
00161 {
00162 std::cout<<"TEST PASSED"<<std::endl;
00163 }
00164 return( NULL );
00165 }
00166 void _CreateThread( int i )
00167 {
00168 if( i == 1 )
00169 {
00170 ThreadAbstractionGetter( "default" ).CreateThread( func1 , NULL );
00171 }
00172 if( i == 2 )
00173 {
00174 ThreadAbstractionGetter( "default" ).CreateThread( func2 , NULL );
00175 }
00176 }
00177 #endif
00178
00179 FUNCTION_TESTING_1( _CreateThread , tstCreateThread , int , void , NO_RET )
00180 FUNCTION_TESTING_1( ThreadAbstraction::Sleep , tstSleep , std::size_t , void , NO_RET )
00181
00182 END_TESTING_SECTION()
00183 }
00184
00185 #endif