From 9a1a82e62365476a176adfb9a16cab32fa668c24 Mon Sep 17 00:00:00 2001
From: vis2k <info@noobtuts.com>
Date: Thu, 22 Oct 2020 10:53:39 +0200
Subject: [PATCH] fix: KcpConnection.Disconnect sets open=false BEFORE calling
 OnDisconnected to prevent deadlocks like
 https://github.com/vis2k/Mirror/issues/2357

---
 kcp2k/Assets/kcp2k/highlevel/KcpConnection.cs | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/kcp2k/Assets/kcp2k/highlevel/KcpConnection.cs b/kcp2k/Assets/kcp2k/highlevel/KcpConnection.cs
index f1ea60f8..348a93fc 100644
--- a/kcp2k/Assets/kcp2k/highlevel/KcpConnection.cs
+++ b/kcp2k/Assets/kcp2k/highlevel/KcpConnection.cs
@@ -244,14 +244,27 @@ public void Handshake()
         /// </summary>
         public virtual void Disconnect()
         {
+            // do nothing if already closed
+            if (!open) return;
+
+            // set as closed BEFORE calling OnDisconnected event.
+            // this avoids potential deadlocks like this Mirror bug:
+            // https://github.com/vis2k/Mirror/issues/2357
+            // where OnDisconnected->Mirror.OnDisconnected->ServerDisconnect->
+            //       Connection.Disconnect->Kcp.Disconnect->OnDisconnected->
+            //       DEADLOCK
+            open = false;
+
             // send a disconnect message and disconnect
-            if (open && socket.Connected)
+            if (socket.Connected)
             {
                 try
                 {
                     Send(Goodby);
                     kcp.Flush();
 
+                    // set as not open
+
                     // call OnDisconnected event, even if we manually
                     // disconnected
                     OnDisconnected?.Invoke();
@@ -270,10 +283,6 @@ public virtual void Disconnect()
                     // were disconnected
                 }
             }
-            open = false;
-
-            // EOF is now available
-            //dataAvailable?.TrySetResult();
         }
 
         // get remote endpoint