Browse Source

* 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 years ago
parent
commit
77c1364713
2 changed files with 14 additions and 16 deletions
  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}
 {$ifdef Unix}
   private
   private
     // see tthread.inc, ThreadFunc and TThread.Resume
     // see tthread.inc, ThreadFunc and TThread.Resume
-    FSem: Pointer;
+    FSuspendEvent: PRTLEvent;
     FInitialSuspended: boolean;
     FInitialSuspended: boolean;
     FSuspendedInternal: longbool;
     FSuspendedInternal: longbool;
     FThreadReaped: boolean;
     FThreadReaped: boolean;

+ 13 - 15
rtl/unix/tthread.inc

@@ -29,9 +29,9 @@
   control. Therefore, I didn't implement .Suspend() if its called from
   control. Therefore, I didn't implement .Suspend() if its called from
   outside the threads execution flow (except on Linux _without_ NPTL).
   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
   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.
   who calls .Resume.
 
 
 
 
@@ -82,8 +82,8 @@ begin
     WRITE_DEBUG('AfterConstruction should have been called for ',ptruint(lthread));
     WRITE_DEBUG('AfterConstruction should have been called for ',ptruint(lthread));
     if LThread.FInitialSuspended then
     if LThread.FInitialSuspended then
       begin
       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
         if not(LThread.FTerminated) then
           begin
           begin
             if not LThread.FSuspended then
             if not LThread.FSuspended then
@@ -103,7 +103,7 @@ begin
        begin
        begin
          LThread.FSuspendedInternal := true;
          LThread.FSuspendedInternal := true;
          WRITE_DEBUG('waiting for SuspendedInternal - ', LThread.ClassName);
          WRITE_DEBUG('waiting for SuspendedInternal - ', LThread.ClassName);
-         SemaphoreWait(LThread.FSem);
+         RtlEventWaitFor(LThread.FSuspendEvent);
          CurrentThreadVar := LThread;
          CurrentThreadVar := LThread;
          WRITE_DEBUG('going into LThread.Execute - ', LThread.ClassName);
          WRITE_DEBUG('going into LThread.Execute - ', LThread.ClassName);
          LThread.Execute;
          LThread.Execute;
@@ -148,10 +148,8 @@ end;
 procedure TThread.SysCreate(CreateSuspended: Boolean;
 procedure TThread.SysCreate(CreateSuspended: Boolean;
                             const StackSize: SizeUInt);
                             const StackSize: SizeUInt);
 begin
 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;
   FSuspended := CreateSuspended;
   FThreadReaped := false;
   FThreadReaped := false;
   FInitialSuspended := CreateSuspended;
   FInitialSuspended := CreateSuspended;
@@ -167,13 +165,13 @@ end;
 
 
 procedure TThread.SysDestroy;
 procedure TThread.SysDestroy;
 begin
 begin
-  if (FSem = nil) then
+  if not assigned(FSuspendEvent) then
     { exception in constructor }
     { exception in constructor }
     exit;
     exit;
   if (FHandle = TThreadID(0)) then
   if (FHandle = TThreadID(0)) then
   { another exception in constructor }
   { another exception in constructor }
     begin
     begin
-      SemaphoreDestroy(FSem);
+      RtlEventDestroy(FSuspendEvent);
       exit;
       exit;
     end;
     end;
   if (FThreadID = GetCurrentThreadID) then
   if (FThreadID = GetCurrentThreadID) then
@@ -199,7 +197,7 @@ begin
           WaitFor;
           WaitFor;
         end;
         end;
     end;
     end;
-  SemaphoreDestroy(FSem);
+  RtlEventDestroy(FSuspendEvent);
   FFatalException.Free;
   FFatalException.Free;
   FFatalException := nil;
   FFatalException := nil;
   { threadvars have been released by cthreads.ThreadMain -> DoneThread, or  }
   { threadvars have been released by cthreads.ThreadMain -> DoneThread, or  }
@@ -222,7 +220,7 @@ begin
     begin
     begin
       if not FSuspended and
       if not FSuspended and
          (InterLockedExchange(longint(FSuspended),longint(longbool(true))) = longint(longbool(false))) then
          (InterLockedExchange(longint(FSuspended),longint(longbool(true))) = longint(longbool(false))) then
-        SemaphoreWait(FSem)
+        RtlEventWaitFor(FSuspendEvent)
     end
     end
   else
   else
     begin
     begin
@@ -236,7 +234,7 @@ begin
   if FSuspendedInternal and (InterLockedExchange(longint(FSuspendedInternal),ord(false)) = longint(longbool(true))) then
   if FSuspendedInternal and (InterLockedExchange(longint(FSuspendedInternal),ord(false)) = longint(longbool(true))) then
     begin
     begin
       WRITE_DEBUG('resuming thread after TThread construction',ptruint(self));
       WRITE_DEBUG('resuming thread after TThread construction',ptruint(self));
-      SemaphorePost(FSem);
+      RtlEventSetEvent(FSuspendEvent);
     end
     end
   else
   else
     begin
     begin
@@ -246,7 +244,7 @@ begin
          (InterLockedExchange(longint(FSuspended),longint(false)) <> longint(longbool(false))) then
          (InterLockedExchange(longint(FSuspended),longint(false)) <> longint(longbool(false))) then
         begin
         begin
           WRITE_DEBUG('resuming ',ptruint(self));
           WRITE_DEBUG('resuming ',ptruint(self));
-          SemaphorePost(FSem);
+          RtlEventSetEvent(FSuspendEvent);
         end
         end
     end
     end
 end;
 end;