In FtlServer::onNewControlConnection(...), a timeout thread is started that waits a number of seconds and then stops the control connection if it has not yet authenticated.
When the timeout lapses, the connection is stopped while a streamDataMutex lock is held.
|
std::unique_lock streamDataLock(streamDataMutex); |
|
if (pendingControlConnections.count(ingestControlConnectionPtr) > 0) |
|
{ |
|
spdlog::info("{} didn't authenticate within {}ms, closing", |
|
addrString, CONNECTION_AUTH_TIMEOUT_MS); |
|
pendingControlConnections.at(ingestControlConnectionPtr)->Stop(); |
|
pendingControlConnections.erase(ingestControlConnectionPtr); |
|
} |
Under some very specific timing circumstances, a deadlock can occur if the timeout elapses around the same time the connection thread attempts to acquire a lock to process stream state changes.
The deadlock looks something like this:
- Client connects and the timeout thread starts
FtlServer attempts to request a new Stream ID
- Timeout thread expires, lock is acquired on
streamDataMutex while waiting for the connection thread to stop
- Connection thread is stuck attempting to acquire a lock on
streamDataMutex to indicate that the stream has started
I was able to reproduce while debugging a REST server implementation by holding up a response to ServiceConnection::StartStream(...), which ended up resulting in lock contention between
and
|
pendingControlConnections.at(ingestControlConnectionPtr)->Stop(); |
In
FtlServer::onNewControlConnection(...), a timeout thread is started that waits a number of seconds and then stops the control connection if it has not yet authenticated.When the timeout lapses, the connection is stopped while a
streamDataMutexlock is held.janus-ftl-plugin/src/FtlServer.cpp
Lines 191 to 198 in ad2ab78
Under some very specific timing circumstances, a deadlock can occur if the timeout elapses around the same time the connection thread attempts to acquire a lock to process stream state changes.
The deadlock looks something like this:
FtlServerattempts to request a new Stream IDstreamDataMutexwhile waiting for the connection thread to stopstreamDataMutexto indicate that the stream has startedI was able to reproduce while debugging a REST server implementation by holding up a response to
ServiceConnection::StartStream(...), which ended up resulting in lock contention betweenjanus-ftl-plugin/src/FtlServer.cpp
Line 229 in ad2ab78
and
janus-ftl-plugin/src/FtlServer.cpp
Line 196 in ad2ab78