/** \file
\brief FdDispatcher public header */
-#ifndef HH_FdDispatcher_
-#define HH_FdDispatcher_ 1
+#ifndef HH_SENF_Scheduler_FdEvent_
+#define HH_SENF_Scheduler_FdEvent_ 1
// Custom includes
#include "../boost/intrusive/iset_hook.hpp"
namespace scheduler {
namespace detail {
- struct FdSetTag;
- typedef boost::intrusive::iset_base_hook<FdSetTag> FdSetBase;
+ struct FdSetTag;
+ typedef boost::intrusive::iset_base_hook<FdSetTag> FdSetBase;
struct FdSetCompare;
struct FindFd;
class FdDispatcher;
The FdEvent class registers a file descriptor for read or write events.
- The type of event is specified using an event mask. Possible events are
+ There are a number of different event types supported for file descriptors. Those are
+ specified using a bit mask. Possible events are
\li \c EV_READ: File descriptor is readable (or at EOF)
\li \c EV_PRIO: There is out-of-band data available to be read on the file descriptor
\li \c EV_WRITE: File descriptor is writable
- These event flags can be or-ed together to form an event mask. The callback will be called
- with those flags set which are currently signaled. There are additional flags which may be
- set when calling the callback:
-
+ The callback will be called with one additional argument. This argument is the event mask of
+ type int. This mask will tell, which of the registered events are signaled. There are some
+ additional flags which can be set when calling the handler callback:
+
\li \c EV_HUP: The other end has closed the connection
\li \c EV_ERR: Transport error
+ Only a single handler may be registered for any combination of file descriptor and event
+ otherwise a DuplicateEventRegistrationException is thrown.
+
The file descriptor is specified using an arbitrary handle type which supports the \c
retrieve_filehandle() protocol: There must be a global function \c retrieve_filehandle
callable with the handle type. This function must return the file descriptor associated with
handles are provided.
The FdEvent class is an implementation of the RAII idiom: The event will be automatically
- unregistered in the FdEvent destructor. The TimerEvent instance should be created
- within the same scope or on a scope below where the callback is defined (e.g. if the
- callback is a member function it should be defined as a class member).
+ unregistered in the FdEvent destructor. The FdEvent instance should be created within the
+ same scope or on a scope below where the callback is defined (e.g. if the callback is a
+ member function it should be defined as a class member).
*/
class FdEvent
- : public FIFORunner::TaskInfo,
- public detail::FdSetBase,
- public FdManager::Event
+ : public detail::FIFORunner::TaskInfo,
+ public detail::FdSetBase,
+ public detail::FdManager::Event
{
public:
///////////////////////////////////////////////////////////////////////////
// Types
- typedef boost::function<void (int)> Callback;
+ typedef boost::function<void (int)> Callback;
enum Events {
- EV_READ = FdManager::EV_READ, EV_PRIO = FdManager::EV_PRIO, EV_WRITE = FdManager::EV_WRITE,
- EV_HUP = FdManager::EV_HUP, EV_ERR = FdManager::EV_ERR,
- EV_ALL = FdManager::EV_READ | FdManager::EV_WRITE | FdManager::EV_PRIO
+ EV_NONE = 0 ///< No event
+ , EV_READ = detail::FdManager::EV_READ ///< fd readable (or EOF)
+ , EV_PRIO = detail::FdManager::EV_PRIO ///< OOB data available for read
+ , EV_WRITE = detail::FdManager::EV_WRITE ///< fd writable
+ , EV_HUP = detail::FdManager::EV_HUP ///< remote end closed connection
+ , EV_ERR = detail::FdManager::EV_ERR ///< transport error
+ , EV_ALL = (detail::FdManager::EV_READ
+ | detail::FdManager::EV_WRITE
+ | detail::FdManager::EV_PRIO) ///< register all events (read, prio and write)
};
///////////////////////////////////////////////////////////////////////////
///@{
template <class Handle>
- FdEvent(std::string const & name, Callback const & cb, Handle const & handle, int events,
- bool initiallyEnabled = true);
+ FdEvent(std::string const & name, Callback const & cb, Handle const & handle, int events,
+ bool initiallyEnabled = true);
///< Register a file descriptor event
/**< Registers \a cb to be called when any of the \a events
occurs on \a handle. If \a initiallyEnabled is set \c
\param[in] cb Callback to call. This callback may \e
explicitly be set to \c 0 if the value cannot be
initialized. */
- ~FdEvent();
+ ~FdEvent();
///@}
///////////////////////////////////////////////////////////////////////////
- void disable(); ///< Disable event
- void enable(); ///< Enable event
- bool enabled(); ///< \c true if event enabled, \c false otherwise
+ void disable(); ///< Disable event
+ void enable(); ///< Enable event
- FdEvent & action(Callback const & cb); ///< Change event callback
+ FdEvent & action(Callback const & cb); ///< Change event callback
- FdEvent & events(int events); ///< Change event mask
+ FdEvent & events(int events); ///< Change event mask
FdEvent & addEvents(int events); ///< Add additional events to event mask
FdEvent & removeEvents(int events); ///< Remove events from event mask
int events(); ///< Current event mask
protected:
private:
- virtual void signal(int events);
- virtual void run();
+ virtual void signal(int events);
+ virtual void v_run();
+ virtual char const * v_type() const;
+ virtual std::string v_info() const;
- Callback cb_;
- int fd_;
+ Callback cb_;
+ int fd_;
bool pollable_;
- int events_;
- int signaledEvents_;
+ int events_;
+ int signaledEvents_;
friend class detail::FdSetCompare;
friend class detail::FindFd;
friend class detail::FileDispatcher;
};
- int retrieve_filehandle(int fd);
+ /** \brief Get file descriptor from handle object
+ This function will query the \a handle for it's file descriptor. The real implementation
+ must be provided by a freestanding function \c retrieve_filehandle(Handle const & h) within
+ the namespace of \a Handle.
+ */
+ template <class Handle>
+ int get_descriptor(Handle const & handle);
}}
///////////////////////////////hh.e////////////////////////////////////////