removed some useless spaces; not very important, I know :)
[senf.git] / Scheduler / Scheduler.hh
index 7a958e3..0f16fce 100644 (file)
@@ -1,9 +1,9 @@
 // $Id$
 //
 // Copyright (C) 2006
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
-//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
@@ -37,7 +37,7 @@
 #include <boost/call_traits.hpp>
 #include <boost/integer.hpp>
 #include "ClockService.hh"
-#include "../Utils/Logger/Target.hh"
+#include "../Utils/Logger/SenfLog.hh"
 
 //#include "scheduler.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -61,39 +61,57 @@ namespace senf {
         are defined on top of this functionality (e.g. ReadHelper or WriteHelper or the interval
         timers of the PPI).
 
-        \section sched_handlers Handlers
 
-        All handlers are managed as generic <a
+        \section sched_handlers Specifying handlers
+
+        All handlers are passed as generic <a
         href="http://www.boost.org/doc/html/function.html">Boost.Function</a> objects. This allows
         to pass any callable as a handler. Depending on the type of handler, some additional
-        arguments may be passed to the handler by the scheduler. If you want to pass additional
-        arguments to the handler, use <a
-        href="http://www.boost.org/libs/bind/bind.html">Boost.Bind</a>)).
+        arguments may be passed to the handler by the scheduler. 
+
+        If you need to pass additional information to your handler, use <a
+        href="http://www.boost.org/libs/bind/bind.html">Boost.Bind</a>:
+        \code
+        // Pass 'handle' as additional first argument to callback()
+        Scheduler::instance().add(handle, boost::bind(&callback, handle, _1))
+        // Call timeout() handler with argument 'n'
+        Scheduler::instance().timeout(boost::bind(&timeout, n))
+        \endcode
+
+        To use member-functions as callbacks, use either <a
+        href="http://www.boost.org/libs/bind/bind.html">Boost.Bind</a> or senf::membind()
+        \code
+        // e.g. in Foo::Foo() constructor:
+        Scheduler::instance().add(handle_, senf::membind(&Foo::callback, this))
+        \endcode
         
 
-        \section sched_fd File descriptors
+        \section sched_fd Registering file descriptors
         
         File descriptors are managed using add() or remove()
         \code
         Scheduler::instance().add(handle, &callback);
         Scheduler::instance().remove(handle);
-        \endcode
+        \endcode 
+
         The callback will be called with one additional argument. This argument is the event mask of
-        type EventId. This mask will tell, which of the registered events are
-        signaled. Additionally, EV_HUP or EV_ERR on hangup or error condition on the handle.
+        type EventId. This mask will tell, which of the registered events are signaled. The
+        additional flags EV_HUP or EV_ERR (on hangup or error condition) may be set additionally.
 
-        There is always only one handler registered for a file descriptor (registering multiple
-        callbacks for a single fd does not make sense).
+        Only a single handler may be registered for any combination of file descriptor and event
+        (registering multiple callbacks for a single fd and event does not make sense).
 
-        The scheduler will accept an almost arbitrary object as it's first argument. It will use
+        The scheduler will accept any object as \a handle argument as long as retrieve_filehandle()
+        may be called on that object
         \code
         int fd = retrieve_filehandle(handle);
-        \endcode
-        To fetch the file handle given some abstract handle type. The definition of
-        retrieve_filehandle() will be found using ADL.
+        \endcode 
+        to fetch the file handle given some abstract handle type. retrieve_filehandle() will be
+        found using ADL depending on the argument namespace. A default implementation is provided
+        for \c int arguments (file descriptors)
 
 
-        \section sched_timers Timers
+        \section sched_timers Registering timers
 
         The Scheduler has very simple timer support. There is only one type of timer: A single-shot
         deadline timer. More complex timers are built based on this. Timers are managed using
@@ -120,7 +138,7 @@ namespace senf {
         timeoutEarly. By default, this value is set to 0 but may be changed if needed.
 
 
-        \section sched_signals POSIX/UNIX signals
+        \section sched_signals Registering POSIX/UNIX signals
 
         The Scheduler also incorporates standard POSIX/UNIX signals. Signals registered with the
         scheduler will be handled \e synchronously within the event loop.
@@ -135,11 +153,17 @@ namespace senf {
         wait for signals \e only.
 
         \todo Fix EventId parameter (probably to int) to allow |-ing without casting ...
+        
+        \todo Fix the file support to use threads (?) fork (?) and a pipe so it works reliably even
+            over e.g. NFS.
       */
     class Scheduler
         : boost::noncopyable
     {
     public:
+
+        SENF_LOG_CLASS_AREA();
+
         ///////////////////////////////////////////////////////////////////////////
         // Types
 
@@ -155,13 +179,14 @@ namespace senf {
             sole member is a typedef symbol defining the callback type given the handle type.
 
             The Callback is any callable object taking a \c Handle and an \c EventId as argument.
-        template <class Handle>
-        struct GenericCallback {
-            typedef boost::function<void (typename boost::call_traits<Handle>::param_type,
-                                          EventId) > Callback;
-        };
+            \code
+            template <class Handle>
+            struct GenericCallback {
+                typedef boost::function<void (typename boost::call_traits<Handle>::param_type,
+                                              EventId) > Callback;
+            };
+            \endcode
          */
-
         typedef boost::function<void (EventId)> FdCallback;
 
         /** \brief Callback type for timer events */
@@ -257,6 +282,7 @@ namespace senf {
         void unregisterSignal(unsigned signal);
                                         ///< Remove signal handler for \a signal
 
+        /// The signal number passed to registerSignal or unregisterSignal is invalid
         struct InvalidSignalNumberException : public std::exception
         { virtual char const * what() const throw() 
                 { return "senf::Scheduler::InvalidSignalNumberException"; } };
@@ -299,7 +325,11 @@ namespace senf {
             FdCallback cb_prio;
             FdCallback cb_write;
 
+            EventSpec() : file(false) {}
+
             int epollMask() const;
+
+            bool file;
         };
 
         /** \brief Timer event specification
@@ -323,6 +353,7 @@ namespace senf {
 
         typedef std::map<int,EventSpec> FdTable;
         typedef std::map<unsigned,TimerSpec> TimerMap; // sorted by id
+        typedef std::vector<unsigned> FdEraseList;
 
 #       ifndef DOXYGEN
 
@@ -343,6 +374,8 @@ namespace senf {
         typedef std::vector<SimpleCallback> SigHandlers;
 
         FdTable fdTable_;
+        FdEraseList fdErase_;
+        unsigned files_;
 
         unsigned timerIdCounter_;
         TimerQueue timerQueue_;