diff options
author | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2015-01-21 23:28:34 +0000 |
---|---|---|
committer | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2015-01-21 23:28:34 +0000 |
commit | 1903b037de2fb3e75826406b46f055acb70963fa (patch) | |
tree | 604cd8b790fe14e5fbe441d4cd647c80d2a36a9a /rtl/unix/tthread.inc | |
parent | ad1141d52f8353457053b925cd674fe1d5c4eafc (diff) | |
parent | 953d907e4d6c3a5c2f8aaee6e5e4f73c55ce5985 (diff) | |
download | fpc-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.inc | 41 |
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; |