Procházet zdrojové kódy

* disable thread suspension from another thread under *nix, see added
comments in cthreads.pp why

git-svn-id: trunk@7551 -

Jonas Maebe před 18 roky
rodič
revize
526a79a3c6
2 změnil soubory, kde provedl 34 přidání a 22 odebrání
  1. 10 2
      rtl/unix/cthreads.pp
  2. 24 20
      rtl/unix/tthread.inc

+ 10 - 2
rtl/unix/cthreads.pp

@@ -274,13 +274,21 @@ Type  PINTRTLEvent = ^TINTRTLEvent;
 
   function  CSuspendThread (threadHandle : TThreadID) : dword;
     begin
-      result := pthread_kill(threadHandle,SIGSTOP);
+    {  pthread_kill(SIGSTOP) cannot be used, because posix-compliant
+       implementations then freeze the entire process instead of only
+       the target thread. Suspending a particular thread is not
+       supported by posix nor by most *nix implementations, presumably
+       because of concerns mentioned in E.4 at
+       http://pauillac.inria.fr/~xleroy/linuxthreads/faq.html#E and in
+       http://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
+    }
+//      result := pthread_kill(threadHandle,SIGSTOP);
     end;
 
 
   function  CResumeThread  (threadHandle : TThreadID) : dword;
     begin
-      result := pthread_kill(threadHandle,SIGCONT);
+//      result := pthread_kill(threadHandle,SIGCONT);
     end;
 
 

+ 24 - 20
rtl/unix/tthread.inc

@@ -199,34 +199,38 @@ end;
 
 procedure TThread.Suspend;
 begin
-  if not FSuspended and
-     (InterLockedExchange(longint(FSuspended),ord(true)) = ord(false)) then
+  if FThreadID = GetCurrentThreadID then
     begin
-      if FThreadID = GetCurrentThreadID then
+      if not FSuspended and
+         (InterLockedExchange(longint(FSuspended),ord(true)) = ord(false)) then
         CurrentTM.SemaphoreWait(FSem)
-      else
-        begin
-          FSuspendedExternal := true;
-          SuspendThread(FHandle);
-        end;
+    end
+  else
+    begin
+      Raise EThread.create('Suspending one thread from inside another one is unsupported (because it is unsafe and deadlock prone) by *nix and posix operating systems');
+//      FSuspendedExternal := true;
+//      SuspendThread(FHandle);
     end;
 end;
 
 
 procedure TThread.Resume;
 begin
-  if FSuspended and
-     (InterLockedExchange(longint(FSuspended),ord(false)) = ord(true)) then
-    if (not FSuspendedExternal) then
-      begin
-        WRITE_DEBUG('resuming ',ptrint(self));
-        CurrentTM.SemaphorePost(FSem);
-      end
-    else
-      begin
-        FSuspendedExternal := false;
-        ResumeThread(FHandle);
-      end;
+  if (not FSuspendedExternal) then
+    begin
+      if FSuspended and
+         (InterLockedExchange(longint(FSuspended),ord(false)) = ord(true)) then
+        begin
+          WRITE_DEBUG('resuming ',ptrint(self));
+          CurrentTM.SemaphorePost(FSem);
+        end
+    end
+  else
+    begin
+      raise EThread.create('External suspending is not supported under *nix/posix, so trying to resume from from an external suspension should never happen');
+//      FSuspendedExternal := false;
+//      ResumeThread(FHandle);
+    end;
 end;