Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(network): deadlock in lwIP UDP handler's Close function (#30)
This PR fixes a deadlock bug when a careless `PacketRequestSender` tries to `Close` the corresponding `PacketResponseReceiver` multiple times, here is the **buggy** flow chart: ``` user calls PacketResponseReceiver.Close() ↓ udpConnResponseWriter.Close() <----------------------------------------(1) ↓ | udpHandler.closeSession(conn) | ↓ | h.mu.Lock() | ↓ | h.senders[laddr].Close() → PacketRequestSender.Close() → PacketResponseReceiver.Close() ``` Note the recursive call path `(1)`: `h.senders[laddr].Close()` will block because `h.mu` has already be held, and it won't `Unlock()` until `h.senders[laddr].Close()` returns, this causes deadlock! This fix simply added a `closed` indicator in `udpConnResponseWriter` to make sure only one `closeSession` will be called: ``` user calls PacketResponseReceiver.Close() ↓ udpConnResponseWriter.Close() ↓ r.closed.CompareAndSwap(false, true) == true ↓ udpHandler.closeSession(conn) x ↓ | h.mu.Lock() r.closed.CompareAndSwap(false, true) == false ↓ | h.senders[laddr].Close() → PacketRequestSender.Close() → PacketResponseReceiver.Close() ↓ h.mu.UnLock() ```
- Loading branch information