Browse Source

* fixed web bug #3387: if one called resume right after creating a
suspended thread, it was possible that resume was executed before
that thread had completed its initialisation in BeginThread ->
FInitialSuspended was set to false in resume and nevertheless a
semafore was posted
* second problem fixed: set FSuspended to false before waking up the
thread, so that it doesn't get FSuspended = true right after waking
up. This should be done atomically to be completely correct though.

Jonas Maebe 20 years ago
parent
commit
92a2ba07ad
5 changed files with 76 additions and 50 deletions
  1. 15 5
      rtl/darwin/tthread.inc
  2. 15 13
      rtl/freebsd/tthread.inc
  3. 16 6
      rtl/linux/tthread.inc
  4. 15 13
      rtl/netbsd/tthread.inc
  5. 15 13
      rtl/openbsd/tthread.inc

+ 15 - 5
rtl/darwin/tthread.inc

@@ -133,7 +133,8 @@ begin
   try
     if LThread.FInitialSuspended then begin
       SemaphoreWait(LThread.FSem);
-      if not LThread.FInitialSuspended then begin
+      if not LThread.FSuspended then begin
+        LThread.FInitialSuspended := false;
         WRITE_DEBUG('going into LThread.Execute');
         LThread.Execute;
       end;
@@ -231,13 +232,12 @@ procedure TThread.Resume;
 begin
   if (not FSuspendedExternal) then begin
     if FSuspended then begin
-      SemaphorePost(FSem);
-      FInitialSuspended := false;
       FSuspended := False;
+      SemaphorePost(FSem);
     end;
   end else begin
-    ResumeThread(FHandle);
     FSuspendedExternal := false;
+    ResumeThread(FHandle);
   end;
 end;
 
@@ -287,7 +287,17 @@ end;
 
 {
   $Log$
-  Revision 1.5  2005-02-25 21:41:09  florian
+  Revision 1.6  2005-03-01 20:38:49  jonas
+    * fixed web bug 3387: if one called resume right after creating a
+      suspended thread, it was possible that resume was executed before
+      that thread had completed its initialisation in BeginThread ->
+      FInitialSuspended was set to false in resume and nevertheless a
+      semafore was posted
+    * second problem fixed: set FSuspended to false before waking up the
+      thread, so that it doesn't get FSuspended = true right after waking
+      up. This should be done atomically to be completely correct though.
+
+  Revision 1.5  2005/02/25 21:41:09  florian
     * generic tthread.synchronize
     * delphi compatible wakemainthread
 

+ 15 - 13
rtl/freebsd/tthread.inc

@@ -414,7 +414,8 @@ begin
   try
     if LThread.FInitialSuspended then begin
       SemaphoreWait(LThread.FSem);
-      if not LThread.FInitialSuspended then begin
+      if not LThread.FSuspended then begin
+        LThread.FInitialSuspended := false;
         WRITE_DEBUG('going into LThread.Execute');
         LThread.Execute;
       end;
@@ -527,21 +528,12 @@ procedure TThread.Resume;
 begin
   if (not FSuspendedExternal) then begin
     if FSuspended then begin
-      SemaphorePost(FSem);
-      FInitialSuspended := false;
       FSuspended := False;
+      SemaphorePost(FSem);
     end;
   end else begin
-{$IFDEF LINUX}
-    // see .Suspend
-    if FPid <> GMainPID then begin
-      fpkill(FPid, SIGCONT);
-      FSuspended := False;
-    end;
-{$ELSE}
-    ResumeThread(FHandle);
-{$ENDIF}
     FSuspendedExternal := false;
+    ResumeThread(FHandle);
   end;
 end;
 
@@ -592,7 +584,17 @@ end;
 
 {
   $Log$
-  Revision 1.14  2005-02-25 21:41:09  florian
+  Revision 1.15  2005-03-01 20:38:49  jonas
+    * fixed web bug 3387: if one called resume right after creating a
+      suspended thread, it was possible that resume was executed before
+      that thread had completed its initialisation in BeginThread ->
+      FInitialSuspended was set to false in resume and nevertheless a
+      semafore was posted
+    * second problem fixed: set FSuspended to false before waking up the
+      thread, so that it doesn't get FSuspended = true right after waking
+      up. This should be done atomically to be completely correct though.
+
+  Revision 1.14  2005/02/25 21:41:09  florian
     * generic tthread.synchronize
     * delphi compatible wakemainthread
 

+ 16 - 6
rtl/linux/tthread.inc

@@ -144,7 +144,8 @@ begin
   try
     if LThread.FInitialSuspended then begin
       SemaphoreWait(LThread.FSem);
-      if not LThread.FInitialSuspended then begin
+      if not LThread.FSuspended then begin
+        LThread.FInitialSuspended := false;
         WRITE_DEBUG('going into LThread.Execute');
         LThread.Execute;
       end;
@@ -257,21 +258,20 @@ procedure TThread.Resume;
 begin
   if (not FSuspendedExternal) then begin
     if FSuspended then begin
-      SemaphorePost(FSem);
-      FInitialSuspended := false;
       FSuspended := False;
+      SemaphorePost(FSem);
     end;
   end else begin
+    FSuspendedExternal := false;
 {$IFDEF LINUX}
     // see .Suspend
     if FPid <> GMainPID then begin
-      fpkill(FPid, SIGCONT);
       FSuspended := False;
+      fpkill(FPid, SIGCONT);
     end;
 {$ELSE}
     ResumeThread(FHandle);
 {$ENDIF}
-    FSuspendedExternal := false;
   end;
 end;
 
@@ -321,7 +321,17 @@ end;
 
 {
   $Log$
-  Revision 1.13  2005-02-25 21:41:09  florian
+  Revision 1.14  2005-03-01 20:38:49  jonas
+    * fixed web bug 3387: if one called resume right after creating a
+      suspended thread, it was possible that resume was executed before
+      that thread had completed its initialisation in BeginThread ->
+      FInitialSuspended was set to false in resume and nevertheless a
+      semafore was posted
+    * second problem fixed: set FSuspended to false before waking up the
+      thread, so that it doesn't get FSuspended = true right after waking
+      up. This should be done atomically to be completely correct though.
+
+  Revision 1.13  2005/02/25 21:41:09  florian
     * generic tthread.synchronize
     * delphi compatible wakemainthread
 

+ 15 - 13
rtl/netbsd/tthread.inc

@@ -414,7 +414,8 @@ begin
   try
     if LThread.FInitialSuspended then begin
       SemaphoreWait(LThread.FSem);
-      if not LThread.FInitialSuspended then begin
+      if not LThread.FSuspended then begin
+        LThread.FInitialSuspended := false;
         WRITE_DEBUG('going into LThread.Execute');
         LThread.Execute;
       end;
@@ -527,21 +528,12 @@ procedure TThread.Resume;
 begin
   if (not FSuspendedExternal) then begin
     if FSuspended then begin
-      SemaphorePost(FSem);
-      FInitialSuspended := false;
       FSuspended := False;
+      SemaphorePost(FSem);
     end;
   end else begin
-{$IFDEF LINUX}
-    // see .Suspend
-    if FPid <> GMainPID then begin
-      fpkill(FPid, SIGCONT);
-      FSuspended := False;
-    end;
-{$ELSE}
-    ResumeThread(FHandle);
-{$ENDIF}
     FSuspendedExternal := false;
+    ResumeThread(FHandle);
   end;
 end;
 
@@ -592,7 +584,17 @@ end;
 
 {
   $Log$
-  Revision 1.4  2005-02-25 21:41:09  florian
+  Revision 1.5  2005-03-01 20:38:49  jonas
+    * fixed web bug 3387: if one called resume right after creating a
+      suspended thread, it was possible that resume was executed before
+      that thread had completed its initialisation in BeginThread ->
+      FInitialSuspended was set to false in resume and nevertheless a
+      semafore was posted
+    * second problem fixed: set FSuspended to false before waking up the
+      thread, so that it doesn't get FSuspended = true right after waking
+      up. This should be done atomically to be completely correct though.
+
+  Revision 1.4  2005/02/25 21:41:09  florian
     * generic tthread.synchronize
     * delphi compatible wakemainthread
 

+ 15 - 13
rtl/openbsd/tthread.inc

@@ -414,7 +414,8 @@ begin
   try
     if LThread.FInitialSuspended then begin
       SemaphoreWait(LThread.FSem);
-      if not LThread.FInitialSuspended then begin
+      if not LThread.FSuspended then begin
+        LThread.FInitialSuspended := false;
         WRITE_DEBUG('going into LThread.Execute');
         LThread.Execute;
       end;
@@ -527,21 +528,12 @@ procedure TThread.Resume;
 begin
   if (not FSuspendedExternal) then begin
     if FSuspended then begin
-      SemaphorePost(FSem);
-      FInitialSuspended := false;
       FSuspended := False;
+      SemaphorePost(FSem);
     end;
   end else begin
-{$IFDEF LINUX}
-    // see .Suspend
-    if FPid <> GMainPID then begin
-      fpkill(FPid, SIGCONT);
-      FSuspended := False;
-    end;
-{$ELSE}
-    ResumeThread(FHandle);
-{$ENDIF}
     FSuspendedExternal := false;
+    ResumeThread(FHandle);
   end;
 end;
 
@@ -592,7 +584,17 @@ end;
 
 {
   $Log$
-  Revision 1.4  2005-02-25 21:41:09  florian
+  Revision 1.5  2005-03-01 20:38:49  jonas
+    * fixed web bug 3387: if one called resume right after creating a
+      suspended thread, it was possible that resume was executed before
+      that thread had completed its initialisation in BeginThread ->
+      FInitialSuspended was set to false in resume and nevertheless a
+      semafore was posted
+    * second problem fixed: set FSuspended to false before waking up the
+      thread, so that it doesn't get FSuspended = true right after waking
+      up. This should be done atomically to be completely correct though.
+
+  Revision 1.4  2005/02/25 21:41:09  florian
     * generic tthread.synchronize
     * delphi compatible wakemainthread