Esempio n. 1
2
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 );
}
Esempio n. 2
0
int __CBeginThread( thread_fn *start_addr, int prio, const char *thread_name,
                         unsigned stack_size, void *arglist )
/************************************************************/
{
    thread_args *td;
    int         th;

    __InitMultipleThread();

    td = malloc( sizeof( *td ) );
    if( td == NULL ) {
        return( -1L );
    }

    td->rtn = start_addr;
    td->argument = arglist;
    td->signal = RdosGetThreadHandle();
    RdosClearSignal();

    RdosCreateKernelThread( prio, stack_size, begin_thread_helper, thread_name, td );

    RdosWaitForSignal();
    th = td->tid;
    free( td );

    return( th );
}
Esempio n. 3
0
int __CBeginThread( thread_fn *start_addr, void *stack_bottom,
                    unsigned stack_size, void *arglist )
/******************************************************/
{
    TID         tid;
    APIRET      rc;
    thread_args td;

    if( __ThreadData == NULL ) {
        if( __InitThreadProcessing() == NULL )  return( -1 );
        __InitMultipleThread();
    }
    stack_bottom = stack_bottom;
    td.rtn = start_addr;
    td.argument = arglist;
    rc = DosCreateEventSem( NULL, &td.event, 0, 0 );
    if( rc != 0 ) return( -1 );
    rc = DosCreateThread( &tid, (PFNTHREAD)begin_thread_helper, (ULONG)&td,
                          0, stack_size + __threadstksize );
    if( rc != 0 ) {
        tid = -1;
    } else {
        /*
           suspend parent thread so that it can't call _beginthread() again
           before new thread extracts data from "td" (no problem if new
           thread calls _beginthread() since it has its own stack)
        */
        DosWaitEventSem( td.event, SEM_INDEFINITE_WAIT );
    }
    DosCloseEventSem( td.event );
    return( tid );
}
Esempio n. 4
0
unsigned long __CBeginThreadEx(
    void *security,
    unsigned stack_size,
    thread_fnex *start_addr,
    void *arglist,
    unsigned initflag,
    unsigned *thrdaddr )
{

    thread_args *td;
    HANDLE      th;

    if( __TlsIndex == NO_INDEX ) {
        if( !__NTThreadInit() )
            return( 0 );
        __InitMultipleThread();
    }

    td = malloc( sizeof( *td ) );
    if( td == NULL ) {
        _RWD_errno = ENOMEM;
        return( 0 );
    }

    stack_size = __ROUND_UP_SIZE_4K( stack_size );

    td->rtn = start_addr;
    td->argument = arglist;

    th = CreateThread(
        (LPSECURITY_ATTRIBUTES)security,
        (DWORD)stack_size,
        (LPTHREAD_START_ROUTINE)&begin_thread_helper,
        (LPVOID) td,
        (DWORD)initflag,
        (LPDWORD)thrdaddr );

    if( th == NULL )
        free( td );

    return( (unsigned long)th );
}
Esempio n. 5
0
 static void __imthread_fn( void ) {
 #if defined(__NT__)
     if( !__NTThreadInit() )
         return;
 #elif defined(_NETWARE_LIB)
     if( !__LibCThreadInit() )
         return;
 #elif defined(__QNX__)
 #elif defined(__LINUX__)
 #elif defined(__WARP__)
     if( __InitThreadProcessing() == 0 )
         return;
 #elif defined(__RDOS__)            
     if( !__RdosThreadInit() )
         return;
 #endif
 #if !defined(__LINUX__)
     __InitMultipleThread();
 #endif
 }
Esempio n. 6
0
int __CBeginThread( thread_fn *start_addr, int prio, const char *thread_name,
                         unsigned stack_size, void *arglist )
/************************************************************/
{
    thread_args *td;
    int         th;
    int         wait_handle;

    if( __TlsIndex == NO_INDEX ) {
        if( !__RdosThreadInit() )
            return( -1L );
        __InitMultipleThread();
    }

    td = malloc( sizeof( *td ) );
    if( td == NULL ) {
        _RWD_errno = ENOMEM;
        return( -1L );
    }

    stack_size = __ROUND_UP_SIZE_4K( stack_size );

    wait_handle = RdosCreateWait();

    td->rtn = start_addr;
    td->argument = arglist;
    td->signal = RdosCreateSignal();
    RdosResetSignal( td->signal );
    RdosAddWaitForSignal( wait_handle, td->signal, 0 );

    __create_thread(begin_thread_helper, prio, thread_name, td, stack_size);

    RdosWaitForever( wait_handle );
    RdosFreeSignal( td->signal );
    RdosCloseWait( wait_handle );
    th = td->tid;
    free( td );

    return( th );
}
Esempio n. 7
0
int __CBeginThread( thread_fn *start_addr, void *stack_bottom,
                    unsigned stack_size, void *arglist )
/************************************************************/
{
    DWORD       tid;
    thread_args *td;
    HANDLE      th;

    stack_bottom = stack_bottom;    /* parameter not used for NT version */

    if( __TlsIndex == NO_INDEX ) {
        if( !__NTThreadInit() )
            return( -1L );
        __InitMultipleThread();
    }

    td = malloc( sizeof( *td ) );
    if( td == NULL ) {
        _RWD_errno = ENOMEM;
        return( -1L );
    }

    stack_size = __ROUND_UP_SIZE_4K( stack_size );

    td->rtn = start_addr;
    td->argument = arglist;

    th = CreateThread( NULL, stack_size, (LPTHREAD_START_ROUTINE)&begin_thread_helper,
                (LPVOID) td, CREATE_SUSPENDED, &tid );
    if( th ) {
        td->thread_handle = th;
        ResumeThread( th );
    } else {
        // we didn't create the thread so it isn't going to free this
        free( td );
        th = (HANDLE)-1L;
    }
    return( (int)th );
}
Esempio n. 8
0
extern int __CBeginThread(
    thread_fn *     start_addr,
    void *          stack_bottom,
    unsigned        stack_size,
    void *          arglist
    )
{
    begin_thread_data   data;
    int                 error;

    if( __NXSlotID == NO_INDEX ) {
        __InitMultipleThread();
    }

    data.start_addr     = start_addr;
    data.stack_bottom   = stack_bottom;
    data.arglist        = arglist;
    if( NULL == (data.semaphore = NXSemaAlloc( 0, NULL )) )
        return( -1 );

    /*
    //  We create the thread as detached (non-joinable) and
    //  to automatically clear context
    */

    if( data.cx = NXContextAlloc( (void (*)(void *))&begin_thread_helper, &data,NX_PRIO_MED, __SYS_ALLOCD_STACK, NX_CTX_NORMAL, &error ) ) {
        error = NXThreadCreate( data.cx, NX_THR_DETACHED |NX_THR_BIND_CONTEXT, &data.nxtid );
    }

    if( 0 == error ) {
        NXSemaWait( data.semaphore );
    } else {
        /* should we set errno here? */
        data.tid = -1;
    }
    NXSemaFree( data.semaphore );
    return( data.tid );
}
Esempio n. 9
0
/*****************************************************************************
//  Initialise runtime environemnt. Equivalent of old prelude
*****************************************************************************/
int     __init_environment( void *  reserved )
{
    int rc = -1;

    if(NULL == (NLMHandle = getnlmhandle()))
        return -1;

    if(NULL == (AllocRTag = AllocateResourceTag( NLMHandle, "OpenWatcom CLIB Memory", AllocSignature )))
        return -1;

    _saved_DS = __DS();

    /*
    //  Call initialisation routines where priority is <= 1 and set the
    //  initialisation finish level to 1
    */
    __InitRtns( INIT_PRIORITY_THREAD );
    InitFiniLevel = INIT_PRIORITY_THREAD;
    /*
    //  Initialise multiple thread support
    */
    if(__CreateFirstThreadData())
    {
        __InitMultipleThread();
        /*
        //  Call initiliation routines at priority 255 (all) and the set the
        //  initialisation finish level to 255
        */
        __InitRtns( 255 );
        InitFiniLevel = 255;
        /*
        //  Environment initialised.
        */
        rc = 0;
    }
    return( rc );
}
Esempio n. 10
0
int __CBeginThread( thread_fn *start_addr, void *stack_bottom,
                    unsigned stack_size, void *arglist )
/******************************************************/
{
    pid_t       pid;
    thread_args td;
    int         rc;

    if( stack_bottom == NULL ) {
        if( stack_size == 0 ) {
            stack_size = 1024*4;
        }
        stack_bottom = lib_calloc( stack_size, 1 );
        if( stack_bottom == NULL ) {
            _RWD_errno = ENOMEM;
            return( -1 );
        }
    }
    __InitMultipleThread();
    td.rtn = start_addr;
    td.argument = arglist;
    td.stack_bottom = stack_bottom;
    rc = __posix_sem_init( &td.event, 1, 0 );
    if( rc == -1 ) return( -1 );
    pid = tfork( stack_bottom, stack_size, begin_thread_helper, &td, 0 );
    if( pid != -1 ) {
        /*
           suspend parent thread so that it can't call _beginthread() again
           before new thread extracts data from "td" (no problem if new
           thread calls _beginthread() since it has its own stack)
        */
        __posix_sem_wait( &td.event );
    }
    __posix_sem_destroy( &td.event );
    return( pid );
}
Esempio n. 11
0
unsigned _LibMain( unsigned hmod, unsigned termination )
/******************************************************/
{
    static int  processes;
    unsigned    rc;

    if( termination != 0 ) {
        // If we're running with single DGROUP and tried to load
        // twice, do not run any termination code! Also reset the
        // process counter so that the already loaded DLL can
        // terminate properly
        if( processes > 1 ) {
            --processes;
            return( 0 );
        }
        rc = LibMain( hmod, termination );
        --processes;
#ifdef __SW_BR
        __FiniRtns( 0, 255 );
#else
        if( _LpwCmdLine ) {
            lib_free( _LpwCmdLine );
            _LpwCmdLine = NULL;
        }
        if( _LpwPgmName ) {
            lib_free( _LpwPgmName );
            _LpwPgmName = NULL;
        }
        __FiniRtns( FINI_PRIORITY_EXIT, 255 );
        // calls to free memory have to be done before semaphores closed
        __FreeInitThreadData( __FirstThreadData );
        __OS2Fini(); // must be done before following finalizers get called
        __FiniRtns( 0, FINI_PRIORITY_EXIT - 1 );
        __shutdown_stack_checking();
#endif
        return( rc );
    }
    ++processes;
    if( processes > 1 ) {
        if( __disallow_single_dgroup(hmod) ) {
            return( 0 );
        }
    }
    __hmodule = hmod;
#ifdef __SW_BR
    {
        static char     fname[_MAX_PATH];
        static wchar_t  wfname[_MAX_PATH];

        __Is_DLL = 1;
        __InitRtns( 255 );
        DosQueryModuleName( hmod, sizeof( fname ), fname );
        _LpDllName = fname;
        _LpwDllName = wfname;
        _atouni( _LpwDllName, _LpDllName );
    }
#else
    {
        PTIB        pptib;
        PPIB        pppib;
        unsigned    i;

        DosGetInfoBlocks( &pptib, &pppib );
        _RWD_Envptr = pppib->pib_pchenv;
        _LpCmdLine = pppib->pib_pchcmd;
        while( *_LpCmdLine ) {          // skip over program name
            _LpCmdLine++;
        }
        _LpCmdLine++;
        _LpwCmdLine = lib_malloc( (strlen( _LpCmdLine ) + 1) * sizeof( wchar_t ) );
        _atouni( _LpwCmdLine, _LpCmdLine );
        {
            // ugly stuff to deal with two copies of .exe name in the
            // environment space. apparently the OS fullpath name is
            // just before this one in the environment space
            char    *cmd_path;

            cmd_path = pppib->pib_pchcmd;
            for( cmd_path -= 2; *cmd_path != '\0'; --cmd_path );
            ++cmd_path;
            _LpPgmName = cmd_path;
            _LpwPgmName = lib_malloc( (strlen( _LpPgmName ) + 1) * sizeof( wchar_t ) );
            _atouni( _LpwPgmName, _LpPgmName );
        }
        __InitRtns( INIT_PRIORITY_THREAD );
        if( __InitThreadProcessing() == NULL )
            return( 0 );
        __OS2Init( TRUE, __AllocInitThreadData( NULL ) );
        for( i = 2; i <= __MaxThreads; i++ ) {
            if( !__OS2AddThread( i, NULL ) ) {
                return( 0 );
            }
        }
        __InitRtns( INIT_PRIORITY_EXIT - 1 );
        __InitMultipleThread();
        {
            static char     fname[_MAX_PATH];
            static wchar_t  wfname[_MAX_PATH];

            DosQueryModuleName( hmod, sizeof( fname ), fname );
            _LpDllName = fname;
            _LpwDllName = wfname;
            _atouni( _LpwDllName, _LpDllName );
        }
        __InitRtns( 255 );
    }
#endif
    __CommonInit();
#ifndef __SW_BR
    /* allocate alternate stack for F77 */
    __ASTACKPTR = (char *)_STACKLOW + __ASTACKSIZ;
#endif
    return( LibMain( hmod, termination ) );
}
Esempio n. 12
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 );
}