wsd/LOOLWebSocket.hpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
New commits: commit 9120fbabad552c22618509cfdc2cf73395e001b7 Author: Ashod Nakashian <[email protected]> Date: Sun Feb 12 23:47:43 2017 -0500 wsd: use separate read/write locks in LOOLWebSocket When two sockets send data to each other in blocking mode, they can both wait until the other end-point's buffers are free enough to receive the data being sent. Since in LOOLWebSocket we lock both send and receive with the same lock, this prevents the reader thread from freeing the buffer while we try to send data. But since our peer is in the same dilemma, neither of us will make progress--deadlock. Since sockets are full-duplex, they are capable of handling two way communication concurrently. Poco seems to not share data between them either, so this seems safe. Change-Id: I1fd68cd4fb3b4250b93c8f94cd42e49ee78f6650 Reviewed-on: https://gerrit.libreoffice.org/34194 Reviewed-by: Ashod Nakashian <[email protected]> Tested-by: Ashod Nakashian <[email protected]> diff --git a/wsd/LOOLWebSocket.hpp b/wsd/LOOLWebSocket.hpp index b1acd35..1408622 100644 --- a/wsd/LOOLWebSocket.hpp +++ b/wsd/LOOLWebSocket.hpp @@ -31,7 +31,8 @@ class LOOLWebSocket : public Poco::Net::WebSocket { private: - std::mutex _mutex; + std::mutex _mutexRead; + std::mutex _mutexWrite; #if ENABLE_DEBUG static std::chrono::milliseconds getWebSocketDelay() @@ -110,11 +111,12 @@ public: // Timeout is in microseconds. We don't need this, except to yield the cpu. static const Poco::Timespan waitTime(POLL_TIMEOUT_MS * 1000 / 10); static const Poco::Timespan waitZero(0); - std::unique_lock<std::mutex> lock(_mutex); while (poll(waitTime, Poco::Net::Socket::SELECT_READ)) { + std::unique_lock<std::mutex> lockRead(_mutexRead); const int n = Poco::Net::WebSocket::receiveFrame(buffer, length, flags); + lockRead.unlock(); if (n <= 0) LOG_TRC("Got nothing (" << n << ")"); @@ -130,6 +132,7 @@ public: if ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_PING) { // Echo back the ping message. + std::unique_lock<std::mutex> lock(_mutexWrite); if (Poco::Net::WebSocket::sendFrame(buffer, n, static_cast<int>(WebSocket::FRAME_FLAG_FIN) | WebSocket::FRAME_OP_PONG) != n) { LOG_WRN("Sending Pong failed."); @@ -158,7 +161,7 @@ public: std::this_thread::sleep_for(getWebSocketDelay()); #endif static const Poco::Timespan waitZero(0); - std::unique_lock<std::mutex> lock(_mutex); + std::unique_lock<std::mutex> lock(_mutexWrite); if (length >= LARGE_MESSAGE_SIZE) { @@ -204,7 +207,8 @@ public: /// or, otherwise, close the socket without sending close frame, if it is. void shutdown(Poco::UInt16 statusCode, const std::string& statusMessage = "") { - std::unique_lock<std::mutex> lock(_mutex); + std::unique_lock<std::mutex> lockRead(_mutexRead); + std::unique_lock<std::mutex> lockWrite(_mutexWrite); try { // Calling shutdown, in case of error, would try to send a 'close' frame _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
