ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libev/ev++.h
Revision: 1.29
Committed: Fri Jan 18 18:15:01 2008 UTC (16 years, 3 months ago) by llucax
Content type: text/plain
Branch: MAIN
Changes since 1.28: +5 -0 lines
Log Message:
Add missing ev_time () to ev namespace, but renamed as now ().

Note there is no colission with ev_now (), which is a member function of
loop_ref named in the C++ interface.

File Contents

# User Rev Content
1 root 1.21 /*
2     * libev simple C++ wrapper classes
3     *
4     * Copyright (c) 2007 Marc Alexander Lehmann <libev@schmorp.de>
5     * All rights reserved.
6     *
7     * Redistribution and use in source and binary forms, with or without modifica-
8     * tion, are permitted provided that the following conditions are met:
9     *
10     * 1. Redistributions of source code must retain the above copyright notice,
11     * this list of conditions and the following disclaimer.
12     *
13     * 2. Redistributions in binary form must reproduce the above copyright
14     * notice, this list of conditions and the following disclaimer in the
15     * documentation and/or other materials provided with the distribution.
16     *
17     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18     * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19     * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20     * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
21     * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
25     * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26     * OF THE POSSIBILITY OF SUCH DAMAGE.
27     *
28     * Alternatively, the contents of this file may be used under the terms of
29     * the GNU General Public License ("GPL") version 2 or any later version,
30     * in which case the provisions of the GPL are applicable instead of
31     * the above. If you wish to allow the use of your version of this file
32     * only under the terms of the GPL and not to allow others to use your
33     * version of this file under the BSD license, indicate your decision
34     * by deleting the provisions above and replace them with the notice
35     * and other provisions required by the GPL. If you do not delete the
36     * provisions above, a recipient may use your version of this file under
37     * either the BSD or the GPL.
38     */
39    
40 root 1.1 #ifndef EVPP_H__
41     #define EVPP_H__
42    
43 root 1.20 #ifdef EV_H
44     # include EV_H
45     #else
46 root 1.22 # include "ev.h"
47 root 1.20 #endif
48 root 1.1
49     namespace ev {
50    
51 llucax 1.24 typedef ev_tstamp tstamp;
52    
53     enum {
54     UNDEF = EV_UNDEF,
55     NONE = EV_NONE,
56     READ = EV_READ,
57     WRITE = EV_WRITE,
58     TIMEOUT = EV_TIMEOUT,
59     PERIODIC = EV_PERIODIC,
60     SIGNAL = EV_SIGNAL,
61     CHILD = EV_CHILD,
62     STAT = EV_STAT,
63     IDLE = EV_IDLE,
64     CHECK = EV_CHECK,
65     PREPARE = EV_PREPARE,
66     FORK = EV_FORK,
67     EMBED = EV_EMBED,
68     ERROR = EV_ERROR,
69     };
70    
71 llucax 1.25 enum
72     {
73     AUTO = EVFLAG_AUTO,
74     NOENV = EVFLAG_NOENV,
75     FORKCHECK = EVFLAG_FORKCHECK,
76     SELECT = EVBACKEND_SELECT,
77     POLL = EVBACKEND_POLL,
78     EPOLL = EVBACKEND_EPOLL,
79     KQUEUE = EVBACKEND_KQUEUE,
80     DEVPOLL = EVBACKEND_DEVPOLL,
81     PORT = EVBACKEND_PORT
82     };
83    
84     enum
85     {
86     NONBLOCK = EVLOOP_NONBLOCK,
87     ONESHOT = EVLOOP_ONESHOT
88     };
89    
90     enum how_t
91     {
92     ONE = EVUNLOOP_ONE,
93     ALL = EVUNLOOP_ALL
94     };
95    
96 llucax 1.28 #ifdef EV_AX
97     # undef EV_AX
98     #endif
99    
100     #ifdef EV_AX_
101     # undef EV_AX_
102     #endif
103    
104     #if EV_MULTIPLICITY
105     # define EV_AX raw_loop
106     # define EV_AX_ raw_loop,
107     #else
108     # define EV_AX
109     # define EV_AX_
110     #endif
111    
112     struct loop_ref
113     {
114    
115     loop_ref (EV_P)
116     #if EV_MULTIPLICITY
117     : EV_AX (EV_A)
118     #endif
119     {
120     }
121    
122     bool operator== (const loop_ref &other) const
123     {
124     #if EV_MULTIPLICITY
125     return this->EV_AX == other.EV_AX;
126     #else
127     return true;
128     #endif
129     }
130    
131     bool operator!= (const loop_ref &other) const
132     {
133     #if EV_MULTIPLICITY
134     return ! (*this == other);
135     #else
136     return false;
137     #endif
138     }
139    
140     #if EV_MULTIPLICITY
141     bool operator== (struct ev_loop *other) const
142     {
143     return this->EV_AX == other;
144     }
145    
146     bool operator!= (struct ev_loop *other) const
147     {
148     return ! (*this == other);
149     }
150    
151     bool operator== (const struct ev_loop *other) const
152     {
153     return this->EV_AX == other;
154     }
155    
156     bool operator!= (const struct ev_loop *other) const
157     {
158     return (*this == other);
159     }
160    
161     operator struct ev_loop * () const
162     {
163     return EV_AX;
164     }
165    
166     operator const struct ev_loop * () const
167     {
168     return EV_AX;
169     }
170    
171     bool is_default () const
172     {
173     return EV_AX == ev_default_loop (0);
174     }
175     #endif
176    
177     void loop (int flags = 0)
178     {
179     ev_loop (EV_AX_ flags);
180     }
181    
182     void unloop (how_t how = ONE)
183     {
184     ev_unloop (EV_AX_ how);
185     }
186    
187     void post_fork ()
188     {
189     #if EV_MULTIPLICITY
190     ev_loop_fork (EV_AX);
191     #else
192     ev_default_fork ();
193     #endif
194     }
195    
196     unsigned int count () const
197     {
198     return ev_loop_count (EV_AX);
199     }
200    
201     unsigned int backend () const
202     {
203     return ev_backend (EV_AX);
204     }
205    
206     tstamp now () const
207     {
208     return ev_now (EV_AX);
209     }
210    
211     void ref ()
212     {
213     ev_ref (EV_AX);
214     }
215    
216     void unref ()
217     {
218     ev_unref (EV_AX);
219     }
220    
221     void set_io_collect_interval (tstamp interval)
222     {
223     ev_set_io_collect_interval (EV_AX_ interval);
224     }
225    
226     void set_timeout_collect_interval (tstamp interval)
227     {
228     ev_set_timeout_collect_interval (EV_AX_ interval);
229     }
230    
231     // function callback
232     void once (int fd, int events, tstamp timeout, void (*cb)(int, void *), void* arg = 0)
233     {
234     ev_once (EV_AX_ fd, events, timeout, cb, arg);
235     }
236    
237     // method callback
238     template<class K, void (K::*method)(int)>
239     void once (int fd, int events, tstamp timeout, K *object)
240     {
241     once (fd, events, timeout, method_thunk<K, method>, object);
242     }
243    
244     template<class K, void (K::*method)(int)>
245     static void method_thunk (int revents, void* arg)
246     {
247     K *obj = static_cast<K *>(arg);
248     (obj->*method) (revents);
249     }
250    
251     // const method callback
252     template<class K, void (K::*method)(int) const>
253     void once (int fd, int events, tstamp timeout, const K *object)
254     {
255     once (fd, events, timeout, const_method_thunk<K, method>, object);
256     }
257    
258     template<class K, void (K::*method)(int) const>
259     static void const_method_thunk (int revents, void* arg)
260     {
261     K *obj = static_cast<K *>(arg);
262     (obj->*method) (revents);
263     }
264    
265     // simple method callback
266     template<class K, void (K::*method)()>
267     void once (int fd, int events, tstamp timeout, K *object)
268     {
269     once (fd, events, timeout, method_noargs_thunk<K, method>, object);
270     }
271    
272     template<class K, void (K::*method)()>
273     static void method_noargs_thunk (int revents, void* arg)
274     {
275     K *obj = static_cast<K *>(arg);
276     (obj->*method) ();
277     }
278    
279     // simpler function callback
280     template<void (*cb)(int)>
281     void once (int fd, int events, tstamp timeout)
282     {
283     once (fd, events, timeout, simpler_func_thunk<cb>);
284     }
285    
286     template<void (*cb)(int)>
287     static void simpler_func_thunk (int revents, void* arg)
288     {
289     (*cb) (revents);
290     }
291    
292     // simplest function callback
293     template<void (*cb)()>
294     void once (int fd, int events, tstamp timeout)
295     {
296     once (fd, events, timeout, simplest_func_thunk<cb>);
297     }
298    
299     template<void (*cb)()>
300     static void simplest_func_thunk (int revents, void* arg)
301     {
302     (*cb) ();
303     }
304    
305     void feed_fd_event (int fd, int revents)
306     {
307     ev_feed_fd_event (EV_AX_ fd, revents);
308     }
309    
310     void feed_signal_event (int signum)
311     {
312     ev_feed_signal_event (EV_AX_ signum);
313     }
314    
315     #if EV_MULTIPLICITY
316     struct ev_loop* EV_AX;
317     #endif
318    
319     };
320    
321     #if EV_MULTIPLICITY
322     struct dynamic_loop: loop_ref
323     {
324    
325     dynamic_loop (unsigned int flags = AUTO)
326     : loop_ref (ev_loop_new (flags))
327     {
328     }
329    
330     ~dynamic_loop ()
331     {
332     ev_loop_destroy (EV_AX);
333     EV_AX = 0;
334     }
335    
336     private:
337    
338     dynamic_loop (const dynamic_loop &);
339    
340     dynamic_loop & operator= (const dynamic_loop &);
341    
342     };
343     #endif
344    
345     struct default_loop: loop_ref
346     {
347    
348     default_loop (unsigned int flags = AUTO)
349     #if EV_MULTIPLICITY
350     : loop_ref (ev_default_loop (flags))
351     {
352     }
353     #else
354     {
355     ev_default_loop (flags);
356     }
357     #endif
358    
359     ~default_loop ()
360     {
361     ev_default_destroy ();
362     #if EV_MULTIPLICITY
363     EV_AX = 0;
364     #endif
365     }
366    
367     private:
368    
369     default_loop (const default_loop &);
370    
371     default_loop & operator= (const default_loop &);
372    
373     };
374    
375     inline loop_ref get_default_loop ()
376     {
377     #if EV_MULTIPLICITY
378     return ev_default_loop (0);
379     #else
380     return loop_ref ();
381     #endif
382     }
383    
384     #undef EV_AX
385     #undef EV_AX_
386    
387     #undef EV_PX
388     #undef EV_PX_
389     #if EV_MULTIPLICITY
390     # define EV_PX loop_ref EV_A
391     # define EV_PX_ loop_ref EV_A_
392     #else
393     # define EV_PX
394     # define EV_PX_
395     #endif
396    
397 root 1.13 template<class ev_watcher, class watcher>
398     struct base : ev_watcher
399 root 1.1 {
400 root 1.13 #if EV_MULTIPLICITY
401 llucax 1.28 EV_PX;
402 root 1.1
403 llucax 1.28 void set (EV_PX)
404 root 1.13 {
405     this->EV_A = EV_A;
406     }
407     #endif
408 root 1.1
409 llucax 1.28 base (EV_PX)
410     #if EV_MULTIPLICITY
411     : EV_A (EV_A)
412     #endif
413 root 1.13 {
414     ev_init (this, 0);
415     }
416    
417 root 1.18 void set_ (void *data, void (*cb)(EV_P_ ev_watcher *w, int revents))
418 root 1.13 {
419 root 1.17 this->data = data;
420 root 1.18 ev_set_cb (static_cast<ev_watcher *>(this), cb);
421 root 1.13 }
422    
423 root 1.19 // method callback
424 root 1.13 template<class K, void (K::*method)(watcher &w, int)>
425     void set (K *object)
426     {
427     set_ (object, method_thunk<K, method>);
428     }
429    
430     template<class K, void (K::*method)(watcher &w, int)>
431 root 1.18 static void method_thunk (EV_P_ ev_watcher *w, int revents)
432 root 1.13 {
433 root 1.17 K *obj = static_cast<K *>(w->data);
434 root 1.18 (obj->*method) (*static_cast<watcher *>(w), revents);
435 root 1.13 }
436    
437 root 1.19 // const method callback
438 root 1.13 template<class K, void (K::*method)(watcher &w, int) const>
439     void set (const K *object)
440     {
441     set_ (object, const_method_thunk<K, method>);
442     }
443    
444     template<class K, void (K::*method)(watcher &w, int) const>
445 root 1.18 static void const_method_thunk (EV_P_ ev_watcher *w, int revents)
446 root 1.13 {
447 root 1.17 K *obj = static_cast<K *>(w->data);
448 root 1.18 (static_cast<K *>(w->data)->*method) (*static_cast<watcher *>(w), revents);
449 root 1.13 }
450    
451 root 1.19 // function callback
452 root 1.17 template<void (*function)(watcher &w, int)>
453     void set (void *data = 0)
454 root 1.13 {
455 root 1.16 set_ (data, function_thunk<function>);
456 root 1.13 }
457    
458     template<void (*function)(watcher &w, int)>
459 root 1.18 static void function_thunk (EV_P_ ev_watcher *w, int revents)
460 root 1.13 {
461 root 1.18 function (*static_cast<watcher *>(w), revents);
462 root 1.13 }
463    
464 root 1.19 // simple callback
465     template<class K, void (K::*method)()>
466     void set (K *object)
467     {
468     set_ (object, method_noargs_thunk<K, method>);
469     }
470    
471     template<class K, void (K::*method)()>
472     static void method_noargs_thunk (EV_P_ ev_watcher *w, int revents)
473     {
474     K *obj = static_cast<K *>(w->data);
475     (obj->*method) ();
476     }
477    
478 root 1.13 void operator ()(int events = EV_UNDEF)
479     {
480 root 1.14 return ev_cb (static_cast<ev_watcher *>(this))
481     (static_cast<ev_watcher *>(this), events);
482 root 1.13 }
483    
484     bool is_active () const
485 root 1.1 {
486 root 1.13 return ev_is_active (static_cast<const ev_watcher *>(this));
487 root 1.1 }
488    
489 root 1.13 bool is_pending () const
490 root 1.1 {
491 root 1.13 return ev_is_pending (static_cast<const ev_watcher *>(this));
492 root 1.1 }
493 llucax 1.27
494     void feed_event (int revents)
495     {
496     ev_feed_event (EV_A_ static_cast<const ev_watcher *>(this), revents);
497     }
498 root 1.1 };
499    
500 llucax 1.29 inline tstamp now ()
501     {
502     return ev_time ();
503     }
504    
505 llucax 1.26 inline void delay (tstamp interval)
506     {
507     ev_sleep (interval);
508     }
509    
510     inline int version_major ()
511     {
512     return ev_version_major ();
513     }
514    
515     inline int version_minor ()
516     {
517     return ev_version_minor ();
518     }
519    
520     inline unsigned int supported_backends ()
521     {
522     return ev_supported_backends ();
523     }
524    
525     inline unsigned int recommended_backends ()
526     {
527     return ev_recommended_backends ();
528     }
529    
530     inline unsigned int embeddable_backends ()
531     {
532     return ev_embeddable_backends ();
533     }
534    
535     inline void set_allocator (void *(*cb)(void *ptr, long size))
536     {
537     ev_set_allocator (cb);
538     }
539    
540     inline void set_syserr_cb (void (*cb)(const char *msg))
541     {
542     ev_set_syserr_cb (cb);
543     }
544    
545 root 1.1 #if EV_MULTIPLICITY
546 llucax 1.28 #define EV_CONSTRUCT(cppstem,cstem) \
547     (EV_PX = get_default_loop ()) \
548     : base<ev_ ## cstem, cppstem> (EV_A) \
549 root 1.1 { \
550 root 1.13 }
551 root 1.1 #else
552 llucax 1.28 #define EV_CONSTRUCT(cppstem,cstem) \
553 root 1.13 () \
554     { \
555     }
556 root 1.1 #endif
557    
558     /* using a template here would require quite a bit more lines,
559     * so a macro solution was chosen */
560 root 1.4 #define EV_BEGIN_WATCHER(cppstem,cstem) \
561 root 1.1 \
562 root 1.13 struct cppstem : base<ev_ ## cstem, cppstem> \
563 root 1.1 { \
564     void start () \
565     { \
566     ev_ ## cstem ## _start (EV_A_ static_cast<ev_ ## cstem *>(this)); \
567     } \
568     \
569     void stop () \
570     { \
571     ev_ ## cstem ## _stop (EV_A_ static_cast<ev_ ## cstem *>(this)); \
572     } \
573     \
574 llucax 1.28 cppstem EV_CONSTRUCT(cppstem,cstem) \
575 root 1.1 \
576 root 1.3 ~cppstem () \
577     { \
578     stop (); \
579     } \
580     \
581 root 1.13 using base<ev_ ## cstem, cppstem>::set; \
582     \
583 root 1.1 private: \
584     \
585 llucax 1.23 cppstem (const cppstem &o); \
586 root 1.6 \
587 llucax 1.23 cppstem & operator =(const cppstem &o); \
588 root 1.1 \
589     public:
590    
591 root 1.4 #define EV_END_WATCHER(cppstem,cstem) \
592 root 1.6 };
593 root 1.4
594     EV_BEGIN_WATCHER (io, io)
595 root 1.1 void set (int fd, int events)
596     {
597     int active = is_active ();
598     if (active) stop ();
599     ev_io_set (static_cast<ev_io *>(this), fd, events);
600     if (active) start ();
601     }
602    
603     void set (int events)
604     {
605     int active = is_active ();
606     if (active) stop ();
607     ev_io_set (static_cast<ev_io *>(this), fd, events);
608     if (active) start ();
609     }
610    
611     void start (int fd, int events)
612     {
613     set (fd, events);
614     start ();
615     }
616 root 1.4 EV_END_WATCHER (io, io)
617 root 1.1
618 root 1.4 EV_BEGIN_WATCHER (timer, timer)
619 root 1.1 void set (ev_tstamp after, ev_tstamp repeat = 0.)
620     {
621     int active = is_active ();
622     if (active) stop ();
623     ev_timer_set (static_cast<ev_timer *>(this), after, repeat);
624     if (active) start ();
625     }
626    
627     void start (ev_tstamp after, ev_tstamp repeat = 0.)
628     {
629     set (after, repeat);
630     start ();
631     }
632    
633     void again ()
634     {
635     ev_timer_again (EV_A_ static_cast<ev_timer *>(this));
636     }
637 root 1.4 EV_END_WATCHER (timer, timer)
638 root 1.1
639 root 1.8 #if EV_PERIODIC_ENABLE
640 root 1.4 EV_BEGIN_WATCHER (periodic, periodic)
641 root 1.1 void set (ev_tstamp at, ev_tstamp interval = 0.)
642     {
643     int active = is_active ();
644     if (active) stop ();
645     ev_periodic_set (static_cast<ev_periodic *>(this), at, interval, 0);
646     if (active) start ();
647     }
648    
649     void start (ev_tstamp at, ev_tstamp interval = 0.)
650     {
651     set (at, interval);
652     start ();
653     }
654    
655     void again ()
656     {
657     ev_periodic_again (EV_A_ static_cast<ev_periodic *>(this));
658     }
659 root 1.4 EV_END_WATCHER (periodic, periodic)
660 root 1.3 #endif
661 root 1.1
662 root 1.4 EV_BEGIN_WATCHER (sig, signal)
663 root 1.1 void set (int signum)
664     {
665     int active = is_active ();
666     if (active) stop ();
667     ev_signal_set (static_cast<ev_signal *>(this), signum);
668     if (active) start ();
669     }
670    
671     void start (int signum)
672     {
673     set (signum);
674     start ();
675     }
676 root 1.4 EV_END_WATCHER (sig, signal)
677 root 1.1
678 root 1.4 EV_BEGIN_WATCHER (child, child)
679 root 1.1 void set (int pid)
680     {
681     int active = is_active ();
682     if (active) stop ();
683     ev_child_set (static_cast<ev_child *>(this), pid);
684     if (active) start ();
685     }
686    
687     void start (int pid)
688     {
689     set (pid);
690     start ();
691     }
692 root 1.4 EV_END_WATCHER (child, child)
693 root 1.1
694 root 1.8 #if EV_STAT_ENABLE
695     EV_BEGIN_WATCHER (stat, stat)
696     void set (const char *path, ev_tstamp interval = 0.)
697     {
698     int active = is_active ();
699     if (active) stop ();
700     ev_stat_set (static_cast<ev_stat *>(this), path, interval);
701     if (active) start ();
702     }
703    
704     void start (const char *path, ev_tstamp interval = 0.)
705     {
706 root 1.12 stop ();
707 root 1.8 set (path, interval);
708     start ();
709     }
710    
711     void update ()
712     {
713     ev_stat_stat (EV_A_ static_cast<ev_stat *>(this));
714     }
715     EV_END_WATCHER (stat, stat)
716     #endif
717    
718     EV_BEGIN_WATCHER (idle, idle)
719     void set () { }
720     EV_END_WATCHER (idle, idle)
721 root 1.7
722 root 1.8 EV_BEGIN_WATCHER (prepare, prepare)
723     void set () { }
724     EV_END_WATCHER (prepare, prepare)
725    
726     EV_BEGIN_WATCHER (check, check)
727     void set () { }
728     EV_END_WATCHER (check, check)
729    
730     #if EV_EMBED_ENABLE
731 root 1.7 EV_BEGIN_WATCHER (embed, embed)
732     void start (struct ev_loop *embedded_loop)
733     {
734 root 1.12 stop ();
735     ev_embed_set (static_cast<ev_embed *>(this), embedded_loop);
736 root 1.7 start ();
737     }
738    
739     void sweep ()
740     {
741     ev_embed_sweep (EV_A_ static_cast<ev_embed *>(this));
742     }
743     EV_END_WATCHER (embed, embed)
744     #endif
745    
746 root 1.10 #if EV_FORK_ENABLE
747     EV_BEGIN_WATCHER (fork, fork)
748     void set () { }
749     EV_END_WATCHER (fork, fork)
750     #endif
751    
752 llucax 1.28 #undef EV_PX
753     #undef EV_PX_
754 root 1.1 #undef EV_CONSTRUCT
755 root 1.4 #undef EV_BEGIN_WATCHER
756 root 1.7 #undef EV_END_WATCHER
757 llucax 1.28
758 root 1.1 }
759    
760     #endif
761