More Driver Questions :-)

Raimo Niskanen <>
Thu Aug 30 12:17:41 CEST 2001


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.

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. 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.

Reference counted binaries will gain some performance because you get
rid of one memcpy(), but you will have to allocate the binaries from
non-signal-handling code, and the same with driver_output_binary().
Perhaps pre-allocate the binaries, put them in a linked list, let the
signal handler fill in the binary and move it to another list
(consistency problem!), let the polling timout callback call
driver_output_binary().

/ Raimo Niskanen, Erlang/OTP, Ericsson UAB.



Bruce Fitzsimons wrote:
> 
> Peoples,
> 
> Firstly thanks to Ulf and Raimo for their response to my process limits
> questions, your responses were really useful - I just need to find some time
> to implement it now...
> 
> My next question is about linked-in drivers. Sean, Vance and Raimo have had
> lots of interesting discussions that I have been following with interest as
> I have my own pet driver for connecting Erlang to Dialogic telephony boards
> (analog pots api) under Linux.
> 
> Its actually nearing a stage where I can post it on sourceforge and people
> can comment on my crap code and design :-)
> 
> Anyway I have an important question about scope and visibility of the buffer
> passed to driver_output.
> 
> In my case I have a signal handler in my driver that is invoked on Dialogic
> events (onhook/offhook/answer etc). It suspends the signal on entry and
> releases on exit inside the handler to avoid re-entrancy problems.
> 
> However my driver is consistently but randomly crashing Erlang with
> segfault. From one core dump it appeared to be inside real erlang doing
> memcpy's with insanely large lengths (Eg corrupt memory) and sometimes I get
> corrupted data posted to the erlang half of the driver (even once I got a
> complete debug statement instead of the data).
> 
> I get about 50-200 calls (on an 8 port system) before crashing. Changing the
> buffer inside the signal handler to be static improved the runtime but did
> not eliminate the problem.
> 
> My signal handler uses a local heap buffer of 1024 bytes which is sprintf's
> into and then uses driver_output to sent it to erlang (length =
> strlen(buffer)).
> 
> eg
> 
>    switch(ATDX_HOOKST(dialogic_handle))
>      {
>      case DX_OFFHOOK:
>        sprintf(output_string, "%02d%02dOFFHOOK", board, channel);
>        break;
>      case DX_ONHOOK:
>        sprintf(output_string, "%02d%02dONHOOK", board, channel);
>        break;
>      default:
>        sprintf(output_string, "%02d%02dERROR SETHOOK", board, channel);
>      }
>     driver_output(erlang_port, error_string, strlen(error_string));
> 
> Is it possible that a rapid series of signals to the signal handler could
> corrupt the buffer that Erlang has? i.e. Does Erlang copy this buffer or use
> it by reference? Does it copy it immediately (before driver_output returns)?
> 
> Should I be using reference-counted binaries for this (it seems a whole lot
> nicer)?
> 
> It is of course possible that the dialogic drivers themselves are doing
> something bad, they are not known for perfect reliability, but my own driver
> code does no dynamic memory allocation at all (I wanted to avoid this
> problem completely).
> 
> These drivers will be EPL'd and up on sourceforge under the name erlogic
> eventually...they're pretty hacky at the moment though
> 
> Cheers,
> Bruce



More information about the erlang-questions mailing list