]> git.llucax.com Git - software/eventxx.git/blobdiff - eventxx
Use enums for several flags.
[software/eventxx.git] / eventxx
diff --git a/eventxx b/eventxx
index 080f40c3c5251fdbeb2f8e8fb54f04430781e216..93e2669b8db40173ed41e7daaa01d339f3e1cceb 100644 (file)
--- a/eventxx
+++ b/eventxx
@@ -25,7 +25,7 @@
  * to redesign the applications. As a result, Libevent allows for portable
  * application development and provides the most scalable event notification
  * mechanism available on an operating system. Libevent should compile on Linux,
- * *BSD, Mac OS X, Solaris and Windows. 
+ * *BSD, Mac OS X, Solaris and Windows.
  *
  * This is a simple, direct, one-header inline C++ wrapper for libevent.
  * It's designed to be as close to use to libevent without compromising modern
@@ -130,7 +130,9 @@ struct invalid_priority: public std::invalid_argument, public exception
 /// Miscelaneous constants
 enum
 {
-       DEFAULT_PRIORITY = -1 ///< Default priority (the middle value)
+       DEFAULT_PRIORITY = -1,      ///< Default priority (the middle value).
+       ONCE = EVLOOP_ONCE,         ///< Loop just once.
+       NONBLOCK = EVLOOP_NONBLOCK  ///< Don't block the event loop.
 };
 
 
@@ -189,6 +191,26 @@ struct time: ::timeval
 /// @defgroup events Events
 //@{
 
+/**
+ * Type of events.
+ *
+ * There are 4 kind of events: eventxx::TIMEOUT, eventxx::READ, eventxx::WRITE
+ * or eventxx::SIGNAL. eventxx::PERSIST is not an event, is an event modifier
+ * flag, that tells eventxx that this event should live until dispatcher::del()
+ * is called. You can use, for example:
+ * @code
+ * eventxx::event(fd, eventxx::READ | eventxx::PERSIST, ...);
+ * @endcode
+ */
+enum type
+{
+       TIMEOUT = EV_TIMEOUT, ///< Timeout event.
+       READ = EV_READ,       ///< Read event.
+       WRITE = EV_WRITE,     ///< Write event.
+       SIGNAL = EV_SIGNAL,   ///< Signal event.
+       PERSIST = EV_PERSIST  ///< Not really an event, is an event modifier.
+};
+
 /**
  * Basic event from which all events derive.
  *
@@ -208,7 +230,7 @@ struct basic_event: internal::event
         *
         * @return true if there is a pending event, false if not.
         */
-       bool pending(short ev) const throw()
+       bool pending(type ev) const throw()
        {
                // HACK libevent don't use const
                return event_pending(const_cast< basic_event* >(this), ev, 0);
@@ -232,6 +254,8 @@ struct basic_event: internal::event
         *
         * @param priority New event priority.
         *
+        * @pre The event must be added to some dispatcher.
+        *
         * @see dispatcher::dispatcher(int)
         */
        void priority(int priority) const throw(invalid_event, invalid_priority)
@@ -268,12 +292,13 @@ struct basic_event: internal::event
  * Generic event object.
  *
  * This object stores all the information about an event, incluiding a callback
- * functor, which is called then the event is fired. Then template parameter
- * must be a callable object (functor) that can take 2 parameters: an integer
- * (the file descriptor of the fired event) and a short (the type of event
- * fired: EV_TIMEOUT, EV_SIGNAL, EV_READ, EV_WRITE). There is an specialized
- * version of this class which takes as the template parameter a C function
- * with the ccallback_type signature, just like C libevent API does.
+ * functor, which is called when the event is fired. The template parameter
+ * must be a functor (callable object or function) that can take 2 parameters:
+ * an integer (the file descriptor of the fired event) and an event::type (the
+ * type of event being fired).
+ * There is a specialized version of this class which takes as the template
+ * parameter a C function with the ccallback_type signature, just like C
+ * libevent API does.
  *
  * @see eventxx::event< ccallback_type >
  */
@@ -285,17 +310,13 @@ struct event: basic_event
         * Creates a new event.
         *
         * @param fd File descriptor to monitor for events.
-        * @param ev Type of events to monitor.
+        * @param ev Type of events to monitor (see eventxx::type).
         * @param handler Callback functor.
-        * @param priority Priority of the event.
         */
-       event(int fd, short ev, F& handler, int priority = DEFAULT_PRIORITY)
-               throw(invalid_priority)
+       event(int fd, short ev, F& handler) throw()
        {
-               event_set(this, fd, ev, &wrapper, reinterpret_cast< void* >(&handler));
-               if (priority != DEFAULT_PRIORITY
-                               && event_priority_set(this, priority))
-                       throw invalid_priority();
+               event_set(this, fd, ev, &wrapper,
+                               reinterpret_cast< void* >(&handler));
        }
 
        protected:
@@ -303,7 +324,9 @@ struct event: basic_event
                static void wrapper(int fd, short ev, void* h)
                {
                        F& handler = *reinterpret_cast< F* >(h);
-                       handler(fd, ev);
+                       // Hackish, but this way the handler can get a clean
+                       // event type
+                       handler(fd, *reinterpret_cast< type* >(&ev));
                }
 
 }; // struct event< F >
@@ -322,19 +345,13 @@ struct event< ccallback_type >: basic_event
         * Creates a new event.
         *
         * @param fd File descriptor to monitor for events.
-        * @param ev Type of events to monitor.
+        * @param ev Type of events to monitor (see eventxx::type).
         * @param handler C-style callback function.
         * @param arg Arbitrary pointer to pass to the handler as argument.
-        * @param priority Priority of the event.
         */
-       event(int fd, short ev, ccallback_type handler, void* arg,
-                       int priority = DEFAULT_PRIORITY)
-               throw(invalid_priority)
+       event(int fd, short ev, ccallback_type handler, void* arg) throw()
        {
                event_set(this, fd, ev, handler, arg);
-               if (priority != DEFAULT_PRIORITY
-                               && event_priority_set(this, priority))
-                       throw invalid_priority();
        }
 
        protected:
@@ -347,9 +364,12 @@ struct event< ccallback_type >: basic_event
  * Timer event object.
  *
  * This is just a special case of event that is fired only when a timeout is
- * reached. It's just a shortcut to event(-1, 0, handler, priority).
+ * reached. It's just a shortcut to:
+ * @code
+ * event(-1, 0, handler);
+ * @endcode
  *
- * @note This event can't EV_PERSIST.
+ * @note This event can't eventxx::PERSIST.
  * @see timer< ccallback_type >
  */
 template < typename F >
@@ -360,16 +380,11 @@ struct timer: event< F >
         * Creates a new timer event.
         *
         * @param handler Callback functor.
-        * @param priority Priority of the event.
         */
-       timer(F& handler, int priority = DEFAULT_PRIORITY)
-               throw(invalid_priority)
+       timer(F& handler) throw()
        {
                evtimer_set(this, &event< F >::wrapper,
                        reinterpret_cast< void* >(&handler));
-               if (priority != DEFAULT_PRIORITY
-                               && event_priority_set(this, priority))
-                       throw invalid_priority();
        }
 
 }; // struct timer< F >
@@ -378,7 +393,7 @@ struct timer: event< F >
 /**
  * This is the specialization of eventxx::timer for C-style callbacks.
  *
- * @note This event can't EV_PERSIST.
+ * @note This event can't eventxx::PERSIST.
  * @see timer
  */
 template <>
@@ -387,18 +402,13 @@ struct timer< ccallback_type >: event< ccallback_type >
 
        /**
         * Creates a new timer event.
-        * 
+        *
         * @param handler C-style callback function.
         * @param arg Arbitrary pointer to pass to the handler as argument.
-        * @param priority Priority of the event.
         */
-       timer(ccallback_type handler, void* arg, int priority = DEFAULT_PRIORITY)
-               throw(invalid_priority)
+       timer(ccallback_type handler, void* arg) throw()
        {
                evtimer_set(this, handler, arg);
-               if (priority != DEFAULT_PRIORITY
-                               && event_priority_set(this, priority))
-                       throw invalid_priority();
        }
 
 }; // struct timer< ccallback_type >
@@ -408,10 +418,12 @@ struct timer< ccallback_type >: event< ccallback_type >
  * Signal event object.
  *
  * This is just a special case of event that is fired when a signal is raised
- * (instead of a file descriptor being active). It's just a shortcut to
- * event(signal, EV_SIGNAL, handler, priority).
+ * (instead of a file descriptor being active). It's just a shortcut to:
+ * @code
+ * event(signum, eventxx::SIGNAL, handler);
+ * @endcode
  *
- * @note This event allways EV_PERSIST.
+ * @note This event always eventxx::PERSIST.
  * @see signal< ccallback_type >
  */
 template < typename F >
@@ -423,16 +435,11 @@ struct signal: event< F >
         *
         * @param signum Signal number to monitor.
         * @param handler Callback functor.
-        * @param priority Priority of the event.
         */
-       signal(int signum, F& handler, int priority = DEFAULT_PRIORITY)
-               throw(invalid_priority)
+       signal(int signum, F& handler) throw()
        {
                signal_set(this, signum, &event< F >::wrapper,
                        reinterpret_cast< void* >(&handler));
-               if (priority != DEFAULT_PRIORITY
-                               && event_priority_set(this, priority))
-                       throw invalid_priority();
        }
 
        /**
@@ -451,7 +458,7 @@ struct signal: event< F >
 /**
  * This is the specialization of eventxx::signal for C-style callbacks.
  *
- * @note This event allways EV_PERSIST.
+ * @note This event always eventxx::PERSIST.
  * @see signal
  */
 template <>
@@ -464,21 +471,15 @@ struct signal< ccallback_type >: event< ccallback_type >
         * @param signum Signal number to monitor.
         * @param handler C-style callback function.
         * @param arg Arbitrary pointer to pass to the handler as argument.
-        * @param priority Priority of the event.
         */
-       signal(int signum, ccallback_type handler, void* arg,
-                       int priority = DEFAULT_PRIORITY)
-               throw(invalid_priority)
+       signal(int signum, ccallback_type handler, void* arg) throw()
        {
                signal_set(this, signum, handler, arg);
-               if (priority != DEFAULT_PRIORITY
-                               && event_priority_set(this, priority))
-                       throw invalid_priority();
        }
 
        /**
         * Event's signal number.
-        * 
+        *
         * @return Event's signal number.
         */
        int signum() const
@@ -511,10 +512,10 @@ struct dispatcher
 {
 
        /**
-        * Creates a default dispatcher (with just 1 prioriority).
+        * Creates a default dispatcher (with just 1 priority).
         *
         * @see dispatcher(int) if you want to create a dispatcher with more
-        *      prioriorities.
+        *      priorities.
         */
        dispatcher() throw()
        {
@@ -522,8 +523,8 @@ struct dispatcher
        }
 
        /**
-        * Creates a dispatcher with npriorities prioriorities.
-        * 
+        * Creates a dispatcher with npriorities priorities.
+        *
         * @param npriorities Number of priority queues to use.
         */
        dispatcher(int npriorities) throw(std::bad_alloc)
@@ -542,25 +543,36 @@ struct dispatcher
         * Adds an event to the dispatcher.
         *
         * @param e Event to add.
+        * @param priority Priority of the event.
         */
-       void add(basic_event& e) throw()
+       void add(basic_event& e, int priority = DEFAULT_PRIORITY)
+               throw(invalid_priority)
        {
                internal::event_base_set(_event_base, &e);
+               if (priority != DEFAULT_PRIORITY
+                               && internal::event_priority_set(&e, priority))
+                       throw invalid_priority();
                internal::event_add(&e, 0);
        }
 
        /**
         * Adds an event to the dispatcher with a timeout.
         *
-        * The event is fired when there is activity on e or when to is elapsed,
+        * The event is fired when there is activity on e or when to has elapsed,
         * whatever come first.
         *
         * @param e Event to add.
         * @param to Timeout.
+        * @param priority Priority of the event.
         */
-       void add(basic_event& e, const time& to) throw()
+       void add(basic_event& e, const time& to,
+                       int priority = DEFAULT_PRIORITY)
+               throw(invalid_priority)
        {
                internal::event_base_set(_event_base, &e);
+               if (priority != DEFAULT_PRIORITY
+                               && internal::event_priority_set(&e, priority))
+                       throw invalid_priority();
                internal::event_add(&e, const_cast< time* >(&to)); // XXX HACK libevent don't use const
        }
 
@@ -568,14 +580,14 @@ struct dispatcher
         * Adds a temporary event.
         *
         * Adds a temporary event, without the need of instantiating a new event
-        * object. Events added this way can't EV_PERSIST.
+        * object. Events added this way can't eventxx::PERSIST.
         *
         * @param fd File descriptor to monitor for events.
         * @param ev Type of events to monitor.
         * @param handler Callback function.
         */
        template < typename F >
-       void add_once(int fd, short ev, F& handler)
+       void add_once(int fd, type ev, F& handler)
        {
                internal::event_once(fd, ev, &dispatcher::wrapper< F >,
                                reinterpret_cast< void* >(&handler), 0);
@@ -585,14 +597,14 @@ struct dispatcher
         * Adds a temporary event to with a C-style callback.
         *
         * Adds a temporary event, without the need of instantiating a new event
-        * object. Events added this way can't EV_PERSIST.
+        * object. Events added this way can't eventxx::PERSIST.
         *
         * @param fd File descriptor to monitor for events.
         * @param ev Type of events to monitor.
         * @param handler Callback function.
         * @param arg Arbitrary pointer to pass to the handler as argument.
         */
-       void add_once(int fd, short ev, ccallback_type handler, void* arg)
+       void add_once(int fd, type ev, ccallback_type handler, void* arg)
        {
                internal::event_once(fd, ev, handler, arg, 0);
        }
@@ -601,7 +613,7 @@ struct dispatcher
         * Adds a temporary event.
         *
         * Adds a temporary event, without the need of instantiating a new event
-        * object. Events added this way can't EV_PERSIST.
+        * object. Events added this way can't eventxx::PERSIST.
         *
         * @param fd File descriptor to monitor for events.
         * @param ev Type of events to monitor.
@@ -609,7 +621,7 @@ struct dispatcher
         * @param to Timeout.
         */
        template < typename F >
-       void add_once(int fd, short ev, F& handler, const time& to)
+       void add_once(int fd, type ev, F& handler, const time& to)
        {
                internal::event_once(fd, ev, &dispatcher::wrapper< F >,
                                reinterpret_cast< void* >(&handler),
@@ -620,7 +632,7 @@ struct dispatcher
         * Adds a temporary event with a C-style callback.
         *
         * Adds a temporary event, without the need of instantiating a new event
-        * object. Events added this way can't EV_PERSIST.
+        * object. Events added this way can't eventxx::PERSIST.
         *
         * @param fd File descriptor to monitor for events.
         * @param ev Type of events to monitor.
@@ -628,7 +640,7 @@ struct dispatcher
         * @param arg Arbitrary pointer to pass to the handler as argument.
         * @param to Timeout.
         */
-       void add_once(int fd, short ev, ccallback_type handler, void* arg, const time& to)
+       void add_once(int fd, type ev, ccallback_type handler, void* arg, const time& to)
        {
                internal::event_once(fd, ev, handler, arg, const_cast< time* >(&to)); // XXX HACK libevent don't use const
        }
@@ -680,18 +692,18 @@ struct dispatcher
        /**
         * Main dispatcher loop.
         *
-        * This function takes the control of the program, waiting for event and
-        * calling it's callbacks when they are fired. It only returns under
+        * This function takes the control of the program, waiting for an event
+        * and calling its callbacks when it's fired. It only returns under
         * this conditions:
         * - exit() was called.
         * - All events were del()eted.
         * - Another internal error.
-        * - LOOP_ONCE flag was set.
-        * - LOOP_NONBLOCK flag was set.
+        * - eventxx::ONCE flag was set.
+        * - eventxx::NONBLOCK flag was set.
         *
-        * @param flags If EVLOOP_ONCE is specified, then just one event is
-        *              processed, if EVLOOP_NONBLOCK is specified, then this
-        *              function returns whenever as an event or not.
+        * @param flags If eventxx::ONCE is specified, then just one event is
+        *              processed, if eventxx::NONBLOCK is specified, then this
+        *              function returns even if there are no pending events.
         */
        int dispatch(int flags = 0) // TODO  throw(exception)
        {
@@ -701,20 +713,23 @@ struct dispatcher
        /**
         * Exit the dispatch() loop.
         *
-        * @param to If a timeout is given, the loop exits after to is passed.
+        * @param to If a timeout is given, the loop exits after the specified
+        *           time is elapsed.
         */
        int exit(const time& to = time())
        {
-               return internal::event_base_loopexit(_event_base, const_cast< time* >(&to)); // XXX HACK libevent don't use const
+               // XXX HACK libevent don't use const
+               return internal::event_base_loopexit(_event_base,
+                       const_cast< time* >(&to));
        }
 
        protected:
                internal::event_base* _event_base;
                template < typename F >
-               static void wrapper(int fd, short ev, void* h)
+               static void wrapper(int fd, type ev, void* h)
                {
                        F& handler = *reinterpret_cast< F* >(h);
-                       handler(fd, ev);
+                       handler(fd, *reinterpret_cast< type* >(&ev));
                }
 
 }; // struct dispatcher