浏览代码

* set FSuspended also if a tthread is suspended by an external thread
on unix
* fixed some dataraces in unix' suspend/resume (although they can't
be solved completely due to no possibility to atomically
suspend/resume and set fsuspended at the same time)

git-svn-id: trunk@5677 -

Jonas Maebe 18 年之前
父节点
当前提交
4cbbfd7f5c
共有 1 个文件被更改,包括 22 次插入22 次删除
  1. 22 22
      rtl/unix/tthread.inc

+ 22 - 22
rtl/unix/tthread.inc

@@ -198,34 +198,34 @@ end;
 
 procedure TThread.Suspend;
 begin
-  if not FSuspended then begin
-    if FThreadID = GetCurrentThreadID then begin
-      FSuspended := true;
-      CurrentTM.SemaphoreWait(FSem);
-    end else begin
-      FSuspendedExternal := true;
-      SuspendThread(FHandle);
+  if not FSuspended and
+     (InterLockedExchange(longint(FSuspended),ord(true)) = ord(false)) then
+    begin
+      if FThreadID = GetCurrentThreadID then
+        CurrentTM.SemaphoreWait(FSem)
+      else
+        begin
+          FSuspendedExternal := true;
+          SuspendThread(FHandle);
+        end;
     end;
-  end;
 end;
 
 
 procedure TThread.Resume;
 begin
-  if (not FSuspendedExternal) then
-    begin
-      if FSuspended then
-        begin
-          WRITE_DEBUG('resuming ',ptrint(self));
-          FSuspended := False;
-          CurrentTM.SemaphorePost(FSem);
-        end;
-    end
-  else
-    begin
-      FSuspendedExternal := false;
-      ResumeThread(FHandle);
-    end;
+  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;
 end;