3.4. The Event Loop

All commands in libraw1394 are asynchronous, with some synchronous wrapper functions for some types of transactions. This means that there are two streams of data, one going into raw1394 and one coming out. With this design you can send out multiple transactions without having to wait for the response before you can continue (sending out other transactions, for example). The responses and other events (like bus resets and received isochronous packets) are queued, and you can get them with raw1394_loop_iterate() or raw1394_loop_iterate_timeout() (which always returns after a user-specified timeout if no raw1394 event has occurred).

This forms an event loop you may already know from similar systems like GUI toolkits. raw1394_loop_iterate() gets one message from the event queue in raw1394, processes it with the configured callback functions and returns the value returned by the callback (so you can signal to the main loop from your callback; the standard callbacks all return 0). It normally blocks when there are no events and always processes only one event. If you are only receiving broadcast events like isochronous packets you thus have to set up a loop continuously calling the iterate function to get your callbacks called.

Often it is necessary to have multiple event loops and combine them, e.g. if your application uses a GUI toolkit which also has its own event loop. In that case you can use raw1394_get_fd() to get the file descriptor used for this handle by libraw1394. The fd can be used to for select() or poll() calls together with the other loop's fd. (Most toolkits, like GTK and Qt, have special APIs for integrating file descriptors into their own event loops).

If using poll(), you must test for POLLIN and POLLPRI events. If using select(), you must test for both read and exception activity.

If any of these conditions trigger, you should then call raw1394_loop_iterate() to pick up the event. raw1394_loop_iterate() is guaranteed not to block when called immediately after select() or poll() indicates activity. After the first call you continue the main event loop. If more events wait, the select()/poll() will immediately return again.

You can also use the fd to set the O_NONBLOCK flag with fcntl(). After that, the iterate function will not block anymore but fail with errno set to EAGAIN if no events wait. These are the only legal uses for the fd returned by raw1394_get_fd().

There are some functions which provide a synchronous wrapper for transactions, note that these will call raw1394_loop_iterate() continuously until their transaction is completed, thus having implicit callback invocations during their execution. The standard transaction functions have names of the form raw1394_start_xxx, the synchronous wrappers are called raw1394_xxx.