mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-15 02:12:42 -04:00
Somewhat experimental fix for memory leaks seen in Microcontrollers. If you notice any new issues after this, please do let me know.
This essentially schedules machines for full cleanup at a later point, to allow executor threads to finish (can't close states while they're running, don't want to wait for them to finish to avoid lagging servers).
This commit is contained in:
parent
5e9861d04a
commit
d13cdc0cd8
@ -22,6 +22,7 @@ import li.cil.oc.common.tileentity.traits.power
|
|||||||
import li.cil.oc.integration.Mods
|
import li.cil.oc.integration.Mods
|
||||||
import li.cil.oc.integration.util
|
import li.cil.oc.integration.util
|
||||||
import li.cil.oc.server.component.Keyboard
|
import li.cil.oc.server.component.Keyboard
|
||||||
|
import li.cil.oc.server.machine.Machine
|
||||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||||
import li.cil.oc.util._
|
import li.cil.oc.util._
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
@ -49,12 +50,16 @@ object EventHandler {
|
|||||||
|
|
||||||
private val keyboards = java.util.Collections.newSetFromMap[Keyboard](new java.util.WeakHashMap[Keyboard, java.lang.Boolean])
|
private val keyboards = java.util.Collections.newSetFromMap[Keyboard](new java.util.WeakHashMap[Keyboard, java.lang.Boolean])
|
||||||
|
|
||||||
|
private val machines = mutable.Set.empty[Machine]
|
||||||
|
|
||||||
def onRobotStart(robot: Robot): Unit = runningRobots += robot
|
def onRobotStart(robot: Robot): Unit = runningRobots += robot
|
||||||
|
|
||||||
def onRobotStopped(robot: Robot): Unit = runningRobots -= robot
|
def onRobotStopped(robot: Robot): Unit = runningRobots -= robot
|
||||||
|
|
||||||
def addKeyboard(keyboard: Keyboard): Unit = keyboards += keyboard
|
def addKeyboard(keyboard: Keyboard): Unit = keyboards += keyboard
|
||||||
|
|
||||||
|
def scheduleClose(machine: Machine) = machines += machine
|
||||||
|
|
||||||
def schedule(tileEntity: TileEntity) {
|
def schedule(tileEntity: TileEntity) {
|
||||||
if (SideTracker.isServer) pending.synchronized {
|
if (SideTracker.isServer) pending.synchronized {
|
||||||
pending += (() => Network.joinOrCreateNetwork(tileEntity))
|
pending += (() => Network.joinOrCreateNetwork(tileEntity))
|
||||||
@ -130,6 +135,10 @@ object EventHandler {
|
|||||||
else if (robot.world != null) robot.machine.update()
|
else if (robot.world != null) robot.machine.update()
|
||||||
})
|
})
|
||||||
runningRobots --= invalid
|
runningRobots --= invalid
|
||||||
|
|
||||||
|
val closed = mutable.ArrayBuffer.empty[Machine]
|
||||||
|
machines.foreach(machine => if (machine.tryClose()) closed += machine)
|
||||||
|
machines --= closed
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
@ -127,6 +127,11 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
|
|||||||
ServerPacketSender.sendComputerState(this)
|
ServerPacketSender.sendComputerState(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def dispose(): Unit = {
|
||||||
|
super.dispose()
|
||||||
|
if (machine != null) machine.stop()
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
override def readFromNBTForServer(nbt: NBTTagCompound) {
|
override def readFromNBTForServer(nbt: NBTTagCompound) {
|
||||||
|
@ -23,6 +23,7 @@ import li.cil.oc.api.network.Message
|
|||||||
import li.cil.oc.api.network.Node
|
import li.cil.oc.api.network.Node
|
||||||
import li.cil.oc.api.network.Visibility
|
import li.cil.oc.api.network.Visibility
|
||||||
import li.cil.oc.api.prefab
|
import li.cil.oc.api.prefab
|
||||||
|
import li.cil.oc.common.EventHandler
|
||||||
import li.cil.oc.common.SaveHandler
|
import li.cil.oc.common.SaveHandler
|
||||||
import li.cil.oc.common.Slot
|
import li.cil.oc.common.Slot
|
||||||
import li.cil.oc.common.tileentity
|
import li.cil.oc.common.tileentity
|
||||||
@ -257,6 +258,7 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
|||||||
false
|
false
|
||||||
case _ =>
|
case _ =>
|
||||||
state.push(Machine.State.Stopping)
|
state.push(Machine.State.Stopping)
|
||||||
|
EventHandler.scheduleClose(this)
|
||||||
true
|
true
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -392,6 +394,8 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
def isExecuting = state.synchronized(state.contains(Machine.State.Running))
|
||||||
|
|
||||||
override val canUpdate = true
|
override val canUpdate = true
|
||||||
|
|
||||||
override def update() = if (state.synchronized(state.top != Machine.State.Stopped)) {
|
override def update() = if (state.synchronized(state.top != Machine.State.Stopped)) {
|
||||||
@ -514,7 +518,7 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
|||||||
inSynchronizedCall = false
|
inSynchronizedCall = false
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(state.top != Machine.State.Running)
|
assert(!isExecuting)
|
||||||
case _ => // Nothing special to do, just avoid match errors.
|
case _ => // Nothing special to do, just avoid match errors.
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -643,7 +647,7 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
|||||||
|
|
||||||
super.load(nbt)
|
super.load(nbt)
|
||||||
|
|
||||||
state.pushAll(nbt.getIntArray("state").reverse.map(Machine.State(_)))
|
state.pushAll(nbt.getIntArray("state").reverseMap(Machine.State(_)))
|
||||||
nbt.getTagList("users", NBT.TAG_STRING).foreach((tag: NBTTagString) => _users += tag.func_150285_a_())
|
nbt.getTagList("users", NBT.TAG_STRING).foreach((tag: NBTTagString) => _users += tag.func_150285_a_())
|
||||||
if (nbt.hasKey("message")) {
|
if (nbt.hasKey("message")) {
|
||||||
message = Some(nbt.getString("message"))
|
message = Some(nbt.getString("message"))
|
||||||
@ -703,7 +707,7 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
|||||||
}
|
}
|
||||||
|
|
||||||
override def save(nbt: NBTTagCompound): Unit = Machine.this.synchronized {
|
override def save(nbt: NBTTagCompound): Unit = Machine.this.synchronized {
|
||||||
assert(state.top != Machine.State.Running) // Lock on 'this' should guarantee this.
|
assert(!isExecuting) // Lock on 'this' should guarantee this.
|
||||||
|
|
||||||
// Make sure we don't continue running until everything has saved.
|
// Make sure we don't continue running until everything has saved.
|
||||||
pause(0.05)
|
pause(0.05)
|
||||||
@ -798,8 +802,16 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def tryClose(): Boolean =
|
||||||
|
if (isExecuting) false
|
||||||
|
else {
|
||||||
|
close()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
private def close() = state.synchronized(
|
private def close() = state.synchronized(
|
||||||
if (state.size == 0 || state.top != Machine.State.Stopped) {
|
if (state.size == 0 || state.top != Machine.State.Stopped) {
|
||||||
|
this.synchronized {
|
||||||
state.clear()
|
state.clear()
|
||||||
state.push(Machine.State.Stopped)
|
state.push(Machine.State.Stopped)
|
||||||
Option(architecture).foreach(_.close())
|
Option(architecture).foreach(_.close())
|
||||||
@ -808,6 +820,7 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
|||||||
cpuTotal = 0
|
cpuTotal = 0
|
||||||
cpuStart = 0
|
cpuStart = 0
|
||||||
remainIdle = 0
|
remainIdle = 0
|
||||||
|
}
|
||||||
|
|
||||||
// Mark state change in owner, to send it to clients.
|
// Mark state change in owner, to send it to clients.
|
||||||
host.markChanged()
|
host.markChanged()
|
||||||
@ -909,7 +922,7 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
|||||||
case Machine.State.Stopping => // Nothing to do, we'll die anyway.
|
case Machine.State.Stopping => // Nothing to do, we'll die anyway.
|
||||||
case _ => throw new AssertionError("Invalid state in executor post-processing.")
|
case _ => throw new AssertionError("Invalid state in executor post-processing.")
|
||||||
}
|
}
|
||||||
assert(state.top != Machine.State.Running)
|
assert(!isExecuting)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user