]> git.llucax.com Git - software/ev.d.git/blob - ev.d
Initial import of ev.d, a libev bingind for the D Programming Language.
[software/ev.d.git] / ev.d
1 /+
2  + D Programming Language "bindings" to libev
3  + <http://software.schmorp.de/pkg/libev.html>
4  +
5  + Written by Leandro Lucarella (2008).
6  +
7  + Placed under BOLA license <http://auriga.wearlab.de/~alb/bola/> which is
8  + basically public domain.
9  +
10  +/
11
12 module ev;
13
14 enum: uint
15 {
16         UNDEF    = 0xFFFFFFFFL, // guaranteed to be invalid
17         NONE     =       0x00L, // no events
18         READ     =       0x01L, // ev_io detected read will not block
19         WRITE    =       0x02L, // ev_io detected write will not block
20         IOFDSET  =       0x80L, // internal use only
21         TIMEOUT  = 0x00000100L, // timer timed out
22         PERIODIC = 0x00000200L, // periodic timer timed out
23         SIGNAL   = 0x00000400L, // signal was received
24         CHILD    = 0x00000800L, // child/pid had status change
25         STAT     = 0x00001000L, // stat data changed
26         IDLE     = 0x00002000L, // event loop is idling
27         PREPARE  = 0x00004000L, // event loop about to poll
28         CHECK    = 0x00008000L, // event loop finished poll
29         EMBED    = 0x00010000L, // embedded event loop needs sweep
30         FORK     = 0x00020000L, // event loop resumed in child
31         ERROR    = 0x80000000L, // sent when an error occurs
32 }
33
34 enum: uint
35 {
36         // bits for ev_default_loop and ev_loop_new
37         // the default
38         AUTO       = 0x00000000UL, // not quite a mask
39         // flag bits
40         NOENV      = 0x01000000UL, // do NOT consult environment
41         FORKCHECK  = 0x02000000UL, // check for a fork in each iteration
42         // method bits to be ored together
43         SELECT     = 0x00000001UL, // about anywhere
44         POLL       = 0x00000002UL, // !win
45         EPOLL      = 0x00000004UL, // linux
46         KQUEUE     = 0x00000008UL, // bsd
47         DEVPOLL    = 0x00000010UL, // solaris 8 / NYI
48         PORT       = 0x00000020UL, // solaris 10
49 }
50
51 enum
52 {
53         NONBLOCK = 1, // do not block/wait
54         ONESHOT  = 2, // block *once* only
55 }
56
57 enum how
58 {
59         CANCEL = 0, // undo unloop
60         ONE    = 1, // unloop once
61         ALL    = 2, // unloop all loops
62 }
63
64 extern (C)
65 {
66
67         version (EV_ENABLE_SELECT)
68         {
69         }
70         else
71         {
72                 version = EV_PERIODIC_ENABLE;
73                 version = EV_STAT_ENABLE;
74                 version = EV_IDLE_ENABLE;
75                 version = EV_FORK_ENABLE;
76                 version = EV_EMBED_ENABLE;
77         }
78
79         alias double ev_tstamp;
80
81         struct ev_loop_t;
82
83         template EV_COMMON()
84         {
85                 void* data;
86         }
87
88         template EV_CB_DECLARE(TYPE)
89         {
90                 void function (ev_loop_t*, TYPE*, int) cb;
91         }
92
93         template EV_WATCHER(TYPE)
94         {
95                 int active;                 // private
96                 int pending;                // private
97                 int priority;               // private
98                 mixin EV_COMMON;            // rw
99                 mixin EV_CB_DECLARE!(TYPE); // private
100         }
101
102         template EV_WATCHER_LIST(TYPE)
103         {
104                 mixin EV_WATCHER!(TYPE);
105                 ev_watcher_list* next;      // private
106         }
107
108         template EV_WATCHER_TIME(TYPE)
109         {
110                 mixin EV_WATCHER!(TYPE);
111                 ev_tstamp at;               // private
112         }
113
114         align (4) {
115
116                 struct ev_watcher
117                 {
118                         mixin EV_WATCHER!(ev_watcher);
119                 }
120
121                 struct ev_watcher_list
122                 {
123                         mixin EV_WATCHER_LIST!(ev_watcher_list);
124                 }
125
126                 struct ev_watcher_time
127                 {
128                         mixin EV_WATCHER_TIME!(ev_watcher_time);
129                 }
130
131                 struct ev_io
132                 {
133                         mixin EV_WATCHER_LIST!(ev_io);
134                         int fd;     // ro
135                         int events; // ro
136                 }
137
138                 struct ev_timer
139                 {
140                         mixin EV_WATCHER_TIME!(ev_timer);
141                         ev_tstamp repeat; // rw
142                 }
143
144                 version (EV_PERIODIC_ENABLE)
145                 {
146                         struct ev_periodic
147                         {
148                                 mixin EV_WATCHER_TIME!(ev_periodic);
149                                 ev_tstamp offset;                     // rw
150                                 ev_tstamp interval;                   // rw
151                                 ev_tstamp function(ev_periodic *w,
152                                         ev_tstamp now) reschedule_cb; // rw
153                         }
154                 }
155
156                 struct ev_signal
157                 {
158                         mixin EV_WATCHER_LIST!(ev_signal);
159                         int signum; // ro
160                 }
161
162                 struct ev_child
163                 {
164                         mixin EV_WATCHER_LIST!(ev_child);
165                         int pid;     // ro
166                         int rpid;    // rw, holds the received pid
167                         int rstatus; // rw, holds the exit status, use the
168                                      // macros from sys/wait.h
169                 }
170
171                 version (EV_STAT_ENABLE)
172                 {
173
174                         version (Windows) // alias _stati64 ev_statdata;
175                         {
176                                 pragma (msg, "ev_stat not supported in windows "
177                                                 "because I don't know the "
178                                                 "layout of _stati64");
179                                 static assert(0);
180                                 // Maybe this should work?
181                                 //static import stat = std.c.windows.stat;
182                                 //alias stat.struct_stat ev_statdata;
183                         }
184                         else // It should be POSIX
185                         {
186                                 static import stat = std.c.unix.unix;
187                                 alias stat.struct_stat ev_statdata;
188                         }
189
190                         struct ev_stat
191                         {
192                                 mixin EV_WATCHER_LIST!(ev_stat);
193
194                                 ev_timer timer;     // private
195                                 ev_tstamp interval; // ro
196                                 const char *path;   // ro
197                                 ev_statdata prev;   // ro
198                                 ev_statdata attr;   // ro
199                                 int wd; // wd for inotify, fd for kqueue
200                         }
201                 }
202
203                 version (EV_IDLE_ENABLE)
204                 {
205                         struct ev_idle
206                         {
207                                 mixin EV_WATCHER!(ev_idle);
208                         }
209                 }
210
211                 struct ev_prepare
212                 {
213                         mixin EV_WATCHER!(ev_prepare);
214                 }
215
216                 struct ev_check
217                 {
218                         mixin EV_WATCHER!(ev_check);
219                 }
220
221                 version (EV_FORK_ENABLE)
222                 {
223                         struct ev_fork
224                         {
225                                 mixin EV_WATCHER!(ev_fork);
226                         }
227                 }
228
229                 version (EV_EMBED_ENABLE)
230                 {
231                         struct ev_embed
232                         {
233                                 mixin EV_WATCHER!(ev_embed);
234                                 ev_loop_t* other;     // ro
235                                 ev_io io;             // private
236                                 ev_prepare prepare;   // private
237                                 ev_check check;       // unused
238                                 ev_timer timer;       // unused
239                                 ev_periodic periodic; // unused
240                                 ev_idle idle;         // unused
241                                 ev_fork fork;         // unused
242                         }
243                 }
244         }
245
246         int ev_version_major();
247         int ev_version_minor();
248
249         uint ev_supported_backends();
250         uint ev_recommended_backends();
251         uint ev_embeddable_backends();
252
253         ev_tstamp ev_time();
254         void ev_sleep(ev_tstamp delay); // sleep for a while
255
256         // Sets the allocation function to use, works like realloc.
257         // It is used to allocate and free memory.
258         // If it returns zero when memory needs to be allocated, the library
259         // might abort
260         // or take some potentially destructive action.
261         // The default is your system realloc function.
262         void ev_set_allocator(void* function(void* ptr, int size));
263
264         // set the callback function to call on a
265         // retryable syscall error
266         // (such as failed select, poll, epoll_wait)
267         void ev_set_syserr_cb(void* function(char* msg));
268
269         extern ev_loop_t* ev_default_loop_ptr;
270
271         ev_loop_t* ev_default_loop_init(uint flags);
272
273         // create and destroy alternative loops that don't handle signals
274         ev_loop_t* ev_loop_new(uint flags);
275         void ev_loop_destroy(ev_loop_t*);
276         void ev_loop_fork(ev_loop_t*);
277
278         ev_tstamp ev_now(ev_loop_t*);
279         void ev_default_destroy();
280         void ev_default_fork();
281         uint ev_backend(ev_loop_t*);
282         uint ev_loop_count(ev_loop_t*);
283         void ev_loop(ev_loop_t*, int flags);
284         void ev_unloop(ev_loop_t*, how);
285         void ev_set_io_collect_interval(ev_loop_t*, ev_tstamp interval);
286         void ev_set_timeout_collect_interval(ev_loop_t*, ev_tstamp interval);
287         void ev_ref(ev_loop_t*);
288         void ev_unref(ev_loop_t*);
289         void ev_once(ev_loop_t*, int fd, int events, ev_tstamp timeout,
290                         void function(int revents, void* arg), void* arg);
291
292         void ev_feed_event(ev_loop_t*, void *w, int revents);
293         void ev_feed_fd_event(ev_loop_t*, int fd, int revents);
294         void ev_feed_signal_event (ev_loop_t*, int signum);
295         void ev_invoke(ev_loop_t*, void *w, int revents);
296         int  ev_clear_pending(ev_loop_t*, void *w);
297
298         void ev_io_start(ev_loop_t*, ev_io *w);
299         void ev_io_stop(ev_loop_t*, ev_io *w);
300
301         void ev_timer_start(ev_loop_t*, ev_timer *w);
302         void ev_timer_stop(ev_loop_t*, ev_timer *w);
303         void ev_timer_again(ev_loop_t*, ev_timer *w);
304
305         version (EV_PERIODIC_ENABLE)
306         {
307                 void ev_periodic_start(ev_loop_t*, ev_periodic *w);
308                 void ev_periodic_stop(ev_loop_t*, ev_periodic *w);
309                 void ev_periodic_again(ev_loop_t*, ev_periodic *w);
310         }
311
312         void ev_signal_start(ev_loop_t*, ev_signal *w);
313         void ev_signal_stop(ev_loop_t*, ev_signal *w);
314
315         /* only supported in the default loop */
316         void ev_child_start(ev_loop_t*, ev_child *w);
317         void ev_child_stop(ev_loop_t*, ev_child *w);
318
319         version (EV_STAT_ENABLE)
320         {
321                 void ev_stat_start(ev_loop_t*, ev_stat *w);
322                 void ev_stat_stop(ev_loop_t*, ev_stat *w);
323                 void ev_stat_stat(ev_loop_t*, ev_stat *w);
324         }
325
326         version (EV_IDLE_ENABLE)
327         {
328                 void ev_idle_start(ev_loop_t*, ev_idle *w);
329                 void ev_idle_stop(ev_loop_t*, ev_idle *w);
330         }
331
332         void ev_prepare_start(ev_loop_t*, ev_prepare *w);
333         void ev_prepare_stop(ev_loop_t*, ev_prepare *w);
334
335         void ev_check_start(ev_loop_t*, ev_check *w);
336         void ev_check_stop(ev_loop_t*, ev_check *w);
337
338         version (EV_FORK_ENABLE)
339         {
340                 void ev_fork_start(ev_loop_t*, ev_fork *w);
341                 void ev_fork_stop(ev_loop_t*, ev_fork *w);
342         }
343
344         version (EV_EMBED_ENABLE)
345         {
346                 // only supported when loop to be embedded is in fact embeddable
347                 void ev_embed_start(ev_loop_t*, ev_embed *w);
348                 void ev_embed_stop(ev_loop_t*, ev_embed *w);
349                 void ev_embed_sweep(ev_loop_t*, ev_embed *w);
350         }
351
352         bool ev_is_pending(TYPE)(TYPE* w)
353         {
354                 return w.pending;
355         }
356
357         bool ev_is_active(TYPE)(TYPE* w)
358         {
359                 return w.active;
360         }
361
362         int ev_priority(TYPE)(TYPE* w)
363         {
364                 return w.priority;
365         }
366
367         void function(ev_loop_t*, TYPE*, int) ev_cb(TYPE)(TYPE* w)
368         {
369                 return w.cb;
370         }
371
372         void ev_set_priority(TYPE)(TYPE* w, int pri)
373         {
374                 w.priority = pri;
375         }
376
377         void ev_set_cb(TYPE)(TYPE* w,
378                         void function(ev_loop_t*, TYPE*, int) cb)
379         {
380                 w.cb = cb;
381         }
382
383         void ev_init(TYPE)(TYPE* w,
384                         void function(ev_loop_t*, TYPE*, int) cb)
385         {
386                 w.active = 0;
387                 w.pending = 0;
388                 w.priority = 0;
389                 ev_set_cb(w, cb);
390         }
391
392         void ev_io_set(ev_io* w, int fd, int events)
393         {
394                 w.fd = fd;
395                 w.events = events | IOFDSET;
396         }
397
398         void ev_timer_set(ev_timer* w, ev_tstamp after, ev_tstamp repeat)
399         {
400                 w.at = after;
401                 w.repeat = repeat;
402         }
403
404         void ev_periodic_set(ev_periodic* w, ev_tstamp ofs, ev_tstamp ival,
405                         ev_tstamp function(ev_periodic *w, ev_tstamp now) res)
406         {
407                 w.offset = ofs;
408                 w.interval = ival;
409                 w.reschedule_cb = res;
410         }
411
412         void ev_signal_set(ev_signal* w, int signum)
413         {
414                 w.signum = signum;
415         }
416
417         void ev_child_set(ev_child* w, int pid)
418         {
419                 w.pid = pid;
420         }
421
422         void ev_stat_set(ev_stat* w, char* path, ev_tstamp interval)
423         {
424                 w.path = path;
425                 w.interval = interval;
426                 w.wd = -2;
427         }
428
429         void ev_idle_set(ev_idle* w)
430         {
431         }
432
433         void ev_prepare_set(ev_prepare* w)
434         {
435         }
436
437         void ev_check_set(ev_check* w)
438         {
439         }
440
441         void ev_embed_set(ev_embed* w, ev_loop_t* other)
442         {
443                 w.other = other;
444         }
445
446         void ev_fork_set(ev_fork* w)
447         {
448         }
449
450         void ev_io_init(ev_io* w, void function(ev_loop_t*, ev_io*, int) cb, int fd,
451                         int events)
452         {
453                 ev_init(w, cb);
454                 ev_io_set(w, fd, events);
455         }
456
457         void ev_timer_init(ev_timer* w, void function(ev_loop_t*, ev_timer*, int) cb,
458                         ev_tstamp after, ev_tstamp repeat)
459         {
460                 ev_init(w, cb);
461                 ev_timer_set(w, after, repeat);
462         }
463
464         void ev_periodic_init(ev_periodic* w,
465                         void function(ev_loop_t*, ev_periodic*, int) cb,
466                         ev_tstamp ofs, ev_tstamp ival,
467                         ev_tstamp function(ev_periodic *w, ev_tstamp now) res)
468         {
469                 ev_init(w, cb);
470                 ev_periodic_set(w, ofs, ival, res);
471         }
472
473         void ev_signal_init(ev_signal* w, void function(ev_loop_t*, ev_signal*, int) cb,
474                         int signum)
475         {
476                 ev_init(w, cb);
477                 ev_signal_set(w, signum);
478         }
479
480         void ev_child_init(ev_child* w, void function(ev_loop_t*, ev_child*, int) cb,
481                         int pid)
482         {
483                 ev_init(w, cb);
484                 ev_child_set(w, pid);
485         }
486
487         void ev_stat_init(ev_stat* w, void function(ev_loop_t*, ev_stat*, int) cb,
488                         char* path, ev_tstamp interval)
489         {
490                 ev_init(w, cb);
491                 ev_stat_set(w, path, interval);
492         }
493
494         void ev_idle_init(ev_idle* w, void function(ev_loop_t*, ev_idle*, int) cb)
495         {
496                 ev_init(w, cb);
497                 ev_idle_set(w);
498         }
499
500         void ev_prepare_init(ev_prepare* w,
501                         void function(ev_loop_t*, ev_prepare*, int) cb)
502         {
503                 ev_init(w, cb);
504                 ev_prepare_set(w);
505         }
506
507         void ev_check_init(ev_check* w, void function(ev_loop_t*, ev_check*, int) cb)
508         {
509                 ev_init(w, cb);
510                 ev_check_set(w);
511         }
512
513         void ev_embed_init(ev_embed* w, void function(ev_loop_t*, ev_embed*, int) cb,
514                         ev_loop_t* other)
515         {
516                 ev_init(w, cb);
517                 ev_embed_set(w, other);
518         }
519
520         void ev_fork_init(ev_fork* w, void function(ev_loop_t*, ev_fork*, int) cb)
521         {
522                 ev_init(w, cb);
523                 ev_fork_set(w);
524         }
525
526         ev_loop_t* ev_default_loop(uint flags = AUTO)
527         {
528                 if (!ev_default_loop_ptr)
529                         ev_default_loop_init(flags);
530                 return ev_default_loop_ptr;
531         }
532
533 }
534