mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-02 07:49:32 +01:00
* disable thread suspension from another thread under *nix, see added
comments in cthreads.pp why git-svn-id: trunk@7551 -
This commit is contained in:
parent
acac591713
commit
526a79a3c6
@ -274,13 +274,21 @@ Type PINTRTLEvent = ^TINTRTLEvent;
|
||||
|
||||
function CSuspendThread (threadHandle : TThreadID) : dword;
|
||||
begin
|
||||
result := pthread_kill(threadHandle,SIGSTOP);
|
||||
{ pthread_kill(SIGSTOP) cannot be used, because posix-compliant
|
||||
implementations then freeze the entire process instead of only
|
||||
the target thread. Suspending a particular thread is not
|
||||
supported by posix nor by most *nix implementations, presumably
|
||||
because of concerns mentioned in E.4 at
|
||||
http://pauillac.inria.fr/~xleroy/linuxthreads/faq.html#E and in
|
||||
http://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
|
||||
}
|
||||
// result := pthread_kill(threadHandle,SIGSTOP);
|
||||
end;
|
||||
|
||||
|
||||
function CResumeThread (threadHandle : TThreadID) : dword;
|
||||
begin
|
||||
result := pthread_kill(threadHandle,SIGCONT);
|
||||
// result := pthread_kill(threadHandle,SIGCONT);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
@ -199,34 +199,38 @@ end;
|
||||
|
||||
procedure TThread.Suspend;
|
||||
begin
|
||||
if not FSuspended and
|
||||
(InterLockedExchange(longint(FSuspended),ord(true)) = ord(false)) then
|
||||
if FThreadID = GetCurrentThreadID then
|
||||
begin
|
||||
if FThreadID = GetCurrentThreadID then
|
||||
if not FSuspended and
|
||||
(InterLockedExchange(longint(FSuspended),ord(true)) = ord(false)) then
|
||||
CurrentTM.SemaphoreWait(FSem)
|
||||
else
|
||||
begin
|
||||
FSuspendedExternal := true;
|
||||
SuspendThread(FHandle);
|
||||
end;
|
||||
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;
|
||||
|
||||
|
||||
procedure TThread.Resume;
|
||||
begin
|
||||
if FSuspended and
|
||||
(InterLockedExchange(longint(FSuspended),ord(false)) = ord(true)) then
|
||||
if (not FSuspendedExternal) then
|
||||
begin
|
||||
WRITE_DEBUG('resuming ',ptrint(self));
|
||||
CurrentTM.SemaphorePost(FSem);
|
||||
end
|
||||
else
|
||||
begin
|
||||
FSuspendedExternal := false;
|
||||
ResumeThread(FHandle);
|
||||
end;
|
||||
if (not FSuspendedExternal) then
|
||||
begin
|
||||
if FSuspended and
|
||||
(InterLockedExchange(longint(FSuspended),ord(false)) = ord(true)) then
|
||||
begin
|
||||
WRITE_DEBUG('resuming ',ptrint(self));
|
||||
CurrentTM.SemaphorePost(FSem);
|
||||
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;
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user