Пример #1
0
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 );
}
Пример #2
0
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 );
}
Пример #3
0
// lookup thread data
thread_data *__GetThreadData( void )
{
    thread_data *tdata = NULL;
    #ifdef __OS2__
        TID             tid;
        tid = GetCurrentThreadId();
        if( tid <= __MaxThreads ) {
            tdata = __AllocInitThreadData( tdata );
            if( tdata != NULL ) {
                if( __initthread( tdata ) ) {
                    __FreeInitThreadData( tdata );
                    tdata = NULL;
                } else {
                    __ThreadData[tid].data = tdata;
                    __ThreadData[tid].allocated_entry = tdata->__allocated;
                }
            }
        } else {
            thread_data_list *tdl;
            thread_data_list **pprev;

            _AccessTDList();
            tdata = NULL;
            pprev = &__thread_data_list;
            for( tdl = *pprev; tdl != NULL ; tdl = tdl->next ) {
                if( tdl->tid == tid ) {
                    tdata = tdl->data;
                    break;
                }
                pprev = &(tdl->next);
            }
            if( tdata == NULL ) {
                tdata = __AllocInitThreadData( tdata );
                if( tdata != NULL ) {
                    if( !__AddThreadData( tid, tdata ) ) {
                        __FreeInitThreadData( tdata );
                        tdata = NULL;
                    }
                }
            } else if( *pprev ) {
                // promote to front
                *pprev = tdl->next;
                tdl->next = __thread_data_list;
                __thread_data_list = tdl;
                // check for need to resize thread data
                if( tdata->__resize ) {
                    tdata = __ReallocThreadData();
                }
            }
            _ReleaseTDList();
        }
    #elif defined(__NT__)
        if( __NTAddThread( tdata ) ) 
        {
            tdata = (thread_data *)TlsGetValue( __TlsIndex );
        }
    #elif defined(_NETWARE_LIBC)
        if( __LibCAddThread( tdata ) )
        {
            if(0 != NXKeyGetValue(__NXSlotID, (void **) &tdata))
                tdata = NULL;
        }
    #elif defined(__RDOS__)
        if( __RdosAddThread( tdata ) ) 
        {
            tdata = (thread_data *)__tls_get_value( __TlsIndex );
        }
    #endif
    if( tdata == NULL ) {
        __fatal_runtime_error( "Thread has no thread-specific data", 1 );
    }
    return( tdata );
}
Пример #4
0
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 );
}