Jelajahi Sumber

* 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 -
florian 16 tahun lalu
induk
melakukan
2f8e263560
2 mengubah file dengan 19 tambahan dan 11 penghapusan
  1. 10 8
      rtl/win/systhrd.inc
  2. 9 3
      rtl/win/syswin.inc

+ 10 - 8
rtl/win/systhrd.inc

@@ -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;

+ 9 - 3
rtl/win/syswin.inc

@@ -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;