int _LibMain( int hdll, int reason, void *reserved ) { thread_data *tdata; int rc = 0; switch( reason ) { case DLL_THREAD_ATTACH: tdata = ( thread_data * )RdosAllocateMem( __ThreadDataSize ); if( tdata ) { memset( tdata, 0, __ThreadDataSize ); tdata->__data_size = __ThreadDataSize; __RdosAddThread( tdata ); } break; case DLL_PROCESS_ATTACH: __InitRtns( INIT_PRIORITY_THREAD ); tdata = ( thread_data * )RdosAllocateMem( __ThreadDataSize ); memset( tdata, 0, __ThreadDataSize ); tdata->__data_size = __ThreadDataSize; __InitThreadData( tdata ); __RdosInit( 1, tdata, hdll ); __InitRtns( 255 ); __CommonInit(); __sig_init_rtn(); if( !__RdosThreadInit() ) return( -1 ); __InitMultipleThread(); rc = LibMain( hdll, reason, reserved ); if( !rc ) { __FiniRtns( 0, 255 ); } break; case DLL_THREAD_DETACH: __RdosRemoveThread(); break; case DLL_PROCESS_DETACH: __FiniRtns( 0, FINI_PRIORITY_EXIT - 1 ); __RdosRemoveThread(); RdosFreeMem( __FirstThreadData ); __FirstThreadData = NULL; break; } return( rc ); }
static DWORD WINAPI begin_thread_helper( thread_args *td ) /***********************************************************/ { thread_fnex *rtn; void *arg; REGISTRATION_RECORD rr; thread_data *tdata; DWORD rv; rtn = td->rtn; arg = td->argument; free( td ); if( !__Is_DLL ) { tdata = __alloca( __ThreadDataSize ); if( tdata == NULL ) return( 0 ); memset( tdata, 0, __ThreadDataSize ); // tdata->__allocated = 0; tdata->__data_size = __ThreadDataSize; if( !__NTAddThread( tdata ) ) { return( 0 ); } } __NewExceptionFilter( &rr ); __sig_init_rtn(); // fills in a thread-specific copy of signal table rv = (*rtn)( arg ); _endthreadex( rv ); return( rv ); }
static void APIENTRY begin_thread_helper( thread_args *td ) /*********************************************************/ { thread_fn *rtn; void *arg; EXCEPTIONREGISTRATIONRECORD xcpt; thread_data *tdata; rtn = td->rtn; arg = td->argument; tdata = __alloca( __ThreadDataSize ); memset( tdata, 0, __ThreadDataSize ); // tdata->__allocated = 0; tdata->__data_size = __ThreadDataSize; if( !__Is_DLL ) { if( !__OS2AddThread( *_threadid, tdata ) ) return; } DosPostEventSem( td->event ); _fpreset(); __XCPTHANDLER = &xcpt; __sig_init_rtn(); (*rtn)( arg ); _endthread(); }
static DWORD WINAPI begin_thread_helper( thread_args *td ) /********************************************************/ { thread_fn *rtn; void *arg; REGISTRATION_RECORD rr; thread_data *tdata; HANDLE thread_handle; rtn = td->rtn; arg = td->argument; thread_handle = td->thread_handle; free( td ); // For DLLs, __NTAddThread has already been called from _LibMain // in DLL_THREAD_ATTACH processing. if( !__Is_DLL ) { // allocate thread_data structure on stack tdata = __alloca( __ThreadDataSize ); if ( tdata ) { memset( tdata, 0, __ThreadDataSize ); // tdata->__allocated = 0; tdata->__data_size = __ThreadDataSize; // do further thread_data initialization and registration if( !__NTAddThread( tdata ) ) { // print runtime error message now ? CloseHandle( thread_handle ); return( 0 ); } } } // now get the thread_data ptr the 'standard' way -- this may cause // a new thread_data structure to be allocated on heap: // by __GetThreadPtr() ==> __MultipleThread(){ TlsGetValue(); if NULL ==> // __GetThreadData() ==> __NTAddThread() ==> __AllocInitThreadData() } tdata = __THREADDATAPTR; if ( !tdata ) { // this is a library runtime error, should we print an error message ? CloseHandle( thread_handle ); return( 0 ); } tdata->thread_handle = thread_handle; __NewExceptionFilter( &rr ); __sig_init_rtn(); // fills in a thread-specific copy of signal table (*rtn)( arg ); _endthread(); return( 0 ); }
static void begin_thread_helper( void *param ) /********************************************************/ { thread_args *td = (thread_args *)param; thread_fn *rtn; void *arg; thread_data *tdata; int thread_handle; REGISTRATION_RECORD rr; td->tid = RdosGetThreadHandle(); rtn = td->rtn; arg = td->argument; thread_handle = td->thread_handle; RdosSetSignal( td->signal ); tdata = (thread_data *)RdosAllocateMem( __ThreadDataSize ); if( tdata != NULL ) { memset( tdata, 0, __ThreadDataSize ); tdata->__data_size = __ThreadDataSize; if( !__RdosAddThread( tdata ) ) { // print runtime error message now ? return; } } // now get the thread_data ptr the 'standard' way -- this may cause // a new thread_data structure to be allocated on heap: tdata = __THREADDATAPTR; if( tdata == NULL ) { // this is a library runtime error, should we print an error message ? return; } __NewExceptionFilter( &rr ); __sig_init_rtn(); // fills in a thread-specific copy of signal table (*rtn)( arg ); _endthread(); RdosFreeMem(tdata); return; }
void __OS2MainInit( EXCEPTIONREGISTRATIONRECORD *xcpt, void *ptr, unsigned hmod, char *env, char *cmd ) /*******************************************************/ { thread_data *tdata; char *args; char *cmd_path; tdata = ptr; for( args = cmd; *args != '\0'; ++args ); /* skip over program name */ ++args; _RWD_Envptr = env; _LpCmdLine = args; #ifdef _UNICODE _LpwCmdLine = lib_malloc( (strlen( _LpCmdLine ) + 1) * sizeof( wchar_t ) ); _atouni( _LpwCmdLine, _LpCmdLine ); #endif for( cmd_path = cmd - 2; *cmd_path != '\0'; --cmd_path ); ++cmd_path; _LpPgmName = cmd_path; #ifdef _UNICODE _LpwPgmName = lib_malloc( (strlen( _LpPgmName ) + 1) * sizeof( wchar_t ) ); _atouni( _LpwPgmName, _LpPgmName ); #endif __hmodule = hmod; __OS2Init( FALSE, tdata ); /* initializers must be executed before signals initialized since __sig_init_rtn may get set by an initializer */ __InitRtns( INIT_PRIORITY_LIBRARY ); __XCPTHANDLER = xcpt; __sig_init_rtn(); #ifndef __SW_BM _STACKLOW = (unsigned)&_end; #endif __InitRtns( 255 ); }
int APIENTRY _LibMain( HANDLE hdll, DWORD reason, LPVOID reserved ) { int rc; static int processes; switch( reason ) { case DLL_THREAD_ATTACH: #ifndef __SW_BR if( !__NTAddThread( NULL ) ) { return( FALSE ); } #endif rc = LibMain( hdll, reason, reserved ); break; case DLL_PROCESS_ATTACH: ++processes; if( processes > 1 ) { if( __disallow_single_dgroup( hdll ) ) { rc = FALSE; break; } } #ifdef __SW_BR __Is_DLL = 1; __InitRtns( INIT_PRIORITY_EXIT - 1 ); #else // The following initializers are called: (in the CLIB run-time DLL): // nothing is called __InitRtns( INIT_PRIORITY_THREAD ); // allocate some thread data storage and initialize run-time variables { thread_data *tdata = __AllocInitThreadData( NULL ); if( !tdata || !__NTInit( TRUE, tdata, hdll ) ) { rc = FALSE; break; } } // set up TLSIndex thingee if( !__NTThreadInit() ) { // safe to call multiple times rc = FALSE; break; } // The following initializers are called: (in the CLIB run-time DLL): // __chk8087 // __verify_pentium_fdiv_bug // __Init_Argv // __imthread_fn (which calls _NTThreadInit and __InitMultipleThread) __InitRtns( INIT_PRIORITY_EXIT - 1 ); // sets up semaphores and starts linked list of thread data storage __InitMultipleThread(); // now safe to call multiple times #endif if( _pRawDllMain != NULL ) { if( !_pRawDllMain( hdll, reason, reserved ) ) { __FiniRtns( 0, FINI_PRIORITY_EXIT - 1 ); rc = FALSE; break; } } // The following initializers are called: (in the CLIB run-time DLL): // profilog_init // __InitWinLinesSem // dbgdata@do_it // __setenvp // __mbInitOnStartup // __sig_init // (??) in STK // __InitFiles // __clock_init __InitRtns( 255 ); #ifdef __SW_BR { static char fn[_MAX_PATH]; __lib_GetModuleFileNameA( hdll, fn, sizeof( fn ) ); _LpDllName = fn; } { static wchar_t wfn[_MAX_PATH]; __lib_GetModuleFileNameW( hdll, wfn, sizeof( wfn ) ); _LpwDllName = wfn; } #endif __CommonInit(); __sig_init_rtn(); rc = LibMain( hdll, reason, reserved ); if( !rc ) { __FiniRtns( 0, 255 ); } break; case DLL_THREAD_DETACH: rc = LibMain( hdll, reason, reserved ); #ifndef __SW_BR __NTRemoveThread( TRUE ); #endif break; case DLL_PROCESS_DETACH: rc = LibMain( hdll, reason, reserved ); __FiniRtns( FINI_PRIORITY_EXIT, 255 ); if( _pRawDllMain != NULL ) { _pRawDllMain( hdll, reason, reserved ); } #ifndef __SW_BR __NTFini(); // must be done before following finalizers get called #endif __FiniRtns( 0, FINI_PRIORITY_EXIT - 1 ); #ifndef __SW_BR __NTRemoveThread( TRUE ); __FreeInitThreadData( __FirstThreadData ); __FirstThreadData = NULL; #endif --processes; } return( rc ); }