Browse Source

* Windows platforms: always start a thread in suspended state and resume it later in AfterConstruction if necessary, prevents race conditions in constructor. Fixes Mantis #16884 on Windows.

git-svn-id: trunk@16091 -
sergei 15 năm trước cách đây
mục cha
commit
a66876704b
3 tập tin đã thay đổi với 9 bổ sung6 xóa
  1. 1 1
      rtl/objpas/classes/classes.inc
  2. 4 0
      rtl/objpas/classes/classesh.inc
  3. 4 5
      rtl/win/tthread.inc

+ 1 - 1
rtl/objpas/classes/classes.inc

@@ -127,7 +127,7 @@ begin
 // enable for all platforms once http://bugs.freepascal.org/view.php?id=16884
 // is fixed for all platforms (in case the fix for non-unix platforms also
 // requires this field at least)
-{$ifdef unix}
+{$if defined(unix) or defined(windows)}
   if not FInitialSuspended then
     Resume;
 {$endif}

+ 4 - 0
rtl/objpas/classes/classesh.inc

@@ -1488,6 +1488,10 @@ type
     procedure Synchronize(AMethod: TThreadMethod);
     property ReturnValue: Integer read FReturnValue write FReturnValue;
     property Terminated: Boolean read FTerminated;
+{$ifdef windows}
+  private
+    FInitialSuspended: boolean;
+{$endif}
 {$ifdef Unix}
   private
     // see tthread.inc, ThreadFunc and TThread.Resume

+ 4 - 5
rtl/win/tthread.inc

@@ -11,14 +11,13 @@ type
 
 constructor TThread.Create(CreateSuspended: Boolean;
                            const StackSize: SizeUInt = DefaultStackSize);
-var
-  Flags: Integer;
 begin
   inherited Create;
   FSuspended := CreateSuspended;
-  Flags := 0;
-  if CreateSuspended then Flags := CREATE_SUSPENDED;
-  FHandle := BeginThread(nil, StackSize, @ThreadProc, pointer(self), Flags,
+  FInitialSuspended := CreateSuspended;
+  { Always start in suspended state, will be resumed in AfterConstruction if necessary
+    See Mantis #16884 }
+  FHandle := BeginThread(nil, StackSize, @ThreadProc, pointer(self), CREATE_SUSPENDED,
                          FThreadID);
   if FHandle = TThreadID(0) then
     raise EThread.create('Failed to create new thread, code:'+inttostr(getlasterror));