The Plan(tm) AFAIK is to convert signals to events[1]. Pressing ^C on the
console or such should be available to user defined exception or signal
handlers.

So the flow of information would be:

  1) signal                     async per definition  - in some thread
  2) event-handler thread       convert to event, which is broadcasted
  3) interpreters task queue    event-handlers pass it on
  4) exception handler          converts to exception
  5) user action                and finally PASM runs

Some experiments on Linux with SIGINT:

I have sorted out signal blocking and threads, so the signal gets
delivered to the event-handler thread. But what now:

,--[ man pthread_cond_signal ]-------------------------------------
|        The condition functions are  not  async-signal  safe,  and
|        should not be called from a signal handler. In particular,
|        calling pthread_cond_signal or pthread_cond_broadcast from
|        a signal handler may deadlock the calling thread.
`------------------------------------------------------------------

So directly signalling the event queue isn't allowed (a short test
shows: it works, but that doesn't seem to be a solution)

The docs indicate, that a timedwait would return EINTR like the
low-level read(2) or such functions:

,--[ man pthread_cond_signal ]-------------------------------------
|               EINTR  pthread_cond_timedwait was interrupted by  a
|                      signal
`------------------------------------------------------------------

But:

,--[ less linuxthreads/ChangeLog ]----------------------------------------
|         * condvar.c (pthread_cond_timedwait_relative): Never return with
|         EINTR.  Patch by Andreas Schwab.
`-------------------------------------------------------------------------

So:

,--[ less linuxthreads/FAQ ]----------------------------------------------
|    The only sensible things you can do from a signal handler is set a
|    global flag, or call sem_post on a semaphore, to record the delivery
|    of the signal. The remainder of the program can then either poll the
|    global flag, or use sem_wait() and sem_trywait() on the semaphore.
|
|    Another option is to do nothing in the signal handler, and dedicate
|    one thread (preferably the initial thread) to wait synchronously for
|    signals, using sigwait(), and send messages to the other threads
|    accordingly.
`-------------------------------------------------------------------------

The event handler thread is waiting on a condition, so the only
possibility seems to be the latter option, that is run another thread
that does nothing but sigwait(3).

[1] where applicable, e.g. no "Program Error Signals"

all citations are from a SuSE 7.3, glibc 2.2.4 system.

Comments welcome,
leo



Reply via email to