Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[SSHD-1289] Fix lock handling in KeyExchangeMessageHandler
Make sure that a thread does not try to acquire the write lock if it already holds the read lock. This could happen if a write is not enqueued and there is an exception during writing, and we then try to close the session on the same thread. The read/write lock is used for three purposes: first, it gives the flushing thread trying to empty the queue of pending packets priority over other threads trying to enqueue more packets, and second, it is held during writeOrEnqueue() while writing a packet directly to prevent that the KEX state changes between being checked and the write being done, and third, to prevent that the KEX state changes asynchronously while the flushing thread is checking it. The read/write lock itself does not serve to ensure mutual exclusion on the KEX state itself. These three functions can also be fulfilled if update() is executed when only the read lock is held. If a thread in update() holds the read lock, this can only occur if it wrote the buffer directly in writeOrEnqueue(), in which case it is fine to proceed, and the flushing thread for sure is not in its critical region where it holds the write lock. Otherwise, any other thread either is the flushing thread and holds the write lock already, or it's a thread not holding the lock at all. In both cases it is fine to acquire the write lock.
- Loading branch information