* 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:
Jonas Maebe 2007-06-02 11:39:59 +00:00
parent acac591713
commit 526a79a3c6
2 changed files with 34 additions and 22 deletions

View File

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

View File

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