[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [Libevent-users] Asynchronous writes in the event loop model



On Thu, Jan 19, 2012 at 9:23 AM, Frank Schoep <frank@xxxxxxx> wrote:
> Hello everyone,
>
> After reading the libevent documentation and hacking on some of the code samples, I've got a question about doing 'asynchronous' socket writes using the event loop model.
>
> I completely understand how libevent can be used to create an HTTP (or alike) server, thanks to that protocol's request-response model. Most examples write the response back to the client after reading enough bytes in a read callback; very easy to grok and an obviously excellent fit for libevent's event loop model.
>
> However, I am wondering how to best do 'spontaneous' or 'asynchronous' writes that originate not from a client's response, but from a different source.
>
> As an example, consider a situation where network clients connect to a server to be notified of a simple 'event' like a button press on the server keyboard. The basic architecture would look something like this:
>
> [ Thread 1 - "main" ]
> step 1 - wait for the 'event' like a button press
> step 2 - notify all clients
> step 3 - goto step 1
>
> [ Thread 2 - "libevent event loop" ]
> events - listen for new connections (and optionally read some data from the client)
>
> What's the best way to inject messages to be written out from thread 1 into the libevent loop on thread 2? Note that the button press is purely hypothetical, any form of external, non-libevent 'event' will suffice.

The usual way is with events that you manually activate.  You'll need
to use libevent 2 for threading support, and call one of the
appropriate functions at startup time to turn on threading support.
Then you can construct events that are not associated with any
particular fd:

  ev = event_new(base, -1, EV_READ, callback_fn, callback_data);

and then turn them on yourself:

  event_active(ev, EV_READ, 1);

You can turn on the event like from any thread; its callback will get
executed in the Libevent loop thread.

If you have huge amounts of data to process like this, you wouldn't
necessarily want a separate event for every little piece of data.
Instead, you typically put the data into some kind of queue-like
data-structure, and have a single event that you activate whenever the
queue becomes nonempty.

Libevent's buffereing code is better for network connections than for
inter-thread communication, though you ought to be able to use an
evbuffer as your queue if that's what you really want to do.
Personally, though, I'd just use a queue.

Other people might have other design ideas too.

cheers,
-- 
Nick
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.