From d46ffdb66b67824e0bd2aec6ecba600517130b67 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sun, 29 Dec 2024 20:49:11 +0700 Subject: [PATCH] Fix Lua memory leaks related to dangling handles --- .../dbotthepony/kstarbound/lua/CommonHandleRegistry.kt | 10 +++++++--- .../ru/dbotthepony/kstarbound/lua/Conversions.kt | 4 ++-- .../kotlin/ru/dbotthepony/kstarbound/lua/LuaHandle.kt | 5 +++-- .../ru/dbotthepony/kstarbound/lua/LuaSharedState.kt | 3 +++ .../kstarbound/world/entities/MonsterEntity.kt | 4 ++-- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/lua/CommonHandleRegistry.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/lua/CommonHandleRegistry.kt index a6a6ec50..007c89e0 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/lua/CommonHandleRegistry.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/lua/CommonHandleRegistry.kt @@ -1,6 +1,10 @@ package ru.dbotthepony.kstarbound.lua data class CommonHandleRegistry( - val future: LuaHandle, - val pathFinder: LuaHandle, -) + val future: LuaHandle = LuaHandle.Nil, + val pathFinder: LuaHandle = LuaHandle.Nil, +) { + companion object { + val EMPTY = CommonHandleRegistry() + } +} diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/lua/Conversions.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/lua/Conversions.kt index 1a36be37..9b10e4da 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/lua/Conversions.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/lua/Conversions.kt @@ -176,10 +176,10 @@ fun LuaThread.getVector2iOrAABB(stackIndex: Int = -1): Either? { fun LuaThread.ArgStack.nextVector2iOrAABB(position: Int = this.position++): Either { if (position !in 1 ..this.top) - throw IllegalArgumentException("bad argument #$position: Vector2d expected, got nil") + throw IllegalArgumentException("bad argument #$position: Vector2i expected, got nil") return lua.getVector2iOrAABB(position) - ?: throw IllegalArgumentException("bad argument #$position: Vector2d or AABB expected, got ${lua.typeAt(position)}") + ?: throw IllegalArgumentException("bad argument #$position: Vector2i or AABB expected, got ${lua.typeAt(position)}") } fun LuaThread.ArgStack.nextOptionalVector2iOrAABB(position: Int = this.position++): Either? { diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/lua/LuaHandle.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/lua/LuaHandle.kt index 7f1fa287..ad61b830 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/lua/LuaHandle.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/lua/LuaHandle.kt @@ -7,6 +7,7 @@ import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.json.InternedJsonElementAdapter import java.io.Closeable import java.lang.ref.Cleaner.Cleanable +import java.lang.ref.WeakReference interface LuaHandle : Closeable { fun push(into: LuaThread) @@ -127,12 +128,12 @@ interface LuaHandle : Closeable { } init { - val parent = parent + val parent = WeakReference(parent) val handle = handle val key = key cleanable = Starbound.CLEANER.register(this) { - parent.freeHandle(handle, key) + parent.get()?.freeHandle(handle, key) } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/lua/LuaSharedState.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/lua/LuaSharedState.kt index a7ff52f0..faaf7b06 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/lua/LuaSharedState.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/lua/LuaSharedState.kt @@ -45,6 +45,9 @@ class LuaSharedState(val handlesThread: LuaThread, private val cleanable: Cleana isValid = false namedHandles.clear() cleanable.clean() + errorToStringFunction = LuaHandle.Nil + errorTrapFunction = LuaHandle.Nil + commonHandles = CommonHandleRegistry.EMPTY } fun initializeHandles(mainThread: LuaThread) { diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/MonsterEntity.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/MonsterEntity.kt index e1c555f9..5c0af90a 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/MonsterEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/entities/MonsterEntity.kt @@ -406,10 +406,10 @@ class MonsterEntity(val variant: MonsterVariant, level: Double? = null) : ActorE } } else { try { - luaUpdate.update(delta) { + /*luaUpdate.update(delta) { luaMovement.clearControlsIfNeeded() forceRegions.clear() - } + }*/ } catch (err: Exception) { LOGGER.error("Exception while ticking $this", err) }