Rev 3 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 3 | magnus | 1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
| 2 | <html><head> |
||
| 3 | <title>liboop: How?</title> |
||
| 4 | <link rel="stylesheet" type="text/css" href="style.css"> |
||
| 5 | </head><body> |
||
| 6 | |||
| 7 | <h2>Overview of liboop.</h2> |
||
| 8 | |||
| 9 | <h4>The basic idea.</h4> |
||
| 10 | |||
| 11 | Liboop is primarily an <em>interface definition</em>. It defines an interface |
||
| 12 | which components may use to request notification when an <em>event</em> |
||
| 13 | (activity on a file descriptor, the real-time clock reaches a certain value, |
||
| 14 | a particular signal is received) occurs. The component which owns the event |
||
| 15 | loop -- the component whose code is active when the system is idle -- |
||
| 16 | implements the interface; it is an <em>event source</em>. Components which |
||
| 17 | are interested in events register themselves with the event source; they are |
||
| 18 | <em>event sinks</em>. Event sinks may themselves source other, higher-level |
||
| 19 | events, but that is outside liboop's scope. |
||
| 20 | |||
| 21 | <h4>Control flow.</h4> |
||
| 22 | |||
| 23 | During initialization, the event source is created. At least one event sink |
||
| 24 | is also created, and registered with the event source. Once initialization |
||
| 25 | completes, control is transferred to the event source, which (at its core) |
||
| 26 | waits for events, usually using a system function like select() or poll(). |
||
| 27 | When an event occurs, the event source gives a <em>callback</em> to all the |
||
| 28 | event sinks which registered interest in that event. |
||
| 29 | <p> |
||
| 30 | During callbacks, the event sinks react to the event as appropriate (usually |
||
| 31 | performing some I/O, or at least modifying internal state). Event sinks for |
||
| 32 | events which are no longer relevant may be unregistered; new event sinks may |
||
| 33 | be registered for additional events. Each event sink, when it finishes, |
||
| 34 | returns a value which tells the event source whether to continue processing |
||
| 35 | events or whether to terminate. |
||
| 36 | <p> |
||
| 37 | While the event source must be fully reentrant (registration and deregistration |
||
| 38 | may, and indeed usually are, performed within the context of an event), event |
||
| 39 | sinks need not be; no event sink will be called while another event sink is |
||
| 40 | active. |
||
| 41 | <p> |
||
| 42 | If no event sink instructs the event source to terminate, the event source |
||
| 43 | continues waiting for events. Otherwise, the event source returns to its |
||
| 44 | caller, which usually shuts down the system. |
||
| 45 | |||
| 46 | <h4>The system event source.</h4> |
||
| 47 | |||
| 48 | Liboop comes with a single "reference" implementation of an event source. |
||
| 49 | This event source uses select() to dispatch events. Most programs built |
||
| 50 | around liboop will probably use the standard system event source; legacy |
||
| 51 | programs with their own event loop, or programs with specialized needs may |
||
| 52 | implement their own event source. |
||
| 53 | |||
| 54 | <h4>Adapters.</h4> |
||
| 55 | |||
| 56 | Liboop supports <em>adapters</em> to enable legacy components to use the liboop |
||
| 57 | interface. For example, many widget sets have their own event loop and their |
||
| 58 | own mechanism for registering callbacks on timeouts and file descriptor |
||
| 59 | activity; liboop uses <em>source adapters</em> that accept registration, |
||
| 60 | register corresponding callbacks with the widget set's event loop, and route |
||
| 61 | events appropriately. Such adapters let general-purpose liboop-based |
||
| 62 | components work in an application based on that widget set. |
||
| 63 | <p> |
||
| 64 | Similarly, some components are designed to work in a non-blocking fashion, and |
||
| 65 | they might be used with a <em>sink adapter</em> to work with liboop. An |
||
| 66 | asynchronous DNS query package, for example, could work as a liboop sink that |
||
| 67 | ultimately generates a higher-level "success" or "failure" callback to the |
||
| 68 | invoking routine. |
||
| 69 | |||
| 70 | <h4>Code.</h4> |
||
| 71 | |||
| 72 | Liboop's abstract event source interface is implemented as a structure |
||
| 73 | containing C function pointers. These functions accept a pointer to the |
||
| 74 | structure as their first argument; sources are expected to include their |
||
| 75 | own data (in whatever format) with the core function pointers. Callbacks |
||
| 76 | are also C function pointers, with "void *" arguments to pass data. |
||
| 77 | <p> |
||
| 12 | magnus | 78 | For more about the liboop interface, see the <a href="ref.html">reference</a>. |
| 3 | magnus | 79 | |
| 80 | <hr><a href="">liboop home</a></body></html> |