Ignore:
Timestamp:
Jun 11, 2002, 6:36:54 PM (23 years ago)
Author:
sandervl
Message:

thread linking + create TEB before thread creation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/thread.cpp

    r8463 r8648  
    1 /* $Id: thread.cpp,v 1.45 2002-05-22 12:57:17 sandervl Exp $ */
     1/* $Id: thread.cpp,v 1.46 2002-06-11 16:36:54 sandervl Exp $ */
    22
    33/*
     
    4545DWORD WIN32API GetCurrentThreadId()
    4646{
    47   // check cached identifier
    48   TEB *teb = GetThreadTEB();
    49   if(teb != NULL && teb->o.odin.threadId != 0xFFFFFFFF)
    50   {
    51     // this is set in InitializeTIB() already.
    52     return teb->o.odin.threadId;
    53   }
     47    // check cached identifier
     48    TEB *teb = GetThreadTEB();
     49    if(teb != NULL && teb->o.odin.threadId != 0xFFFFFFFF)
     50    {
     51        // this is set in InitializeTIB() already.
     52        return teb->o.odin.threadId;
     53    }
    5454 
    5555////  dprintf(("GetCurrentThreadId\n"));
    56   return MAKE_THREADID(O32_GetCurrentProcessId(), O32_GetCurrentThreadId());
     56    return MAKE_THREADID(O32_GetCurrentProcessId(), O32_GetCurrentThreadId());
    5757}
    5858//******************************************************************************
     
    6060HANDLE WIN32API GetCurrentThread()
    6161{
    62  TEB *teb;
     62    TEB *teb;
    6363
    6464    teb = GetThreadTEB();
    6565    if(teb == 0) {
    66         SetLastError(ERROR_INVALID_HANDLE); //todo
    67         return 0;
     66        SetLastError(ERROR_INVALID_HANDLE); //todo
     67        return 0;
    6868    }
    6969    return teb->o.odin.hThread;
     
    188188VOID WIN32API ExitThread(DWORD exitcode)
    189189{
    190  EXCEPTION_FRAME *exceptFrame;
    191  TEB             *teb;
    192 
    193   dprintf(("ExitThread %x (%x)", GetCurrentThread(), exitcode));
    194 
    195   teb = GetThreadTEB();
    196   if(teb != 0) {
    197         exceptFrame = (EXCEPTION_FRAME *)teb->o.odin.exceptFrame;
    198   }
    199   else  DebugInt3();
    200 
    201   HMSetThreadTerminated(GetCurrentThread());
    202   Win32DllBase::detachThreadFromAllDlls();    //send DLL_THREAD_DETACH message to all dlls
    203   Win32DllBase::tlsDetachThreadFromAllDlls(); //destroy TLS structures of all dlls
    204   if(WinExe)  WinExe->tlsDetachThread();      //destroy TLS structure of main exe
    205   DestroyTIB();
    206 
    207   if(exceptFrame) OS2UnsetExceptionHandler((void *)exceptFrame);
    208 
    209   O32_ExitThread(exitcode);
     190    EXCEPTION_FRAME *exceptFrame;
     191    TEB             *teb;
     192
     193    dprintf(("ExitThread %x (%x)", GetCurrentThread(), exitcode));
     194
     195    teb = GetThreadTEB();
     196    if(teb != 0) {
     197             exceptFrame = (EXCEPTION_FRAME *)teb->o.odin.exceptFrame;
     198    }
     199    else DebugInt3();
     200
     201    HMSetThreadTerminated(GetCurrentThread());
     202    Win32DllBase::detachThreadFromAllDlls();    //send DLL_THREAD_DETACH message to all dlls
     203    Win32DllBase::tlsDetachThreadFromAllDlls(); //destroy TLS structures of all dlls
     204    if(WinExe)  WinExe->tlsDetachThread();      //destroy TLS structure of main exe
     205
     206    if(teb) DestroyTEB(teb);
     207
     208    if(exceptFrame) OS2UnsetExceptionHandler((void *)exceptFrame);
     209
     210    O32_ExitThread(exitcode);
    210211}
    211212/*****************************************************************************
     
    223224 * Result    : TRUE / FALSE
    224225 * Remark    :
    225  * Status    : UNTESTED STUB
    226  *
    227  * Author    : Patrick Haller [Mon, 1998/06/15 08:00]
     226 * Status    : Fully functional
     227 *
     228 * Author    : SvL
    228229 *****************************************************************************/
    229230
     
    231232                                     DWORD  dwThreadAffinityMask)
    232233{
    233   dprintf(("KERNEL32: SetThreadAffinityMask(%08xh,%08xh)",
    234            hThread, dwThreadAffinityMask));
    235 
    236   if(hThread != GetCurrentThread()) {
    237       dprintf(("WARNING: Setting the affinity mask for another thread than the current one is not supported!!"));
    238       return FALSE;
    239   }
    240   return OSLibDosSetThreadAffinity(dwThreadAffinityMask);
     234    dprintf(("KERNEL32: SetThreadAffinityMask(%08xh,%08xh)", hThread, dwThreadAffinityMask));
     235
     236    if(hThread != GetCurrentThread()) {
     237        dprintf(("WARNING: Setting the affinity mask for another thread than the current one is not supported!!"));
     238        return FALSE;
     239    }
     240    return OSLibDosSetThreadAffinity(dwThreadAffinityMask);
    241241}
    242242//******************************************************************************
     
    268268Win32Thread::Win32Thread(LPTHREAD_START_ROUTINE pUserCallback, LPVOID lpData, DWORD dwFlags, HANDLE hThread)
    269269{
    270   lpUserData = lpData;
    271   pCallback  = pUserCallback;
    272   this->dwFlags = dwFlags;
    273   this->hThread = hThread;
     270    lpUserData = lpData;
     271    pCallback  = pUserCallback;
     272    this->dwFlags = dwFlags;
     273    this->hThread = hThread;
     274
     275    teb = CreateTEB(hThread, 0xFFFFFFFF);
     276    if(teb == NULL) {
     277        DebugInt3();
     278    }
    274279}
    275280//******************************************************************************
     
    277282DWORD OPEN32API Win32ThreadProc(LPVOID lpData)
    278283{
    279  EXCEPTION_FRAME exceptFrame;
    280  Win32Thread     *me = (Win32Thread *)lpData;
    281  ULONG            threadCallback = (ULONG)me->pCallback;
    282  LPVOID           userdata  = me->lpUserData;
    283  HANDLE           hThread   = me->hThread;
    284  DWORD            rc;
    285 
    286   delete(me);    //only called once
    287   dprintf(("Win32ThreadProc %x\n", GetCurrentThreadId()));
    288 
    289   TEB *winteb = (TEB *)InitializeTIB();
    290   if(winteb == NULL) {
    291         dprintf(("Win32ThreadProc: InitializeTIB failed!!"));
    292         DebugInt3();
    293         return 0;
    294   }
    295   winteb->flags = me->dwFlags;
    296 
    297   winteb->entry_point = (void *)threadCallback;
    298   winteb->entry_arg   = (void *)userdata;
    299   winteb->o.odin.hThread = hThread;
    300 
    301   winteb->o.odin.hab = OSLibWinInitialize();
    302   winteb->o.odin.hmq = OSLibWinQueryMsgQueue(winteb->o.odin.hab);
    303   dprintf(("Win32ThreadProc: hab %x hmq %x", winteb->o.odin.hab, winteb->o.odin.hmq));
    304 #ifdef DEBUG
    305   TEB *teb = GetThreadTEB();
    306   dprintf(("Stack top 0x%x, stack end 0x%x", teb->stack_top, teb->stack_low));
    307 #endif
    308 
    309   //Note: The Win32 exception structure referenced by FS:[0] is the same
    310   //      in OS/2
    311   OS2SetExceptionHandler((void *)&exceptFrame);
    312   winteb->o.odin.exceptFrame = (ULONG)&exceptFrame;
    313 
    314   //Determine if thread callback is inside a PE dll; if true, then force
    315   //switch to win32 TIB (FS selector)
    316   //(necessary for Opera when loading win32 plugins that create threads)
    317   Win32DllBase *dll;
    318   dll = Win32DllBase::findModuleByAddr(threadCallback);
    319   if(dll && dll->isPEImage()) {
    320        dprintf(("Win32ThreadProc: Force win32 TIB switch"));
    321        SetWin32TIB(TIB_SWITCH_FORCE_WIN32);
    322   }
    323   else SetWin32TIB(TIB_SWITCH_DEFAULT); //executable type determines whether or not FS is changed
    324 
    325   DWORD dwProcessAffinityMask, dwSystemAffinityMask;
    326 
    327   //Change the affinity mask of this thread to the mask for the whole process
    328   if(GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask) == TRUE) {
    329       SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
    330   }
    331 
    332   if(WinExe) WinExe->tlsAttachThread();     //setup TLS structure of main exe
    333   Win32DllBase::tlsAttachThreadToAllDlls(); //setup TLS structures of all dlls
    334   Win32DllBase::attachThreadToAllDlls();    //send DLL_THREAD_ATTACH message to all dlls
    335 
    336   //Set FPU control word to 0x27F (same as in NT)
    337   CONTROL87(0x27F, 0xFFF);
    338   rc = AsmCallThreadHandler(threadCallback, userdata);
    339 
    340   if(fExitProcess) {
    341       OSLibDosExitThread(rc);
    342   }
    343   else {
    344       HMSetThreadTerminated(GetCurrentThread());
    345       winteb->o.odin.exceptFrame = 0;
    346       Win32DllBase::detachThreadFromAllDlls();  //send DLL_THREAD_DETACH message to all dlls
    347       Win32DllBase::tlsDetachThreadFromAllDlls(); //destroy TLS structures of all dlls
    348       if(WinExe) WinExe->tlsDetachThread();               //destroy TLS structure of main exe
    349       DestroyTIB();  //destroys TIB and restores FS
    350       OS2UnsetExceptionHandler((void *)&exceptFrame);
    351   }
    352 
    353   return rc;
    354 }
    355 //******************************************************************************
    356 //******************************************************************************
     284    EXCEPTION_FRAME  exceptFrame;
     285    Win32Thread     *me = (Win32Thread *)lpData;
     286    ULONG            threadCallback = (ULONG)me->pCallback;
     287    LPVOID           userdata  = me->lpUserData;
     288    DWORD            rc;
     289    TEB             *winteb    = (TEB *)me->teb;
     290
     291    delete(me);    //only called once
     292
     293    if(InitializeThread(winteb) == FALSE) {
     294            dprintf(("Win32ThreadProc: InitializeTIB failed!!"));
     295            DebugInt3();
     296            return 0;
     297    }
     298    dprintf(("Win32ThreadProc %x\n", GetCurrentThreadId()));
     299
     300    winteb->flags = me->dwFlags;
     301
     302    winteb->entry_point = (void *)threadCallback;
     303    winteb->entry_arg   = (void *)userdata;
     304
     305    winteb->o.odin.hab = OSLibWinInitialize();
     306    winteb->o.odin.hmq = OSLibWinQueryMsgQueue(winteb->o.odin.hab);
     307    dprintf(("Win32ThreadProc: hab %x hmq %x", winteb->o.odin.hab, winteb->o.odin.hmq));
     308    dprintf(("Stack top 0x%x, stack end 0x%x", winteb->stack_top, winteb->stack_low));
     309
     310    //Note: The Win32 exception structure referenced by FS:[0] is the same
     311    //      in OS/2
     312    OS2SetExceptionHandler((void *)&exceptFrame);
     313    winteb->o.odin.exceptFrame = (ULONG)&exceptFrame;
     314   
     315    //Determine if thread callback is inside a PE dll; if true, then force
     316    //switch to win32 TIB (FS selector)
     317    //(necessary for Opera when loading win32 plugins that create threads)
     318    Win32DllBase *dll;
     319    dll = Win32DllBase::findModuleByAddr(threadCallback);
     320    if(dll && dll->isPEImage()) {
     321         dprintf(("Win32ThreadProc: Force win32 TIB switch"));
     322         SetWin32TIB(TIB_SWITCH_FORCE_WIN32);
     323    }
     324    else SetWin32TIB(TIB_SWITCH_DEFAULT); //executable type determines whether or not FS is changed
     325
     326    DWORD dwProcessAffinityMask, dwSystemAffinityMask;
     327
     328    //Change the affinity mask of this thread to the mask for the whole process
     329    if(GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask) == TRUE) {
     330        SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
     331    }
     332
     333    if(WinExe) WinExe->tlsAttachThread();           //setup TLS structure of main exe
     334    Win32DllBase::tlsAttachThreadToAllDlls(); //setup TLS structures of all dlls
     335    Win32DllBase::attachThreadToAllDlls();    //send DLL_THREAD_ATTACH message to all dlls
     336
     337    //Set FPU control word to 0x27F (same as in NT)
     338    CONTROL87(0x27F, 0xFFF);
     339    rc = AsmCallThreadHandler(threadCallback, userdata);
     340
     341    if(fExitProcess) {
     342        OSLibDosExitThread(rc);
     343    }
     344    else {
     345        HMSetThreadTerminated(GetCurrentThread());
     346        winteb->o.odin.exceptFrame = 0;
     347        Win32DllBase::detachThreadFromAllDlls();  //send DLL_THREAD_DETACH message to all dlls
     348        Win32DllBase::tlsDetachThreadFromAllDlls(); //destroy TLS structures of all dlls
     349        if(WinExe) WinExe->tlsDetachThread();             //destroy TLS structure of main exe
     350        DestroyTEB(winteb);  //destroys TIB and restores FS
     351        OS2UnsetExceptionHandler((void *)&exceptFrame);
     352    }
     353
     354    return rc;
     355}
     356//******************************************************************************
     357//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.