mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 06:09:11 +02:00
* 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 -
This commit is contained in:
parent
35a313d98c
commit
77c1364713
@ -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;
|
||||||
|
@ -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));
|
WRITE_DEBUG('thread ', ptruint(LThread), ' waiting for RTLEvent ', ptruint(LThread.FSuspendEvent));
|
||||||
SemaphoreWait(LThread.FSem);
|
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();
|
FSuspendEvent := RtlEventCreate;
|
||||||
if FSem = pointer(-1) then
|
WRITE_DEBUG('thread ', ptruint(self), ' created RTLEvent ', ptruint(FSuspendEvent));
|
||||||
raise EThread.create('Semaphore init failed (possibly too many concurrent threads)');
|
|
||||||
WRITE_DEBUG('thread ', ptruint(self), ' created semaphore ', ptruint(FSem));
|
|
||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user