More Driver Questions :-)

Raimo Niskanen raimo@REDACTED
Thu Aug 30 13:43:04 CEST 2001


I hereby forward some comments from a signal handling guru.

/ Raimo Niskanen, Erlang/OTP, Ericsson UAB



Raimo Niskanen <raimo@REDACTED> wrote:
>
>Signal handling in unix is not my bag though, but I can tell you this:
>
>The function driver_output() copies the passed buffer into a list or a
>fresh binary depending on if the port is in binary mode or not, before
>it returns to the driver. Doing this from a signal handler sounds
>dangerous.

That's probably an understatement.:-) There are very few things that can
be done safely from a signal handler in general, manipulating complex
data structures that are also manipulated by other, non-signal-blocking
parts of the code is definitely not one of them (malloc() and friends is
obviously an example of this, and then there are of course all of the
Erlang runtime system's internal structures).

>You should try to make the call to driver_output() from e.g the timeout
>callback, i.e polling the buffer or some other status variable.

But timed polling is ugly.:-)

> I do not
>know what the properties of a signal handler with respect to data shared
>with non-signal-handling code is, if semaphores are necessary nor
>allowed.

As long as you block the signal in question in the non-signal-handling
code, you should be able to do pretty complex things I think (and not
need semaphores).

There is an example purporting to demonstrate how to do signal handling
in a driver in erts/emulator/drivers/unix/sig_drv.c, looks nice and
clean - unfortunately the crucial driver_interrupt() function that it
uses doesn't exist:-) (and I seem to remember that its implementation
wasn't all that great when it did exist).

What Bruce could do however, perhaps a bit ugly but perhaps not, is to
turn the "signal event" into an "I/O event": In the driver
initialization, create a pipe(2) and register the read end of the pipe
via driver_select(). Then in the signal handler just write(2) (stdio is
not allowed I believe:-) to the write end of the pipe, perhaps just a
single byte, which will cause the ready_input handler to be invoked on a
"safe" level, where it can read from the pipe, do whatever else it needs
to do, and call driver_output() without risk.

--Per Hedeland



More information about the erlang-questions mailing list