summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
Diffstat (limited to 'includes')
-rw-r--r--includes/Printer.h2
-rw-r--r--includes/Selectable.h49
-rw-r--r--includes/Socket.h24
3 files changed, 56 insertions, 19 deletions
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 <Handle.h>
+#include <TaskMan.h>
+#include <Task.h>
+#include <StacklessTask.h>
+#include <Printer.h>
+
+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<SelectableEvent, &SelectableEvent::evt_cb>(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 <netdb.h>
#endif
#include <Handle.h>
+#include <Selectable.h>
#include <TaskMan.h>
#include <Task.h>
#include <StacklessTask.h>
@@ -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<Socket> 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<SocketEvent, &SocketEvent::evt_cb>(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;
};