diff --git a/src/AsyncSocket.h b/src/AsyncSocket.h index 791ff32..bbbe533 100644 --- a/src/AsyncSocket.h +++ b/src/AsyncSocket.h @@ -68,25 +68,31 @@ protected: /* Cork this socket. Only one socket may ever be corked per-loop at any given time */ void cork() { - getLoopData()->corked = true; + /* What if another socket is corked? */ + getLoopData()->corkedSocket = this; } - // this is highly broken right now, should properly make use of secondary buffer if needed + /* Returns wheter we are corked or not */ + bool isCorked() { + return getLoopData()->corkedSocket == this; + } + + /* Returns a suitable buffer for temporary assemblation of send data */ std::pair getSendBuffer(size_t size) { - - // for now, just return this straight up - + /* If we are corked and we have room, return the cork buffer itself */ LoopData *loopData = getLoopData(); + if (loopData->corkedSocket == this && loopData->corkOffset + size < LoopData::CORK_BUFFER_SIZE) { + char *sendBuffer = loopData->corkBuffer + loopData->corkOffset; + loopData->corkOffset += size; + return {sendBuffer, false}; + } else { + // slow path for now - char *sendBuffer = loopData->corkBuffer + loopData->corkOffset; + return {(char *) malloc(size), true}; + // if we are out of buffer, fail this completely? - // very broken - loopData->corkOffset += size; - - - - return {sendBuffer, false}; + } } /* Write in three levels of prioritization: cork-buffer, syscall, socket-buffer. Always drain if possible. @@ -126,7 +132,7 @@ protected: } if (length) { - if (loopData->corked) { + if (loopData->corkedSocket == this) { /* We are corked */ if (LoopData::CORK_BUFFER_SIZE - loopData->corkOffset >= length) { /* If the entire chunk fits in cork buffer */ @@ -186,8 +192,8 @@ protected: std::pair uncork(const char *src = nullptr, int length = 0, bool optionally = false) { LoopData *loopData = getLoopData(); - if (loopData->corked) { - loopData->corked = false; + if (loopData->corkedSocket == this) { + loopData->corkedSocket = nullptr; if (loopData->corkOffset) { /* Corked data is already accounted for via its write call */ diff --git a/src/LoopData.h b/src/LoopData.h index 4ed035b..36ab301 100644 --- a/src/LoopData.h +++ b/src/LoopData.h @@ -44,7 +44,7 @@ public: /* Cork data */ char *corkBuffer = new char[CORK_BUFFER_SIZE]; int corkOffset = 0; - bool corked = false; + void *corkedSocket = nullptr; /* Compression data */ InflationStream *inflationStream = nullptr; diff --git a/src/WebSocket.h b/src/WebSocket.h index 13686b8..728ed03 100644 --- a/src/WebSocket.h +++ b/src/WebSocket.h @@ -39,7 +39,7 @@ private: } public: - // this function need clean-ups and perf. fixes + /* Send or buffer a WebSocket frame, compressed or not. Returns false on increased user space backpressure. */ bool send(std::string_view message, uWS::OpCode opCode = uWS::OpCode::BINARY, bool compress = false) { /* Transform the message to compressed domain if requested */ if (compress) { @@ -53,6 +53,10 @@ public: WebSocketProtocol>::formatMessage(sendBuffer, message.data(), message.length(), opCode, message.length(), false); if (requiresWrite) { auto[written, failed] = Super::write(sendBuffer, messageFrameSize); + + /* For now, we are slow here (fix!) */ + free(sendBuffer); + /* Return true for success */ return !failed; } diff --git a/src/WebSocketContext.h b/src/WebSocketContext.h index 72a876f..992d934 100644 --- a/src/WebSocketContext.h +++ b/src/WebSocketContext.h @@ -270,7 +270,7 @@ private: /* Handle WebSocket data streams */ static_dispatch(us_ssl_socket_context_on_data, us_socket_context_on_data)(getSocketContext(), [](auto *s, char *data, int length) { - std::cout << "websocket data" << std::endl; + //std::cout << "websocket data" << std::endl; /* We always cork on data */ AsyncSocket *webSocket = (AsyncSocket *) s;