* allow only one thread at a time to attach on a dll so the tls slot is allocated properly, resolves #12987

git-svn-id: trunk@13648 -
This commit is contained in:
florian 2009-09-05 13:41:09 +00:00
parent 621ebe240e
commit 2f8e263560
2 changed files with 19 additions and 11 deletions

View File

@ -187,6 +187,8 @@ CONST
procedure SysInitMultithreading;
begin
{ do not check IsMultiThread, as program could have altered it, out of Delphi habit }
{ the thread attach/detach code uses locks to avoid multiple calls of this }
if TLSKey=$ffffffff then
begin
{ We're still running in single thread mode, setup the TLS }
@ -200,10 +202,10 @@ CONST
procedure SysFiniMultithreading;
begin
if IsMultiThread then
begin
TlsFree(TLSKey);
TLSKey:=$ffffffff;
end;
begin
TlsFree(TLSKey);
TLSKey:=$ffffffff;
end;
end;
function SysBeginThread(sa : Pointer;stacksize : ptruint;
@ -342,10 +344,10 @@ end;
Const
wrSignaled = 0;
wrTimeout = 1;
wrAbandoned= 2;
wrError = 3;
wrSignaled = 0;
wrTimeout = 1;
wrAbandoned= 2;
wrError = 3;
type Tbasiceventstate=record
fhandle : THandle;

View File

@ -24,6 +24,8 @@ Const
Var
DLLBuf : Jmp_buf;
MainThreadIdWin32 : DWORD;
AttachingThread : TRTLCriticalSection;
function Dll_entry{$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}(const info : TEntryInformation){$endif FPC_HAS_INDIRECT_MAIN_INFORMATION} : longbool; [public,alias:'_FPC_DLL_Entry'];
var
@ -37,6 +39,7 @@ function Dll_entry{$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}(const info : TEntry
case DLLreason of
DLL_PROCESS_ATTACH :
begin
WinInitCriticalSection(AttachingThread);
MainThreadIdWin32 := Win32GetCurrentThreadId;
If SetJmp(DLLBuf) = 0 then
begin
@ -59,7 +62,8 @@ function Dll_entry{$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}(const info : TEntry
DLL_THREAD_ATTACH :
begin
inclocked(Thread_count);
WinEnterCriticalSection(AttachingThread);
if (Win32GetCurrentThreadId <> MainThreadIdWin32) then
begin
{ Set up TLS slot for the DLL }
@ -73,14 +77,15 @@ 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;
WinLeaveCriticalSection(AttachingThread);
end;
DLL_THREAD_DETACH :
begin
declocked(Thread_count);
if assigned(Dll_Thread_Detach_Hook) then
Dll_Thread_Detach_Hook(DllParam);
{ Release Threadvars }
if (Win32GetCurrentThreadId <> MainThreadIdWin32) then
if (Win32GetCurrentThreadId<>MainThreadIdWin32) then
DoneThread; { Assume everything is idempotent there }
Dll_entry:=true; { return value is ignored }
end;
@ -94,6 +99,7 @@ function Dll_entry{$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}(const info : TEntry
{ Free TLS resources used by ThreadVars }
SysFiniMultiThreading;
WinDoneCriticalSection(AttachingThread);
end;
end;
end;