fix(win): stop TLS sockets busy-spinning the socket poll loop
pollSocket() caches a socket's writability and skips waiting once it's known writable, relying on writeSocket() to clear the cache on WSAEWOULDBLOCK. SecureSocket writes via SSL_write(), bypassing writeSocket() entirely, so the cache never clears and the multiplexer spins at a zero timeout instead of blocking whenever TLS hits backpressure. Add IArchNetwork::resetPollWriteOnSocket() and call it from checkResult()'s SSL_ERROR_WANT_WRITE case, mirroring writeSocket()'s existing WSAEWOULDBLOCK handling.
This commit is contained in:
parent
0d7414d89a
commit
59d41b906e
4 changed files with 21 additions and 2 deletions
|
|
@ -211,6 +211,16 @@ public:
|
|||
*/
|
||||
virtual size_t writeSocket(ArchSocket s, const void *buf, size_t len) = 0;
|
||||
|
||||
//! Reset the writable poll hint for a socket
|
||||
/*!
|
||||
Tells pollSocket() to wait for a fresh writable notification instead of
|
||||
assuming the socket is still writable. Needed by callers that write to a
|
||||
socket without going through writeSocket(), e.g. OpenSSL's SSL_write().
|
||||
*/
|
||||
virtual void resetPollWriteOnSocket(ArchSocket)
|
||||
{
|
||||
}
|
||||
|
||||
//! Check error on socket
|
||||
/*!
|
||||
If the socket \c s is in an error state then throws an appropriate
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2026 Deskflow Developers
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Synergy App Ltd
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
|
|
@ -557,6 +558,12 @@ size_t ArchNetworkWinsock::writeSocket(ArchSocket s, const void *buf, size_t len
|
|||
return static_cast<size_t>(n);
|
||||
}
|
||||
|
||||
void ArchNetworkWinsock::resetPollWriteOnSocket(ArchSocket s)
|
||||
{
|
||||
assert(s != nullptr);
|
||||
s->m_pollWrite = true;
|
||||
}
|
||||
|
||||
void ArchNetworkWinsock::throwErrorOnSocket(ArchSocket s)
|
||||
{
|
||||
assert(s != nullptr);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2026 Deskflow Developers
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Synergy App Ltd
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
|
|
@ -71,6 +72,7 @@ public:
|
|||
void unblockPollSocket(ArchThread thread) override;
|
||||
size_t readSocket(ArchSocket s, void *buf, size_t len) override;
|
||||
size_t writeSocket(ArchSocket s, const void *buf, size_t len) override;
|
||||
void resetPollWriteOnSocket(ArchSocket s) override;
|
||||
void throwErrorOnSocket(ArchSocket) override;
|
||||
bool setNoDelayOnSocket(ArchSocket, bool noDelay) override;
|
||||
void setKeepAliveOnSocket(ArchSocket, bool keepAlive) override;
|
||||
|
|
|
|||
|
|
@ -556,8 +556,8 @@ void SecureSocket::checkResult(int status, int &retry)
|
|||
break;
|
||||
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
// Need to make sure the socket is known to be writable so the impending
|
||||
// poll action actually triggers on a write.
|
||||
// SSL_write() bypasses writeSocket(), so reset the poll hint ourselves.
|
||||
ARCH->resetPollWriteOnSocket(getSocket());
|
||||
setWritable(true);
|
||||
retry++;
|
||||
LOG_VERBOSE("want to write, error=%d, attempt=%d", errorCode, retry);
|
||||
|
|
|
|||
Loading…
Reference in a new issue