event-loop documentation update
[wmiirc-lua.git] / doc / event-loop
blob6ca255c09823158007900d027ed4c4c018826202
1 == About
3 The problem is that the libixp interface does not permit a select() loop to
4 be ran against the ixp socket w/o a major rewrite of the ixp library.  I
5 am not interested in this.
7 == The eventloop library
9 The cleanest way to handle multiple event sources is via a select() or
10 poll() loop.  However the blocking nature of libixp is still a problem.
11 Fortunately, there is only one file in wmii's ixp filesystem that would
12 cause blocking... the /event file.  This is a magic file that never
13 stops generating content; at least not while wmii is running.
15 To handle IO on all wmii files we use the libixp.so library.  It's
16 already good at what it does... accessing readily available content.
17 For handling the read of the /event file we fork off a wmiir process to
18 read it.  This process is connected to the main program via a pipe(2).
19 One side of the pipe is fed by wmiir, and the other is used on the lua
20 side in a select() loop.
22 The select loop is implemented in C, and exported to lua as an eventloop
23 module.  wmii.lua creates an eventloop instance and adds a wmiir process
24 to it via an api call.  It then calls a run_loop() function with a
25 duration which causes the select loop to run for that much time, or less
26 if data is generated by the wmiir process.  On return from the
27 run_loop() function, wmii.lua executes the next timer that's queued up.
29 Here is what it looks like:
31         el = eventloop.new()
32         el.add_exec ("wmiir read /events",
33                         function (line)
34                                 ... process event ...
35                         end)
36         ...
37         while true do
38                 local next_timer = handle_timers()
39                 el.run_loop(next_timer)
40         end
42 The nice thing about this is that plugins can use this to generate
43 output on the bar:
45         widget = wmii.widget:new ("990_load")
46         el.add_exec ("dstat --load --nocolor --noheaders --noupdate",
47                         function (line)
48                                 widget:show (line)
49                         end)
51 This makes it really clean to get events from other sources.  We can
52 fork off netcat or tail to get other events.  Best of all no threads or
53 alarm hacks.
55 And the ASCII diagram looks like this.
57     (1)                (3)                      (4)
58   +------+  (ixp) +--------+   read/write() +------------+
59   | wmii | <----- | ixp.so | <------------- | wmiirc.lua |
60   +------+        +--------+                +------------+
61         ^                                         |
62         |                                         v 
63         | (ixp)       (6)                  +--------------+
64      +-------------------+     (fifo)      | eventloop.so | (5)
65      | wmiir read /event | --------------> |   select()   |
66      +-------------------+                 +--------------+
67                                                   |
68                                                   | (fifo)
69                                                   v
70                                            +-------------+
71                                            |  other data | (7)
72                                            |   sources   |
73                                            +-------------+
77 vim: set ts=8 et sw=8 tw=72