[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-2-0' - wsd/LOOLWebSocket.hpp
Ashod Nakashian
ashod.nakashian at collabora.co.uk
Mon Feb 13 15:03:51 UTC 2017
wsd/LOOLWebSocket.hpp | 34 +++++++++++++++++++++++++++-------
1 file changed, 27 insertions(+), 7 deletions(-)
New commits:
commit f7bbd9072db7a71ff28ba178d5ca9eebe6cf4397
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
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 <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
Reviewed-on: https://gerrit.libreoffice.org/34213
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
Tested-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/wsd/LOOLWebSocket.hpp b/wsd/LOOLWebSocket.hpp
index 86dc659..22e2891 100644
--- a/wsd/LOOLWebSocket.hpp
+++ b/wsd/LOOLWebSocket.hpp
@@ -31,10 +31,11 @@
class LOOLWebSocket : public Poco::Net::WebSocket
{
private:
- std::mutex _mutex;
+ std::mutex _mutexRead;
+ std::mutex _mutexWrite;
#if ENABLE_DEBUG
- std::chrono::milliseconds getWebSocketDelay()
+ static std::chrono::milliseconds getWebSocketDelay()
{
unsigned long baseDelay = 0;
unsigned long jitter = 0;
@@ -108,7 +109,10 @@ public:
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 << ")");
@@ -119,11 +123,17 @@ public:
}
if ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_PING)
{
- sendFrame(buffer, n, WebSocket::FRAME_FLAG_FIN | WebSocket::FRAME_OP_PONG);
+ // 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.");
+ return -1;
+ }
}
else if ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_PONG)
{
- // In case we do send pongs in the future.
+ // In case we do send pings in the future.
}
else
{
@@ -131,6 +141,7 @@ public:
}
}
+ // Not ready for read.
return -1;
}
@@ -141,13 +152,22 @@ public:
// Delay sending the frame
std::this_thread::sleep_for(getWebSocketDelay());
#endif
- std::unique_lock<std::mutex> lock(_mutex);
+ std::unique_lock<std::mutex> lock(_mutexWrite);
if (length >= LARGE_MESSAGE_SIZE)
{
const std::string nextmessage = "nextmessage: size=" + std::to_string(length);
- Poco::Net::WebSocket::sendFrame(nextmessage.data(), nextmessage.size());
- LOG_TRC("Message is long, sent " + nextmessage);
+ const int size = nextmessage.size();
+
+ if (Poco::Net::WebSocket::sendFrame(nextmessage.data(), size) == size)
+ {
+ LOG_TRC("Sent long message preample: " + nextmessage);
+ }
+ else
+ {
+ LOG_WRN("Failed to send long message preample.");
+ return -1;
+ }
}
const int result = Poco::Net::WebSocket::sendFrame(buffer, length, flags);
More information about the Libreoffice-commits
mailing list