[Libreoffice-commits] online.git: wsd/LOOLWebSocket.hpp
Ashod Nakashian
ashod.nakashian at collabora.co.uk
Mon Feb 13 06:54:01 UTC 2017
wsd/LOOLWebSocket.hpp | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
New commits:
commit 9120fbabad552c22618509cfdc2cf73395e001b7
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>
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
More information about the Libreoffice-commits
mailing list