dol: initial dol commit
[jump.git] / dol / src / dol / visitor / hdsd / scd / scd_sock_poller.h
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_sock_poller.h b/dol/src/dol/visitor/hdsd/scd/scd_sock_poller.h
new file mode 100644 (file)
index 0000000..b19cece
--- /dev/null
@@ -0,0 +1,144 @@
+#ifndef SCD_SOCK_POLLER_H
+#define SCD_SOCK_POLLER_H
+
+#include <vector>
+#include "poll.h"
+
+#include "scd_socket.h"
+
+
+typedef short sock_ev;
+const sock_ev SOCK_EV_READ = POLLIN;
+const sock_ev SOCK_EV_WRITE = POLLOUT;
+const sock_ev SOCK_EV_CLOSE = POLLERR | POLLHUP | POLLNVAL;
+
+
+/**
+ * Interface for classes able to handle socket events.
+ */
+class scd_sock_ev_handler_if
+{
+public:
+    /**
+     * Executes the handler for socket events that have been registered
+     * and have ocured. Callback carried out by scd_sock_poller.
+     *\param events the events that occured
+     */
+    virtual void handle_sock_ev(sock_ev events) = 0;
+
+    /**
+     * Returns the socket that should be watched. The socket must
+     * be the same as long the handler is registered.
+     */
+    virtual const scd_socket &get_sock() = 0;
+
+    virtual ~scd_sock_ev_handler_if() {};
+};
+
+
+/**
+ * Dispatcher that watches sockets and executes call backs if watched
+ * event occure. Socket events (sock_ev) are an OR combination of flags
+ * supported by ::poll. See "man 2 poll". The watched events for a specific
+ * event handler stay watched until the events are overwritten or the handler
+ * is removed.
+ */
+class scd_sock_poller
+{
+public:
+    /**
+     * Register a socket event handler (a class handling socket events).
+     * Optionally the events to watch can be specified.
+     * \param handler the object that wants to watch a socket
+     * \param events (optional) the events to watch
+     * \return true if the handler could be registered succesfully
+     */
+    bool register_handler(scd_sock_ev_handler_if &handler, sock_ev events = 0);
+
+    /**
+     * Remove a socket event handler. The socket is not watched anymore.
+     * \param the object that has previously been registered
+     * \return false if no such handler was registered
+     */
+    bool remove_handler(const scd_sock_ev_handler_if &handler);
+
+    /**
+     * Set events to watch. The events expire only when overwritten
+     * by calling this function again or by removing the handler.
+     * \param handler the handler that has been registered before
+     * \param events the events the handler is interested in
+     * \return false if the handler has not been registered before
+     */
+    bool set_ev(const scd_sock_ev_handler_if &handler, sock_ev events);
+
+    /**
+     * Gets the events that are currently watched for the handler.
+     * \param the handler to get the watched events for
+     * \param events the variable where the watched events are written to
+     * \return false if the handler has not been registered before
+     */
+    bool get_ev(const scd_sock_ev_handler_if &handler, sock_ev &events) const;
+
+    /**
+     * Wait (blocking) for registered events or a timeout to occure.
+     * No callbacks are executed.
+     * \param milis timeout in milliseconds to wait for events, if omitted
+     * or -1 it is waited until events occure
+     * \return true if events occured, false otherwise
+     * \exception scd_exception if unexpected errors occured
+     */
+    bool wait(int ms = -1);
+
+    /**
+     * Check if events occured and callback the affected handlers.
+     * \return true if some events occured
+     * \exception scd_exception if unexcpected errors occured
+     */
+    bool process();
+
+    /**
+     * Wait (blocking) for registered events to occure and callback the
+     * affected handlers.
+     * \exception scd_exception if unexcpected errors occured
+     */
+    void wait_process();
+
+private:
+    /* member variables */
+    std::vector<scd_sock_ev_handler_if *> _handlers;
+    std::vector<struct pollfd> _events;
+
+    /* member functions */
+
+    /**
+     * Checks if a handler is already registered.
+     * \param handler the handler to check for existence
+     * \return true if the handler has been registered before
+     */
+    bool _handler_exists(const scd_sock_ev_handler_if& handler) const;
+
+    /**
+     * Returns the index of an event handler in the vector. This is the same
+     * index as the corresponding pollfd.
+     * \param handler the handler to get the index of
+     * \return the index of the handler or -1 if it could not be found
+     */
+    int _get_index(const scd_sock_ev_handler_if& handler) const;
+
+    /**
+     * Polls during a specified amount of time.
+     * \param ms miliseconds to block (-1 for infinite)
+     * \exception scd_exception if an unexpected error occured
+     * \return number of sockets for witch events occured
+     */
+    int _poll(int ms);
+
+    /**
+     * Calls handlers back for which events occured.
+     */
+    void _callback();
+}; 
+
+//scd_sock_poller* scd_get_sock_poller();
+
+#endif