|
@@ -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;
|