Browse Source

--- Merging r13571 into '.':
U rtl\win\systhrd.inc
--- Merging r13608 into '.':
G rtl\win\systhrd.inc
--- Merging r13648 into '.':
U rtl\win\syswin.inc
G rtl\win\systhrd.inc

git-svn-id: branches/fixes_2_4@13649 -

florian 16 years ago
parent
commit
51b38b90f5
2 changed files with 36 additions and 19 deletions
  1. 27 16
      rtl/win/systhrd.inc
  2. 9 3
      rtl/win/syswin.inc

+ 27 - 16
rtl/win/systhrd.inc

@@ -72,8 +72,8 @@ CONST
     const
     const
       threadvarblocksize : dword = 0;
       threadvarblocksize : dword = 0;
 
 
-    var
-      TLSKey : Dword;
+    const
+      TLSKey : DWord = $ffffffff;
 
 
     procedure SysInitThreadvar(var offset : dword;size : dword);
     procedure SysInitThreadvar(var offset : dword;size : dword);
       begin
       begin
@@ -104,14 +104,22 @@ CONST
       var
       var
         dataindex : pointer;
         dataindex : pointer;
         errorsave : dword;
         errorsave : dword;
-      begin
+      begin	    
 {$ifdef dummy}
 {$ifdef dummy}
-        { I've no clue why this doesn't read dataindex, imo it should (FK) }
+        { it least in the on windows 7 x64, this still doesn't not work, fs:(0x2c) is
+          self referencing on this system (FK) }
         asm
         asm
           movl TLSKey,%edx
           movl TLSKey,%edx
-          movl $0x2c,%eax
-          movl %fs:(%eax),%eax
-          movl (%eax,%edx,4),%eax
+          movl %fs:(0x2c),%eax
+          orl  %eax,%eax
+          jnz  .LAddressInEAX
+		  { this works on Windows 7, but I don't know if it works on other OSes (FK) }
+          movl %fs:(0x18),%eax
+          movl 0xe10(%eax,%edx,4),%eax
+          jmp  .LToDataIndex
+          .LAddressInEAX:
+           movl (%eax,%edx,4),%eax
+          .LToDataIndex:
           movl %eax,dataindex
           movl %eax,dataindex
         end;
         end;
         if DataIndex=nil then
         if DataIndex=nil then
@@ -179,11 +187,14 @@ CONST
     procedure SysInitMultithreading;
     procedure SysInitMultithreading;
       begin
       begin
         { do not check IsMultiThread, as program could have altered it, out of Delphi habit }
         { do not check IsMultiThread, as program could have altered it, out of Delphi habit }
-        if TLSKey = 0 then
+        
+        { the thread attach/detach code uses locks to avoid multiple calls of this }
+        if TLSKey=$ffffffff then
          begin
          begin
            { We're still running in single thread mode, setup the TLS }
            { We're still running in single thread mode, setup the TLS }
            TLSKey:=TlsAlloc;
            TLSKey:=TlsAlloc;
            InitThreadVars(@SysRelocateThreadvar);
            InitThreadVars(@SysRelocateThreadvar);
+		   { allocate the thread vars for the main thread }
            IsMultiThread:=true;
            IsMultiThread:=true;
          end;
          end;
       end;
       end;
@@ -191,10 +202,10 @@ CONST
     procedure SysFiniMultithreading;
     procedure SysFiniMultithreading;
       begin
       begin
         if IsMultiThread then
         if IsMultiThread then
-         begin
-           TlsFree(TLSKey);
-           TLSKey := 0;
-         end;
+          begin
+            TlsFree(TLSKey);
+            TLSKey:=$ffffffff;
+          end;
       end;
       end;
 
 
     function SysBeginThread(sa : Pointer;stacksize : ptruint;
     function SysBeginThread(sa : Pointer;stacksize : ptruint;
@@ -333,10 +344,10 @@ end;
 
 
 
 
 Const
 Const
-        wrSignaled = 0;
-        wrTimeout  = 1;
-        wrAbandoned= 2;
-        wrError    = 3;
+  wrSignaled = 0;
+  wrTimeout  = 1;
+  wrAbandoned= 2;
+  wrError    = 3;
 
 
 type Tbasiceventstate=record
 type Tbasiceventstate=record
                         fhandle    : THandle;
                         fhandle    : THandle;

+ 9 - 3
rtl/win/syswin.inc

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