summaryrefslogtreecommitdiff
path: root/rtl/unix/tthread.inc
diff options
context:
space:
mode:
authorjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2015-01-21 23:28:34 +0000
committerjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2015-01-21 23:28:34 +0000
commit1903b037de2fb3e75826406b46f055acb70963fa (patch)
tree604cd8b790fe14e5fbe441d4cd647c80d2a36a9a /rtl/unix/tthread.inc
parentad1141d52f8353457053b925cd674fe1d5c4eafc (diff)
parent953d907e4d6c3a5c2f8aaee6e5e4f73c55ce5985 (diff)
downloadfpc-blocks.tar.gz
* synchronised with trunk till r29513blocks
git-svn-id: http://svn.freepascal.org/svn/fpc/branches/blocks@29516 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'rtl/unix/tthread.inc')
-rw-r--r--rtl/unix/tthread.inc41
1 files changed, 15 insertions, 26 deletions
diff --git a/rtl/unix/tthread.inc b/rtl/unix/tthread.inc
index afc2001249..e58977b48a 100644
--- a/rtl/unix/tthread.inc
+++ b/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,17 +148,14 @@ 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;
- FSuspendedExternal := false;
FThreadReaped := false;
FInitialSuspended := CreateSuspended;
FFatalException := nil;
FSuspendedInternal := not CreateSuspended;
- WRITE_DEBUG('creating thread, self = ',longint(self));
+ WRITE_DEBUG('creating thread, self = ',ptruint(self));
FHandle:= BeginThread(@ThreadFunc, Pointer(Self), FThreadID, StackSize);
if FHandle = TThreadID(0) then
raise EThread.create('Failed to create new thread');
@@ -168,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
@@ -200,7 +197,7 @@ begin
WaitFor;
end;
end;
- SemaphoreDestroy(FSem);
+ RtlEventDestroy(FSuspendEvent);
FFatalException.Free;
FFatalException := nil;
{ threadvars have been released by cthreads.ThreadMain -> DoneThread, or }
@@ -223,13 +220,11 @@ begin
begin
if not FSuspended and
(InterLockedExchange(longint(FSuspended),longint(longbool(true))) = longint(longbool(false))) then
- SemaphoreWait(FSem)
+ RtlEventWaitFor(FSuspendEvent)
end
else
begin
Raise EThread.create('Suspending one thread from inside another one is unsupported (because it is unsafe and deadlock prone) by *nix and posix operating systems');
-// FSuspendedExternal := true;
-// SuspendThread(FHandle);
end;
end;
@@ -239,9 +234,9 @@ 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 if (not FSuspendedExternal) then
+ else
begin
if FSuspended and
{ don't compare with ord(true) or ord(longbool(true)), }
@@ -249,15 +244,9 @@ begin
(InterLockedExchange(longint(FSuspended),longint(false)) <> longint(longbool(false))) then
begin
WRITE_DEBUG('resuming ',ptruint(self));
- SemaphorePost(FSem);
+ RtlEventSetEvent(FSuspendEvent);
end
end
- else
- begin
- raise EThread.create('External suspending is not supported under *nix/posix, so trying to resume from from an external suspension should never happen');
-// FSuspendedExternal := false;
-// ResumeThread(FHandle);
- end;
end;