diff options
author | Pierre Ossman <ossman@cendio.se> | 2021-01-19 13:45:06 +0100 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2021-01-19 13:45:06 +0100 |
commit | 59d5bc4095383f73635398c21611d95274a4d914 (patch) | |
tree | e4c325f0013ed27cc38b9e7d5538550457a7db77 /win | |
parent | edaf70bd36667c85d70fb362213ec93c58bb8577 (diff) | |
parent | 8ddebf6dd2dca7be98230e2b8d567c70833bd5a7 (diff) | |
download | tigervnc-59d5bc4095383f73635398c21611d95274a4d914.tar.gz tigervnc-59d5bc4095383f73635398c21611d95274a4d914.zip |
Merge branch 'noblock' of https://github.com/CendioOssman/tigervnc
Diffstat (limited to 'win')
-rw-r--r-- | win/rfb_win32/SocketManager.cxx | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/win/rfb_win32/SocketManager.cxx b/win/rfb_win32/SocketManager.cxx index 0092d94d..393e2191 100644 --- a/win/rfb_win32/SocketManager.cxx +++ b/win/rfb_win32/SocketManager.cxx @@ -170,6 +170,13 @@ int SocketManager::checkTimeouts() { j_next = j; j_next++; if (j->second.sock->isShutdown()) shutdownSocks.push_back(j->second.sock); + else { + long eventMask = FD_READ | FD_CLOSE; + if (j->second.sock->outStream().hasBufferedData()) + eventMask |= FD_WRITE; + if (WSAEventSelect(j->second.sock->getFd(), j->first, eventMask) == SOCKET_ERROR) + throw rdr::SystemException("unable to adjust WSAEventSelect:%u", WSAGetLastError()); + } } std::list<network::Socket*>::iterator k; @@ -213,6 +220,13 @@ void SocketManager::processEvent(HANDLE event) { try { // Process data from an active connection + WSANETWORKEVENTS events; + long eventMask; + + // Fetch why this event notification triggered + if (WSAEnumNetworkEvents(ci.sock->getFd(), event, &events) == SOCKET_ERROR) + throw rdr::SystemException("unable to get WSAEnumNetworkEvents:%u", WSAGetLastError()); + // Cancel event notification for this socket if (WSAEventSelect(ci.sock->getFd(), event, 0) == SOCKET_ERROR) throw rdr::SystemException("unable to disable WSAEventSelect:%u", WSAGetLastError()); @@ -220,16 +234,29 @@ void SocketManager::processEvent(HANDLE event) { // Reset the event object WSAResetEvent(event); + // Call the socket server to process the event - ci.server->processSocketReadEvent(ci.sock); - if (ci.sock->isShutdown()) { - remSocket(ci.sock); - return; + if (events.lNetworkEvents & FD_WRITE) { + ci.server->processSocketWriteEvent(ci.sock); + if (ci.sock->isShutdown()) { + remSocket(ci.sock); + return; + } + } + if (events.lNetworkEvents & (FD_READ | FD_CLOSE)) { + ci.server->processSocketReadEvent(ci.sock); + if (ci.sock->isShutdown()) { + remSocket(ci.sock); + return; + } } // Re-instate the required socket event // If the read event is still valid, the event object gets set here - if (WSAEventSelect(ci.sock->getFd(), event, FD_READ | FD_CLOSE) == SOCKET_ERROR) + eventMask = FD_READ | FD_CLOSE; + if (ci.sock->outStream().hasBufferedData()) + eventMask |= FD_WRITE; + if (WSAEventSelect(ci.sock->getFd(), event, eventMask) == SOCKET_ERROR) throw rdr::SystemException("unable to re-enable WSAEventSelect:%u", WSAGetLastError()); } catch (rdr::Exception& e) { vlog.error("%s", e.str()); |