[haiku-development] Re: kill thread?

  • From: "Ingo Weinhold" <ingo_weinhold@xxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Fri, 17 Aug 2012 23:37:25 +0200

Pete Goodeve wrote:
> On Thu, Aug 16, 2012 at 02:22:08PM +0200, Ingo Weinhold wrote:
> > Pete Goodeve wrote:
> > > Since when has 'kill <thread id>' not worked? ...And why?
> > 
> > I would say since hrev42116. The reason for this is that the semantics of 
> > kill() has been fixed, which is what the kill command uses to send the 
> > signal(s).
> > 
> > > I can kill a *team* by id, but if I just want to remove one of its 
> > > sub-threads,
> > > I get "no such process"!
[...]
> > I believe sending other signals to threads is indeed not easily possible 
> > anymore. If it is any consolation, it never was in BeOS.
> >
> Actually BeOS lets you send any signal to a thread -- it just always
> terminates it (:-/) [Maybe that's what you meant?]

I stand corrected. Apparently BeOS used a kill command that indeed sends the 
signals to threads, not teams. Come to think of it, it actually makes sense, 
since BeOS doesn't support the concept of sending a signal to a team. It only 
supports sending signals to threads. That's part of why the BeOS signals 
implementation isn't POSIX compliant.

> Isn't the ability to send an 'out-of-band' notification to a thread
> (waiting on a port or semaphore) somewhat important, though? I think
> I've wanted to do that in the past [and probably never succeeded due
> to the above... (:-/)]. How do you do that without signals?

Not sure I follow. You can send a signal to a thread also in Haiku (via 
send_signal()), there just isn't any command line tool that does that ATM.

Anyway, IMO signals don't work so well in multi-thread programs anyway. You 
have to be very careful and block signals when the code the thread is executing 
is not signal-safe. When that is the case depends on what signal handlers you 
install. If one of them acquires a lock, any code acquiring that lock must 
block the respective signal when it does that and as long as it keeps the lock. 
Otherwise you'd risk a deadlock.

Moreover, with a signal you don't really send a notification to the thread. The 
signal handler is executed by the thread, but when returning from it the thread 
continues just where the signal interrupted it. The only way to directly 
influence the thread's control flow is to longjmp() out of the signal handler 
(*). But that's a sledge hammer approach. And just setting a flag (global or 
thread-associated variable) is something you can do directly, without sending a 
signal in the first place. The issue of waking up the thread, if it is blocking 
or about to block, remains the same.

Haiku introduces the (experimental) wait_for_objects(), which allows you to 
wait for multiple events. I.e. the thread could not only wait for the 
semaphore, port, socket,... it wants to play with, but also for some other 
condition (e.g. a semaphore) for out-of-band notifications. I find this a much 
better approach than using signals.

> After pawing through documents and experiments all day, the only
> way I've found to have the thread skip a held semaphore is via
> "suspend; resume", which is hardly intuitive! (And I see that the
> BeBook says this is equivalent to 'SIGCONT', but it isn't either in Haiku
> or BeOS! That signal seems to be the only one just ignored.)

Either the documentation is incorrect or you misread something. On BeOS 
suspend_thread() is equivalent to sending a SIGSTOP and resume_thread() is 
equivalent to sending a SIGCONT. Just sending a SIGCONT to a thread that has 
not been stopped (note: stopped != waiting) is a no-op. For better POSIX 
compliance SIGSTOP + SIGCONT doesn't interrupt a syscall on Haiku. 
suspend_thread() + resume_thread() still does, though. However, IMO that is 
rather useless feature, since it requires you to know that the thread in 
question is already waiting. It doesn't work (i.e. amounts to a no-op), when 
the thread is just about to enter the blocking syscall.

CU, Ingo

(*) A signal handler that is not set up to restart an interrupted syscall will 
of course directly influence the control flow as well, but that's something one 
cannot really rely on, since the signal could be delivered just before that 
syscall is entered, so that the thread would still block despite the signal.

Other related posts: