From f8dbc120c055fb61fa79f901cc2974d049d04f4f Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Tue, 16 Jul 2013 11:14:34 -0700 Subject: Split the Socket class into Selectable, in order to let it work with other non-socket file descriptors. --- includes/Printer.h | 2 ++ includes/Selectable.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ includes/Socket.h | 24 +++++------------------- 3 files changed, 56 insertions(+), 19 deletions(-) create mode 100644 includes/Selectable.h (limited to 'includes') diff --git a/includes/Printer.h b/includes/Printer.h index cc9be2c..8494e49 100644 --- a/includes/Printer.h +++ b/includes/Printer.h @@ -27,6 +27,7 @@ enum { #undef E_INPUT #undef E_SOCKET #undef E_THREAD +#undef E_SELECT enum { E_STRING = 1, @@ -39,6 +40,7 @@ enum { E_OUTPUT = 128, E_HTTPSERVER = 256, E_ASYNC = 512, + E_SELECT = 1024, }; class Printer { diff --git a/includes/Selectable.h b/includes/Selectable.h new file mode 100644 index 0000000..0cfae0c --- /dev/null +++ b/includes/Selectable.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace Balau { + +class Selectable : public Handle { + public: + ~Selectable(); + virtual ssize_t read(void * buf, size_t count) throw (GeneralException); + virtual ssize_t write(const void * buf, size_t count) throw (GeneralException); + virtual bool isClosed(); + virtual bool isEOF(); + + bool gotR() { return m_evtR->gotSignal(); } + bool gotW() { return m_evtW->gotSignal(); } + + class SelectableEvent : public Events::BaseEvent { + public: + SelectableEvent(int fd, int evt = ev::READ | ev::WRITE) : m_task(NULL) { Printer::elog(E_SELECT, "Got a new SelectableEvent at %p", this); m_evt.set(this); m_evt.set(fd, evt); } + virtual ~SelectableEvent() { Printer::elog(E_SELECT, "Destroying a SelectableEvent at %p", this); m_evt.stop(); } + void stop() { Printer::elog(E_SELECT, "Stopping a SelectableEvent at %p", this); reset(); m_evt.stop(); } + private: + void evt_cb(ev::io & w, int revents) { Printer::elog(E_SELECT, "Got a libev callback on a SelectableEvent at %p", this); doSignal(); } + virtual void gotOwner(Task * task); + + ev::io m_evt; + Task * m_task = NULL; + }; + + protected: + Selectable() { } + void setFD(int fd) throw (GeneralException); + void internalClose() { m_fd = -1; } + int getFD() { return m_fd; } + virtual ssize_t recv(int sockfd, void *buf, size_t len, int flags) = 0; + virtual ssize_t send(int sockfd, const void *buf, size_t len, int flags) = 0; + + SelectableEvent * m_evtR = NULL, * m_evtW = NULL; + + private: + int m_fd = -1; +}; + +}; diff --git a/includes/Socket.h b/includes/Socket.h index 00dc2b4..cfa8218 100644 --- a/includes/Socket.h +++ b/includes/Socket.h @@ -8,6 +8,7 @@ #include #endif #include +#include #include #include #include @@ -17,47 +18,32 @@ namespace Balau { struct DNSRequest; -class Socket : public Handle { +class Socket : public Selectable { public: Socket() throw (GeneralException); - virtual void close() throw (GeneralException); virtual ssize_t read(void * buf, size_t count) throw (GeneralException); virtual ssize_t write(const void * buf, size_t count) throw (GeneralException); - virtual bool isClosed(); - virtual bool isEOF(); + virtual void close() throw (GeneralException); virtual bool canRead(); virtual bool canWrite(); virtual const char * getName(); bool setLocal(const char * hostname = NULL, int port = 0); bool connect(const char * hostname, int port); - bool gotR() { return m_evtR->gotSignal(); } - bool gotW() { return m_evtW->gotSignal(); } IO accept() throw (GeneralException); bool listen(); bool resolved(); private: Socket(int fd); - class SocketEvent : public Events::BaseEvent { - public: - SocketEvent(int fd, int evt = ev::READ | ev::WRITE) : m_task(NULL) { Printer::elog(E_SOCKET, "Got a new SocketEvent at %p", this); m_evt.set(this); m_evt.set(fd, evt); } - virtual ~SocketEvent() { Printer::elog(E_SOCKET, "Destroying a SocketEvent at %p", this); m_evt.stop(); } - void stop() { Printer::elog(E_SOCKET, "Stopping a SocketEvent at %p", this); reset(); m_evt.stop(); } - private: - void evt_cb(ev::io & w, int revents) { Printer::elog(E_SOCKET, "Got a libev callback on a SocketEvent at %p", this); doSignal(); } - virtual void gotOwner(Task * task); - ev::io m_evt; - Task * m_task = NULL; - }; + virtual ssize_t recv(int sockfd, void *buf, size_t len, int flags); + virtual ssize_t send(int sockfd, const void *buf, size_t len, int flags); - int m_fd; String m_name; bool m_connected = false; bool m_connecting = false; bool m_listening = false; sockaddr_in6 m_localAddr, m_remoteAddr; - SocketEvent * m_evtR, * m_evtW; DNSRequest * m_req = NULL; }; -- cgit v1.2.3