From dc0a3791060a6236bac4251a27eb7d7f2de3cb89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Fri, 21 Jun 2019 16:24:10 +0800 Subject: =?UTF-8?q?=E5=BD=93=E8=A6=81=E5=8A=A0=E8=BD=BD=E7=9A=84=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=81=B0=E5=A5=BD=E5=A4=84=E4=BA=8E=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E5=8D=8F=E7=A8=8B=E4=B8=AD=E6=97=B6=EF=BC=8C=E5=BF=AB=E8=BF=9B?= =?UTF-8?q?=E5=8D=8F=E7=A8=8B=E8=80=8C=E4=B8=8D=E6=98=AF=E6=8A=9B=E5=BC=83?= =?UTF-8?q?=E5=8D=8F=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/src/service.lua | 39 +++++++++++++++--------------- server/src/task.lua | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 20 deletions(-) create mode 100644 server/src/task.lua (limited to 'server') diff --git a/server/src/service.lua b/server/src/service.lua index ee2965a9..945cd939 100644 --- a/server/src/service.lua +++ b/server/src/service.lua @@ -16,6 +16,7 @@ local functionMgr= require 'vm.function' local listMgr = require 'vm.list' local emmyMgr = require 'emmy.manager' local config = require 'config' +local task = require 'task' local ErrorCodes = { -- Defined by JSON RPC @@ -353,7 +354,14 @@ function mt:loadVM(uri) if uri ~= self._lastLoadedVM then self:needCompile(uri) end - self:compileVM(uri) + if self._compileTask + and not self._compileTask:isRemoved() + and self._compileTask:get 'uri' == uri + then + self._compileTask:fastForward() + else + self:compileVM(uri) + end if obj.vm then self._lastLoadedVM = uri end @@ -638,12 +646,12 @@ function mt:_createCompileTask() message = lang.script.MWS_COMPLETE, }) end - return end - self._compileTask = coroutine.create(function () + self._compileTask = task(function () self:doDiagnostics(self._lastLoadedVM) local uri = self._needCompile[1] if uri then + self._compileTask:set('uri', uri) pcall(function () self:compileVM(uri) end) else uri = next(self._needDiagnostics) @@ -655,29 +663,20 @@ function mt:_createCompileTask() end function mt:_doCompileTask() - if not self._compileTask then + if not self._compileTask or self._compileTask:isRemoved() then self:_createCompileTask() end - if not self._compileTask then - return - end - while self._compileTask do - local suc, res = coroutine.resume(self._compileTask) - if not suc then - self._compileTask = nil - return - end + while true do + local res = self._compileTask:step() if res == 'stop' then - self._compileTask = nil - return + self._compileTask:remove() + break end - if coroutine.status(self._compileTask) == 'suspended' then - self:_loadProto() - else - self._compileTask = nil - return + if self._compileTask:isRemoved() then + break end end + self:_loadProto() end function mt:_loadProto() diff --git a/server/src/task.lua b/server/src/task.lua new file mode 100644 index 00000000..a1ed37de --- /dev/null +++ b/server/src/task.lua @@ -0,0 +1,64 @@ +local mt = {} +mt.__index = mt +mt.type = 'task' + +function mt:remove() + if self._removed then + return + end + self._removed = true +end + +function mt:isRemoved() + return self._removed +end + +function mt:step() + if self._removed then + return + end + local suc, res = coroutine.resume(self.task) + if not suc then + self:remove() + log.error(debug.traceback(self.task, res)) + return + end + if coroutine.status(self.task) == 'dead' then + self:remove() + end + return res +end + +function mt:fastForward() + if self._removed then + return + end + while true do + local suc = coroutine.resume(self.task) + if not suc then + self:remove() + break + end + if coroutine.status(self.task) == 'dead' then + self:remove() + break + end + end +end + +function mt:set(key, value) + self.data[key] = value +end + +function mt:get(key) + return self.data[key] +end + +return function (callback) + local self = setmetatable({ + callback = callback, + data = {}, + task = coroutine.create(callback), + }, mt) + return self +end -- cgit v1.2.3