Waiting on multiple sources

OK, here is a genuine newbie question. I’m guessing it has a simple answer.

I am writing a server (not a resource manager for now) that needs to block
until any of three things happen:

  • an interrupt (InterruptWait)
  • a message (MsgReceive)
  • a signal (sigsuspend)

My interrupt handler (for my custom hardware) sends a SIGEV_INTR event. My
client processes will MsgSend() to the server to retrieve information from
the custom hardware. I’d also like to be able to catch other signals so I
can shut down my hardware gracefully.

It has been suggested to me to use a separate thread for each case to handle
the waiting, but that seems complicated and introduces synchronization
problems. I’d really like a single-threaded solution.

Something like this:

while (! Shutdown)
WaitFor (Interrupt Or Message Or Signal)
case Interrupt

case Message

case Signal
Shutdown = TRUE
end while
Shutdown hardware here

Am I barking up the wrong tree? How can I wait on multiple sources?

Matt Boothe wrote:

Am I barking up the wrong tree?

No, of course not.

How can I wait on multiple sources?

See the documentation (in the helpviewer) on “Writing a Resource Manager”.
The section most pertinent to your question is the section entitled
“Handling private messages and pulses” (a pulse is what you would use
for your interrupt handler).

Rennie

Your interrupt handler could simply return a SIGEV_PULSE event, which
would wake up a MsgReceive()

Matt Boothe wrote:

OK, here is a genuine newbie question. I’m guessing it has a simple answer.

I am writing a server (not a resource manager for now) that needs to block
until any of three things happen:

  • an interrupt (InterruptWait)
  • a message (MsgReceive)
  • a signal (sigsuspend)

My interrupt handler (for my custom hardware) sends a SIGEV_INTR event. My
client processes will MsgSend() to the server to retrieve information from
the custom hardware. I’d also like to be able to catch other signals so I
can shut down my hardware gracefully.

It has been suggested to me to use a separate thread for each case to handle
the waiting, but that seems complicated and introduces synchronization
problems. I’d really like a single-threaded solution.

Something like this:

while (! Shutdown)
WaitFor (Interrupt Or Message Or Signal)
case Interrupt

case Message

case Signal
Shutdown = TRUE
end while
Shutdown hardware here

Am I barking up the wrong tree? How can I wait on multiple sources?


cburgess@qnx.com

Colin Burgess wrote:

Your interrupt handler could simply return a SIGEV_PULSE event, which
would wake up a MsgReceive()

And your signal-catching thread could be a simple loop that gets the
signal and sends it to the main thread in a message or pulse. I imagine
it would take about 10 lines of code and require no synchronization.

Matt Boothe wrote:

OK, here is a genuine newbie question. I’m guessing it has a simple
answer.

I am writing a server (not a resource manager for now) that needs to
block until any of three things happen:

  • an interrupt (InterruptWait)
  • a message (MsgReceive)
  • a signal (sigsuspend)

My interrupt handler (for my custom hardware) sends a SIGEV_INTR
event. My client processes will MsgSend() to the server to retrieve
information from the custom hardware. I’d also like to be able to
catch other signals so I can shut down my hardware gracefully.

It has been suggested to me to use a separate thread for each case to
handle the waiting, but that seems complicated and introduces
synchronization problems. I’d really like a single-threaded solution.

Something like this:

while (! Shutdown)
WaitFor (Interrupt Or Message Or Signal)
case Interrupt

case Message

case Signal
Shutdown = TRUE
end while
Shutdown hardware here

Am I barking up the wrong tree? How can I wait on multiple sources?

Thanks for the replies.

Looking at MsgReceive_r, it returns -EINTR if it is interrupted by a signal.
So it seems it would be possible to do all the work (assuming I send a pulse
from my ISR as suggested) using MsgReceive_r instead of adding another
thread? Any reason that won’t work?

Also, I notice that in the IPC chapter of the System Architecture Guide
there is a summary of signals and that some of them cannot be caught or
ignored, e.g. SIGKILL. This would seem to present a problem for me. Recall
that I want to be able to exit my forever loop and shutdown my hardware
before I exit the process. I’m really not sure what to do about that.

Maybe my POSIX.4 book (in the mail) will help me answer this kind of
question. I’m pretty hazy on the entire issue of signals. I’m guessing
that signal handling is obvious to people with a UNIX background because
they were hardly even mentioned in the “Getting Started” book by Krten.
Unfortunately for me, my background is with RTOS’s, not UNIX.

Matt Boothe <embeddedmatt@yahoo.com> wrote:

Thanks for the replies.

Looking at MsgReceive_r, it returns -EINTR if it is interrupted by a signal.
So it seems it would be possible to do all the work (assuming I send a pulse
from my ISR as suggested) using MsgReceive_r instead of adding another

from my ISR as suggested) using MsgReceive_r instead of adding another
thread? Any reason that won’t work?

MsgReceive and MsgReceive_r will both handle the signal case – MsgReceive
will return -1, and set errno = EINTR if you get hit by a signal.
MsgReceive_r will return -EINTR. Actually, in general, MsgReceive will
return -1 on error, and set errno, while for the same error conditions
MsgReceive_r will return -errno.

Using this as your common blocking point will work very well, assuming
you use a pulse from your ISR as suggested.

One other thing, though, you probably want to make sure you ONLY receive
signals while in the MsgReceive (or as close to that as you can), because
if you get hit by a signal anywhere else, it will be a real pain.

You will probably want to:

  • mask all signals as part of your initialization
  • attach a signal handler to the signals you want to handle
  • in that signal handler, deliver a pulse to your main thread
  • unmask just the signals you are willing to accept before your
    MsgRecevie[_r] call
  • mask the signals after you return from MsgReceive[_r].

(You deliver the pulse from the signal handler to deal with cases where the
signal is sent before or after you go RECEIVE blocked in yoru MsgReceive()
call.)

Also, I notice that in the IPC chapter of the System Architecture Guide
there is a summary of signals and that some of them cannot be caught or
ignored, e.g. SIGKILL. This would seem to present a problem for me. Recall
that I want to be able to exit my forever loop and shutdown my hardware
before I exit the process. I’m really not sure what to do about that.

You can’t do anything about SIGKILL. POSIX mandates that SIGKILL must be
non-maskable, non-catchable, non-handleable. It’s often called
“kill-em-dead”. (Well, you can make your system such that it will never
send a SIGKILL - write no programs that deliver, don’t include any
programs that will let a user deliver an arbitrary signal to a process.
[e.g. slay, kill, qconn]).

Maybe my POSIX.4 book (in the mail) will help me answer this kind of
question. I’m pretty hazy on the entire issue of signals. I’m guessing
that signal handling is obvious to people with a UNIX background because
they were hardly even mentioned in the “Getting Started” book by Krten.
Unfortunately for me, my background is with RTOS’s, not UNIX.

QNX’s implementation of signals is pretty well pure POSIX. And, yes,
they are generally pretty well covered by most any decent Unix or
POSIX programming guide. This is (I expect) one of the reasons that
Rob’s (very good) book doesn’t cover them. The other is, I expect,
that, compared to pulses, signals are a major pain to deal with.

[BTW, my favourite Unix programming book is Advanced Programming in the
Unix Environment
by W. Richard Stevens.]

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

David Gibbs wrote:

Matt Boothe <> embeddedmatt@yahoo.com> > wrote:

Thanks for the replies.


Looking at MsgReceive_r, it returns -EINTR if it is interrupted by a signal.
So it seems it would be possible to do all the work (assuming I send a pulse
from my ISR as suggested) using MsgReceive_r instead of adding another

[snip]

[BTW, my favourite Unix programming book is Advanced Programming in the
Unix Environment
by W. Richard Stevens.]

OP: If your going to mix signals and threads then I would recommend
googling for “signals threads”, and get “Programming with POSIX Threads”
by David R. Butenhof.

Rennie

This is not as easy as it sounds. The problem is that most common blocking
calls do not allow to wait for all those types of events simultaneously.

InterruptWait will wait for interrupts.
MsgReceive will wait for messages or pulses (that can also come from
interrupt), but not for signals.
sigwait/sigwaitinfo will wait for a synchronous signal (that can come from
interrupt, timer or a message queue) but not for messages/pulses.

The signals in their classic async form are generally evil thing. You need
to care about EINTR and it tends to be very messy. One way to deal with them
is what David have suggested (masking/unmasking around MsgReceive). Another
way is using a dedicated thread to receive signals synchronously (then you
don’t have to worry about EINTR at all). You can wait for messages/pulses in
one thread and for signals (sigwaitinfo) in another. If you block signals in
the first thread, the second will get them. Then it can inject pulses into
the first one (i.e., ‘translate’ signals into pulses).

– igor

“Matt Boothe” <embeddedmatt@yahoo.com> wrote in message
news:cipbv1$ad6$1@inn.qnx.com

OK, here is a genuine newbie question. I’m guessing it has a simple
answer.

I am writing a server (not a resource manager for now) that needs to block
until any of three things happen:

  • an interrupt (InterruptWait)
  • a message (MsgReceive)
  • a signal (sigsuspend)

My interrupt handler (for my custom hardware) sends a SIGEV_INTR event.
My
client processes will MsgSend() to the server to retrieve information from
the custom hardware. I’d also like to be able to catch other signals so I
can shut down my hardware gracefully.

It has been suggested to me to use a separate thread for each case to
handle
the waiting, but that seems complicated and introduces synchronization
problems. I’d really like a single-threaded solution.

Something like this:

while (! Shutdown)
WaitFor (Interrupt Or Message Or Signal)
case Interrupt

case Message

case Signal
Shutdown = TRUE
end while
Shutdown hardware here

Am I barking up the wrong tree? How can I wait on multiple sources?

David Gibbs <dagibbs@qnx.com> wrote:

Matt Boothe <> embeddedmatt@yahoo.com> > wrote:

[snip]

Maybe my POSIX.4 book (in the mail) will help me answer this kind of
question. I’m pretty hazy on the entire issue of signals. I’m guessing
that signal handling is obvious to people with a UNIX background because
they were hardly even mentioned in the “Getting Started” book by Krten.
Unfortunately for me, my background is with RTOS’s, not UNIX.

QNX’s implementation of signals is pretty well pure POSIX. And, yes,
they are generally pretty well covered by most any decent Unix or
POSIX programming guide. This is (I expect) one of the reasons that
Rob’s (very good) book doesn’t cover them. The other is, I expect,
that, compared to pulses, signals are a major pain to deal with.

Nah, I just never use them! The only time I’ve ever used signals is
to ignore ^C. That’s it. :slight_smile:

Cheers,
-RK


[If replying via email, you’ll need to click on the URL that’s emailed to you
afterwards to forward the email to me – spam filters and all that]
Robert Krten, PDP minicomputer collector http://www.parse.com/~pdp8/

Thanks to everyone who responded. The discussion was quite helpful to me.
It’s funny, I hadn’t even considered the option of ignoring signals as Mr.
Krten always does, but maybe that’s not such a bad idea. I could write a
small client whose sole purpose in life is to shutdown my server by sending
it a normal message. Since my system is deeply embedded, there won’t often
be someone connected to the shell, and if there is, that person will be an
engineer. Although us engineers are generally untrustworthy :slight_smile: I think I
can trust the engineers not to slay my server and use my shutdown client
instead. At least that will work in the short term.

Thanks again.

Robert Krten <rk@parse.com> wrote:

David Gibbs <> dagibbs@qnx.com> > wrote:
This is (I expect) one of the reasons that
Rob’s (very good) book doesn’t cover them. The other is, I expect,
that, compared to pulses, signals are a major pain to deal with.

Nah, I just never use them! The only time I’ve ever used signals is
to ignore ^C. That’s it. > :slight_smile:

Ah, so it is case two – you don’t use them [because they’re a pain to
deal with], so you didn’t write about them. :slight_smile:

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

David Gibbs <dagibbs@qnx.com> wrote:
DG > Robert Krten <rk@parse.com> wrote:

David Gibbs <> dagibbs@qnx.com> > wrote:
This is (I expect) one of the reasons that
Rob’s (very good) book doesn’t cover them. The other is, I expect,
that, compared to pulses, signals are a major pain to deal with.

Nah, I just never use them! The only time I’ve ever used signals is
to ignore ^C. That’s it. > :slight_smile:

DG > Ah, so it is case two – you don’t use them [because they’re a pain to
DG > deal with], so you didn’t write about them. :slight_smile:

Gee, I always felt that Rob’s opinion about signals was well known.
Nothing new here.