diff --git a/rtl/inc/thread.inc b/rtl/inc/thread.inc index fda06c3790..697a7b90da 100644 --- a/rtl/inc/thread.inc +++ b/rtl/inc/thread.inc @@ -71,7 +71,11 @@ Var { Open all stdio fds again } SysFlushStdio; {$endif FPC_HAS_FEATURE_CONSOLEIO} - CurrentTM.ReleaseThreadVars; + { Support platforms where threadvar memory is managed outside of the RTL: + reset ThreadID and allow ReleaseThreadVars to be unassigned } + ThreadID := 0; + if assigned(CurrentTM.ReleaseThreadVars) then + CurrentTM.ReleaseThreadVars; end; {***************************************************************************** diff --git a/rtl/win/systhrd.inc b/rtl/win/systhrd.inc index 58d6f14dfb..91a16f93e6 100644 --- a/rtl/win/systhrd.inc +++ b/rtl/win/systhrd.inc @@ -121,10 +121,14 @@ var { these aren't allocated yet ... } { allocate room on the heap for the thread vars } errorsave:=GetLastError; + if tlskey=$ffffffff then + RunError(226); dataindex:=TlsGetValue(tlskey); if dataindex=nil then begin dataindex:=pointer(LocalAlloc(LMEM_FIXED or LMEM_ZEROINIT,threadvarblocksize)); + if dataindex=nil then + RunError(226); TlsSetValue(tlskey,dataindex); end; SetLastError(errorsave); @@ -150,11 +154,9 @@ var procedure SysFiniMultithreading; begin - if IsMultiThread then - begin - TlsFree(TLSKey); - TLSKey:=$ffffffff; - end; + if TLSKey<>$ffffffff then + TlsFree(TLSKey); + TLSKey:=$ffffffff; end; function SysRelocateThreadvar(offset : dword) : pointer; @@ -176,9 +178,16 @@ var procedure SysReleaseThreadVars; + var + p: pointer; begin - LocalFree(TlsGetValue(tlskey)); - TlsSetValue(tlskey, nil); + if TLSKey<>$ffffffff then + begin + p:=TlsGetValue(tlskey); + if Assigned(p) then + LocalFree(p); + TlsSetValue(tlskey, nil); + end; end; diff --git a/rtl/win/syswin.inc b/rtl/win/syswin.inc index 12d727c99e..b34e50b6ca 100644 --- a/rtl/win/syswin.inc +++ b/rtl/win/syswin.inc @@ -30,7 +30,7 @@ function Dll_entry{$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}(const info : TEntry EntryInformation:=info; {$endif FPC_HAS_INDIRECT_MAIN_INFORMATION} IsLibrary:=true; - Dll_entry:=false; + Dll_entry:=false; { return value is ignored, except when DLLreason=DLL_PROCESS_ATTACH } case DLLreason of DLL_PROCESS_ATTACH : begin @@ -61,7 +61,6 @@ function Dll_entry{$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}(const info : TEntry if assigned(Dll_Thread_Attach_Hook) then Dll_Thread_Attach_Hook(DllParam); - Dll_entry:=true; { return value is ignored } end; DLL_THREAD_DETACH : begin @@ -70,11 +69,9 @@ function Dll_entry{$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}(const info : TEntry { Release Threadvars } if TlsGetValue(TLSKey)<>nil then DoneThread; { Assume everything is idempotent there } - Dll_entry:=true; { return value is ignored } end; DLL_PROCESS_DETACH : begin - Dll_entry:=true; { return value is ignored } if MainThreadIDWin32=0 then // already been here. exit; If SetJmp(DLLBuf) = 0 then @@ -82,7 +79,7 @@ function Dll_entry{$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}(const info : TEntry if assigned(Dll_Process_Detach_Hook) then Dll_Process_Detach_Hook(DllParam); - DoneThread; + SysReleaseThreadVars; { Free TLS resources used by ThreadVars } SysFiniMultiThreading; MainThreadIDWin32:=0;