Bläddra i källkod

* replaced use of semaphores in Unix version of TThread for suspend/resume
functionality with RTLEvent:
o the thread manager semaphore functionality isn't used for anything else,
and the main difference between mutex/condvar and semaphores is that the
latter can be used for IPC (while the thread manager is always used
within a single process) and that they are counting (but since a thread
can only suspend itself nowadays, it cannot be suspended recursively)
o OS X sandboxing does not support the use of semaphores (or rather: Apple
does not allow sandboxing rules that enable the use of IPC semaphores in
the appstore)

git-svn-id: trunk@28965 -

Jonas Maebe 10 år sedan
förälder
incheckning
77c1364713
2 ändrade filer med 14 tillägg och 16 borttagningar
  1. 1 1
      rtl/objpas/classes/classesh.inc
  2. 13 15
      rtl/unix/tthread.inc

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

@@ -1609,7 +1609,7 @@ type
 {$ifdef Unix}
   private
     // see tthread.inc, ThreadFunc and TThread.Resume
-    FSem: Pointer;
+    FSuspendEvent: PRTLEvent;
     FInitialSuspended: boolean;
     FSuspendedInternal: longbool;
     FThreadReaped: boolean;

+ 13 - 15
rtl/unix/tthread.inc

@@ -29,9 +29,9 @@
   control. Therefore, I didn't implement .Suspend() if its called from
   outside the threads execution flow (except on Linux _without_ NPTL).
 
-  The implementation for .suspend uses a semaphore, which is initialized
+  The implementation for .suspend uses an RTLEvent, which is initialized
   at thread creation. If the thread tries to suspend itself, we simply
-  let it wait on the semaphore until it is unblocked by someone else
+  let it wait on the Event until it is unblocked by someone else
   who calls .Resume.
 
 
@@ -82,8 +82,8 @@ begin
     WRITE_DEBUG('AfterConstruction should have been called for ',ptruint(lthread));
     if LThread.FInitialSuspended then
       begin
-        WRITE_DEBUG('thread ', ptruint(LThread), ' waiting for semaphore ', ptruint(LThread.FSem));
-        SemaphoreWait(LThread.FSem);
+        WRITE_DEBUG('thread ', ptruint(LThread), ' waiting for RTLEvent ', ptruint(LThread.FSuspendEvent));
+        RtlEventWaitFor(LThread.FSuspendEvent);
         if not(LThread.FTerminated) then
           begin
             if not LThread.FSuspended then
@@ -103,7 +103,7 @@ begin
        begin
          LThread.FSuspendedInternal := true;
          WRITE_DEBUG('waiting for SuspendedInternal - ', LThread.ClassName);
-         SemaphoreWait(LThread.FSem);
+         RtlEventWaitFor(LThread.FSuspendEvent);
          CurrentThreadVar := LThread;
          WRITE_DEBUG('going into LThread.Execute - ', LThread.ClassName);
          LThread.Execute;
@@ -148,10 +148,8 @@ end;
 procedure TThread.SysCreate(CreateSuspended: Boolean;
                             const StackSize: SizeUInt);
 begin
-  FSem := SemaphoreInit();
-  if FSem = pointer(-1) then
-    raise EThread.create('Semaphore init failed (possibly too many concurrent threads)');
-  WRITE_DEBUG('thread ', ptruint(self), ' created semaphore ', ptruint(FSem));
+  FSuspendEvent := RtlEventCreate;
+  WRITE_DEBUG('thread ', ptruint(self), ' created RTLEvent ', ptruint(FSuspendEvent));
   FSuspended := CreateSuspended;
   FThreadReaped := false;
   FInitialSuspended := CreateSuspended;
@@ -167,13 +165,13 @@ end;
 
 procedure TThread.SysDestroy;
 begin
-  if (FSem = nil) then
+  if not assigned(FSuspendEvent) then
     { exception in constructor }
     exit;
   if (FHandle = TThreadID(0)) then
   { another exception in constructor }
     begin
-      SemaphoreDestroy(FSem);
+      RtlEventDestroy(FSuspendEvent);
       exit;
     end;
   if (FThreadID = GetCurrentThreadID) then
@@ -199,7 +197,7 @@ begin
           WaitFor;
         end;
     end;
-  SemaphoreDestroy(FSem);
+  RtlEventDestroy(FSuspendEvent);
   FFatalException.Free;
   FFatalException := nil;
   { threadvars have been released by cthreads.ThreadMain -> DoneThread, or  }
@@ -222,7 +220,7 @@ begin
     begin
       if not FSuspended and
          (InterLockedExchange(longint(FSuspended),longint(longbool(true))) = longint(longbool(false))) then
-        SemaphoreWait(FSem)
+        RtlEventWaitFor(FSuspendEvent)
     end
   else
     begin
@@ -236,7 +234,7 @@ begin
   if FSuspendedInternal and (InterLockedExchange(longint(FSuspendedInternal),ord(false)) = longint(longbool(true))) then
     begin
       WRITE_DEBUG('resuming thread after TThread construction',ptruint(self));
-      SemaphorePost(FSem);
+      RtlEventSetEvent(FSuspendEvent);
     end
   else
     begin
@@ -246,7 +244,7 @@ begin
          (InterLockedExchange(longint(FSuspended),longint(false)) <> longint(longbool(false))) then
         begin
           WRITE_DEBUG('resuming ',ptruint(self));
-          SemaphorePost(FSem);
+          RtlEventSetEvent(FSuspendEvent);
         end
     end
 end;