[erlang-questions] driver asyncronous notifications

Oscar Hellström oscar@REDACTED
Fri Jun 1 10:43:33 CEST 2007

Serge Aleynikov wrote:
> Greetings!
> I wanted to consult with the list on the following subject.  In the past 
> couple of weeks I have been writing an Erlang driver for TibcoRV.  This 
> messaging system has a proprietary API with a multi-threaded engine. 
> The engine consists of a producer/consumer pair of threads that dispatch 
> and enqueue messages and also allows to register an event callback 
> triggered on every dequeued message.
> In order to interface with an Erlang driver, I need in the event 
> callback to convert an RV message to an Erlang term and send it to the 
> emulator's thread via driver_output family of functions.  The main 
> problem is that the driver API is mostly suited for three sorts of tasks:
> a. Detection of activity on some registered file descriptor that 
> triggers ready_{input,output} callbacks in the context of the emulator's 
> thread.
Could you use a pipe here to notify the emulator of the event?
> b. A short-lived non-blocking request initiated from an Erlang process 
> (in the driver-space called via output*() or call() callback functions) 
> and followed by driver_output call to return result to the Erlang side.
> c. A long-lived asynchronous request via driver_async() call, executed 
> in the context of a thread from a managed thread-pool with the result 
> returned by the async_ready() callback.

This is my impression also... We're lacking a way to react on *any*
event, and then send messages to the emulator process.
> None of these three cases are suited for events that don't come on file 
> descriptors, but on callbacks in the context of other threads. 
> Unfortunately those callbacks cannon make direct use of driver_output* 
> non thread-safe functions.  One possibility is to create a pipe and 
> register a read-end of the pipe with Erlang's select loop by calling 
> driver_select() function, and use write() call on the other end of the 
> pine from another thread to communicate some activity, so that if would 
> trigger the ready_input() driver's callback in the context of emulator's 
> thread.  However this is a very expensive solution which I wouldn't want 
> to use.
> Also driver_async() call is not very efficient in this case either 
> because when called from ThreadC, it'll execute a given function (that 
> doesn't really need to do anything since ThreadC in the RV's callback 
> function already have done all the work of creating an Erlang term to be 
> sent to the emulator) in the context of a ThreadB from a thread-pool and 
> then return to the emulator's ThreadA that can finally call 
> driver_output().  As you see, there is an unnecessary use of ThreadB in 
> this case that leads to performance loss.  For reference, I implemented 
> this approach and got performance of 25,000 msgs/sec at 100% CPU 
> utilization, which is not quite suitable for the application I am 
> building (my C implementation gives over 60,000 msgs/sec).
> Perhaps I am missing something here.  How can I send a message 
> originated from some 3rd party callback function in the context of 
> ThreadC (that is not a part of a thread pool managed by Erlang) to the 
> emulator's ThreadA so that it would become aware of the new event and 
> safely deliver this message to a mailbox of an Erlang process (i.e. call 
> driver_output)?

As I mentioned earlier, maybe you could use a pipe to notify
ready_{input, output}? I have however not tried this approach and don't
know what penalty you'd get.
> Serge
When I asked about this back in August [1]  I got the answer

"Future versions of the SMP emulator will probably have new driver
APIs to make multi-threaded drivers much easier to write." [2]

Don't think this has been implemented yet.

[1] http://www.erlang.org/pipermail/erlang-questions/2006-August/022158.html
[2] http://www.erlang.org/pipermail/erlang-questions/2006-August/022211.html

More information about the erlang-questions mailing list