diff --git a/15.pro b/15.pro index 08f9c13..159f599 100644 --- a/15.pro +++ b/15.pro @@ -26,7 +26,8 @@ HEADERS += \ src/new_design/HttpResponse.h \ src/new_design/StaticDispatch.h \ src/new_design/LoopData.h \ - src/new_design/AsyncSocket.h + src/new_design/AsyncSocket.h \ + src/new_design/AsyncSocketData.h INCLUDEPATH += uSockets/src src #QMAKE_CXXFLAGS += -fsanitize=address diff --git a/src/Loop.h b/src/Loop.h index c5caa00..fbcda60 100644 --- a/src/Loop.h +++ b/src/Loop.h @@ -1,6 +1,8 @@ #ifndef HUB_H #define HUB_H +// this header needs fixing! should not depend on source files! + #include "new_design/LoopData.h" #include diff --git a/src/new_design/AsyncSocket.h b/src/new_design/AsyncSocket.h index 5934ecd..9eb8dcc 100644 --- a/src/new_design/AsyncSocket.h +++ b/src/new_design/AsyncSocket.h @@ -3,6 +3,7 @@ #include "StaticDispatch.h" #include "LoopData.h" +#include "AsyncSocketData.h" // todo: this is where the magic happens @@ -10,18 +11,14 @@ namespace uWS { template struct AsyncSocket : StaticDispatch { +protected: + // this will probably be different on ssl and non-ssl + static const int MAX_COPY_DISTANCE = 4096; using SOCKET_TYPE = typename StaticDispatch::SOCKET_TYPE; using StaticDispatch::static_dispatch; - // control everything with write, cork, uncork, close - // have HttpResponseData derive from AsyncSocketData? - - // HttpResponse will only need one buffer for outgoing - the corked up - - // maybe better name would be CorkableSocket? - - // this does not belong here! + // this will have to belong here for now int u32toa(uint32_t value, char *dst) { char temp[10]; char *p = temp; @@ -39,15 +36,43 @@ struct AsyncSocket : StaticDispatch { return ret; } - void cork() { - LoopData *loopData = (LoopData *) us_loop_ext(us_socket_context_loop(us_socket_get_context((us_socket *) this))); - - loopData->corked = true; - + LoopData *getLoopData() { + return (LoopData *) us_loop_ext(us_socket_context_loop(us_socket_get_context((SOCKET_TYPE *) this))); } + void *getExt() { + return static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this); + } + +public: + + // cork should bascially mark corked + // if already corked, crash and burn! + void cork() { + LoopData *loopData = getLoopData(); + loopData->corked = true; + } + + // if not in corked mode, write & buffer. if in corked mode: either write & buffer or buffer + // that is, corking is optional + void write(const char *src, int length) { + LoopData *loopData = getLoopData(); + + // append it + memcpy(loopData->corkBuffer + loopData->corkOffset, src, length); + loopData->corkOffset += length; + } + + // should follow same rules as for write + void writeUnsigned(unsigned int value) { + LoopData *loopData = getLoopData(); + + loopData->corkOffset += u32toa(value, loopData->corkBuffer + loopData->corkOffset); + } + + // uncork should always send and clean the loop's cork buffer. anything that is not able to send, buffer it up in the socket void uncork() { - LoopData *loopData = (LoopData *) us_loop_ext(us_socket_context_loop(us_socket_get_context((us_socket *) this))); + LoopData *loopData = getLoopData(); loopData->corked = false; @@ -60,19 +85,12 @@ struct AsyncSocket : StaticDispatch { // buffer the rest up in the outbuffer of this asynsocket! } - void writeUnsigned(unsigned int value) { - LoopData *loopData = (LoopData *) us_loop_ext(us_socket_context_loop(us_socket_get_context((us_socket *) this))); + // when we are writable AND have buffer length, that's a really bad situation that should not happen! + void drain() { - loopData->corkOffset += u32toa(value, loopData->corkBuffer + loopData->corkOffset); - } - - void write(const char *src, int length) { - LoopData *loopData = (LoopData *) us_loop_ext(us_socket_context_loop(us_socket_get_context((us_socket *) this))); - - memcpy(loopData->corkBuffer + loopData->corkOffset, src, length); - loopData->corkOffset += length; } + // this one will write up to length and simply leave things be int writeOptionally(const char *src, int length) { // not optional for now @@ -111,10 +129,6 @@ struct AsyncSocket : StaticDispatch { } - void *getExt() { - return static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this); - } - void close() { static_dispatch(us_ssl_socket_close, us_socket_close)((SOCKET_TYPE *) this); } diff --git a/src/new_design/AsyncSocketData.h b/src/new_design/AsyncSocketData.h new file mode 100644 index 0000000..c51a2ce --- /dev/null +++ b/src/new_design/AsyncSocketData.h @@ -0,0 +1,17 @@ +#ifndef ASYNCSOCKETDATA_H +#define ASYNCSOCKETDATA_H + +#include + +// todo: think about chains of AsyncSocketData too! +// we want to buffer things up in one buffer, or in many separate ones (like with websockets) + +template +struct AsyncSocketData { + + // we need a buffer + std::string buffer; + +}; + +#endif // ASYNCSOCKETDATA_H diff --git a/src/new_design/HttpResponseData.h b/src/new_design/HttpResponseData.h index 5d3e2e0..6f9d992 100644 --- a/src/new_design/HttpResponseData.h +++ b/src/new_design/HttpResponseData.h @@ -4,12 +4,15 @@ /* This data belongs to the HttpResponse */ #include "HttpParser.h" +#include "AsyncSocketData.h" #include namespace uWS { template -struct HttpResponseData : HttpParser { +struct HttpResponseData : HttpParser, AsyncSocketData { + + // asyncsocketdata will hold the outgoing buffer to hold the header if not sent off in one go // inStream, outStream std::function inStream; diff --git a/src/new_design/LoopData.h b/src/new_design/LoopData.h index 8abc96d..b0349b9 100644 --- a/src/new_design/LoopData.h +++ b/src/new_design/LoopData.h @@ -8,7 +8,6 @@ private: public: static const int CORK_BUFFER_SIZE = 16 * 1024; - static const int MAX_COPY_DISTANCE = 4096; char *corkBuffer = new char[CORK_BUFFER_SIZE]; int corkOffset = 0;