WebSocket::close is re-entrant
This commit is contained in:
parent
af2f31045d
commit
22dffd5b7e
@ -65,7 +65,6 @@ namespace ix
|
|||||||
, _receivedMessageCompressed(false)
|
, _receivedMessageCompressed(false)
|
||||||
, _readyState(ReadyState::CLOSED)
|
, _readyState(ReadyState::CLOSED)
|
||||||
, _closeCode(WebSocketCloseConstants::kInternalErrorCode)
|
, _closeCode(WebSocketCloseConstants::kInternalErrorCode)
|
||||||
, _closeReason(WebSocketCloseConstants::kInternalErrorMessage)
|
|
||||||
, _closeWireSize(0)
|
, _closeWireSize(0)
|
||||||
, _closeRemote(false)
|
, _closeRemote(false)
|
||||||
, _enablePerMessageDeflate(false)
|
, _enablePerMessageDeflate(false)
|
||||||
@ -77,6 +76,7 @@ namespace ix
|
|||||||
, _pingCount(0)
|
, _pingCount(0)
|
||||||
, _lastSendPingTimePoint(std::chrono::steady_clock::now())
|
, _lastSendPingTimePoint(std::chrono::steady_clock::now())
|
||||||
{
|
{
|
||||||
|
setCloseReason(WebSocketCloseConstants::kInternalErrorMessage);
|
||||||
_readbuf.resize(kChunkSize);
|
_readbuf.resize(kChunkSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,13 +179,12 @@ namespace ix
|
|||||||
|
|
||||||
if (readyState == ReadyState::CLOSED)
|
if (readyState == ReadyState::CLOSED)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_closeDataMutex);
|
|
||||||
if (_onCloseCallback)
|
if (_onCloseCallback)
|
||||||
{
|
{
|
||||||
_onCloseCallback(_closeCode, _closeReason, _closeWireSize, _closeRemote);
|
_onCloseCallback(_closeCode, getCloseReason(), _closeWireSize, _closeRemote);
|
||||||
}
|
}
|
||||||
|
setCloseReason(WebSocketCloseConstants::kInternalErrorMessage);
|
||||||
_closeCode = WebSocketCloseConstants::kInternalErrorCode;
|
_closeCode = WebSocketCloseConstants::kInternalErrorCode;
|
||||||
_closeReason = WebSocketCloseConstants::kInternalErrorMessage;
|
|
||||||
_closeWireSize = 0;
|
_closeWireSize = 0;
|
||||||
_closeRemote = false;
|
_closeRemote = false;
|
||||||
}
|
}
|
||||||
@ -642,11 +641,7 @@ namespace ix
|
|||||||
{
|
{
|
||||||
// we got the CLOSE frame answer from our close, so we can close the connection
|
// we got the CLOSE frame answer from our close, so we can close the connection
|
||||||
// if the code/reason are the same
|
// if the code/reason are the same
|
||||||
bool identicalReason;
|
bool identicalReason = _closeCode == code && getCloseReason() == reason;
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(_closeDataMutex);
|
|
||||||
identicalReason = _closeCode == code && _closeReason == reason;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (identicalReason)
|
if (identicalReason)
|
||||||
{
|
{
|
||||||
@ -1084,13 +1079,10 @@ namespace ix
|
|||||||
{
|
{
|
||||||
closeSocket();
|
closeSocket();
|
||||||
|
|
||||||
{
|
setCloseReason(reason);
|
||||||
std::lock_guard<std::mutex> lock(_closeDataMutex);
|
_closeCode = code;
|
||||||
_closeCode = code;
|
_closeWireSize = closeWireSize;
|
||||||
_closeReason = reason;
|
_closeRemote = remote;
|
||||||
_closeWireSize = closeWireSize;
|
|
||||||
_closeRemote = remote;
|
|
||||||
}
|
|
||||||
|
|
||||||
setReadyState(ReadyState::CLOSED);
|
setReadyState(ReadyState::CLOSED);
|
||||||
_requestInitCancellation = false;
|
_requestInitCancellation = false;
|
||||||
@ -1110,13 +1102,11 @@ namespace ix
|
|||||||
closeWireSize = reason.size();
|
closeWireSize = reason.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
setCloseReason(reason);
|
||||||
std::lock_guard<std::mutex> lock(_closeDataMutex);
|
_closeCode = code;
|
||||||
_closeCode = code;
|
_closeWireSize = closeWireSize;
|
||||||
_closeReason = reason;
|
_closeRemote = remote;
|
||||||
_closeWireSize = closeWireSize;
|
|
||||||
_closeRemote = remote;
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_closingTimePointMutex);
|
std::lock_guard<std::mutex> lock(_closingTimePointMutex);
|
||||||
_closingTimePoint = std::chrono::steady_clock::now();
|
_closingTimePoint = std::chrono::steady_clock::now();
|
||||||
@ -1161,4 +1151,15 @@ namespace ix
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebSocketTransport::setCloseReason(const std::string& reason)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_closeReasonMutex);
|
||||||
|
_closeReason = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& WebSocketTransport::getCloseReason() const
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_closeReasonMutex);
|
||||||
|
return _closeReason;
|
||||||
|
}
|
||||||
} // namespace ix
|
} // namespace ix
|
||||||
|
@ -178,11 +178,11 @@ namespace ix
|
|||||||
std::atomic<ReadyState> _readyState;
|
std::atomic<ReadyState> _readyState;
|
||||||
|
|
||||||
OnCloseCallback _onCloseCallback;
|
OnCloseCallback _onCloseCallback;
|
||||||
uint16_t _closeCode;
|
|
||||||
std::string _closeReason;
|
std::string _closeReason;
|
||||||
size_t _closeWireSize;
|
mutable std::mutex _closeReasonMutex;
|
||||||
bool _closeRemote;
|
std::atomic<uint16_t> _closeCode;
|
||||||
mutable std::mutex _closeDataMutex;
|
std::atomic<size_t> _closeWireSize;
|
||||||
|
std::atomic<bool> _closeRemote;
|
||||||
|
|
||||||
// Data used for Per Message Deflate compression (with zlib)
|
// Data used for Per Message Deflate compression (with zlib)
|
||||||
WebSocketPerMessageDeflatePtr _perMessageDeflate;
|
WebSocketPerMessageDeflatePtr _perMessageDeflate;
|
||||||
@ -267,5 +267,8 @@ namespace ix
|
|||||||
void unmaskReceiveBuffer(const wsheader_type& ws);
|
void unmaskReceiveBuffer(const wsheader_type& ws);
|
||||||
|
|
||||||
std::string getMergedChunks() const;
|
std::string getMergedChunks() const;
|
||||||
|
|
||||||
|
void setCloseReason(const std::string& reason);
|
||||||
|
const std::string& getCloseReason() const;
|
||||||
};
|
};
|
||||||
} // namespace ix
|
} // namespace ix
|
||||||
|
Loading…
x
Reference in New Issue
Block a user