src/Network/Reactor.hh
author Tero Marttila <terom@fixme.fi>
Fri, 16 Jan 2009 22:03:49 +0200
changeset 400 d64bf28c4340
parent 386 2f019ecb4aa9
permissions -rw-r--r--
more documentation tweaking, all Network/ files now have a @file comment. Fix Platform.h -> Platform.hh, and Buffer.hh + Packet.cc
#ifndef NETWORK_REACTOR_HH
#define NETWORK_REACTOR_HH

/**
 * @file
 *
 * A select() based reactor for NetworkSocket's
 */

// forward-declare
class NetworkReactor;

/**
 * Event types to poll for
 */
enum NetworkPollBit {
    POLL_READ       = 0x01,
    POLL_WRITE      = 0x02,
};

/**
 * Poll event bitmask of NetworkPollBit's
 */
typedef int NetworkPollMask;

#include "Platform.hh"
#include "Socket.hh"
#include "Error.hh"

#include <list>

/**
 * A reactor maintains a list of NetworkSockets (which must register themselves to their reactor), and providers
 * readyness notification of non-blocking I/O operations.
 *
 * NetworkSockets must call add_socket(), whereup the NetworkReactor will use NetworkSocket::get_poll() to build the
 * set of sockets to notify. If activity is detected, I will call NetworkSocket::notify().
 *
 * The poll() method can then be used by the application main loop to do timed sleeps, waking up on socket activity and
 * driving the sockets.
 */
class NetworkReactor {
    protected:
        std::list<NetworkSocket*> sockets;

    public:
        /**
         * Construct the empty reactor
         */
        NetworkReactor (void);

        /**
         * The global NetworkReactor, used by default for all NetworkSockets.
         */
        static NetworkReactor *current;

        /**
         * Add a NetworkSocket to our list of sockets. The desired notification states are fetched directly from the
         * socket itself using NetworkSocket::get_poll(), and it will be notified using NetworkSocket::notify().
         *
         * @param socket the socket to watch
         */
        void add_socket (NetworkSocket *socket) { sockets.push_back(socket); }

        /**
         * Remove a NetworkSocket from our list of sockets.
         *
         * @param socket the socket to stop watching
         */
        void remove_socket (NetworkSocket *socket) { sockets.remove(socket); }

        /**
         * Wait for activity on any of the sockets registered and with notification enabled, driving them using 
         * NetworkSocket::notify() if select() indicates activity. This method will sleep at most \a timeout, returning
         * once there was socket activity, or the timeout ran out.
         *
         * This is intended to be particularly efficient if the socket list is empty.
         */
        void poll (timeval *timeout = NULL);
};

/**
 * Reactor error
 */
class NetworkReactorError : public NetworkErrno {
    public:
        NetworkReactorError (std::string op) : NetworkErrno(op) { }
};

#endif