From 00da2ee53e0da3a861c5a5c7ed1eaa516af2975d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sat, 25 Jul 2015 14:53:57 +0200 Subject: [PATCH] Should fix potential deadlock when machines get disposed while they're running. Closes #1322. --- .../scala/li/cil/oc/server/machine/Machine.scala | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/scala/li/cil/oc/server/machine/Machine.scala b/src/main/scala/li/cil/oc/server/machine/Machine.scala index 8bb64559b..459b7eb60 100644 --- a/src/main/scala/li/cil/oc/server/machine/Machine.scala +++ b/src/main/scala/li/cil/oc/server/machine/Machine.scala @@ -835,9 +835,11 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach true } - private def close() = state.synchronized( - if (state.isEmpty || state.top != Machine.State.Stopped) { - this.synchronized { + private def close() = + if (state.synchronized(state.isEmpty || state.top != Machine.State.Stopped)) { + // Give up the state lock, then get the more generic lock on this instance first + // before locking on state again. Always must be in that order to avoid deadlocks. + this.synchronized(state.synchronized { state.clear() state.push(Machine.State.Stopped) Option(architecture).foreach(_.close()) @@ -846,11 +848,11 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach cpuTotal = 0 cpuStart = 0 remainIdle = 0 - } + }) // Mark state change in owner, to send it to clients. host.markChanged() - }) + } // ----------------------------------------------------------------------- //