[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