From d03e78b0cbe1edfd852c55ffca776641aa9a0de6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Fri, 17 Apr 2015 20:14:51 +0200 Subject: [PATCH] Made time limit enforcement in __gc wrapper more memory friendly, closes #1079. --- .../assets/opencomputers/lua/machine.lua | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/resources/assets/opencomputers/lua/machine.lua b/src/main/resources/assets/opencomputers/lua/machine.lua index 3402c90ec..e72d36f1f 100644 --- a/src/main/resources/assets/opencomputers/lua/machine.lua +++ b/src/main/resources/assets/opencomputers/lua/machine.lua @@ -634,6 +634,14 @@ local function spcall(...) end end +local sgcco + +local function sgcf(self, gc) + while true do + self, gc = coroutine.yield(pcall(gc, self)) + end +end + local function sgc(self) local oldDeadline, oldHitDeadline = deadline, hitDeadline local mt = debug.getmetatable(self) @@ -642,11 +650,16 @@ local function sgc(self) if type(gc) ~= "function" then return end - local co = coroutine.create(gc) - debug.sethook(co, checkDeadline, "", hookInterval) + if not sgcco then + sgcco = coroutine.create(sgcf) + end + debug.sethook(sgcco, checkDeadline, "", hookInterval) deadline, hitDeadline = math.min(oldDeadline, computer.realTime() + 0.5), true - local result, reason = coroutine.resume(co, self) - debug.sethook(co) + local _, result, reason = coroutine.resume(sgcco, self, gc) + debug.sethook(sgcco) + if coroutine.status(sgcco) == "dead" then + sgcco = nil + end deadline, hitDeadline = oldDeadline, oldHitDeadline if not result then error(reason, 0)