diff options
| author | ruki <[email protected]> | 2021-05-12 00:37:42 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2021-05-12 00:37:42 +0800 |
| commit | 4e67226f86e1949d1087893cd8fe218535d91ba9 (patch) | |
| tree | ab02507940eabe403903b4ce80ec353681510223 /xmake/core/base/scheduler.lua | |
| parent | a19a2e76fbd8abe1f592f013776a8776a758aa1f (diff) | |
isolate coroutine
Diffstat (limited to 'xmake/core/base/scheduler.lua')
| -rw-r--r-- | xmake/core/base/scheduler.lua | 65 |
1 files changed, 40 insertions, 25 deletions
diff --git a/xmake/core/base/scheduler.lua b/xmake/core/base/scheduler.lua index 34dfacb85..c33b5c7f0 100644 --- a/xmake/core/base/scheduler.lua +++ b/xmake/core/base/scheduler.lua @@ -87,15 +87,14 @@ function _coroutine:is_suspended() return self:status() == "suspended" end --- is trampoline? -function _coroutine:is_trampoline() - return self._TRAMPOLINE +-- is isolated? +function _coroutine:is_isolated() + return self._ISOLATED end --- mark this coroutine as trampoline, --- envs and curdir will not be changed when switch to this coroutine -function _coroutine:set_trampoline(trampoline) - self._TRAMPOLINE = trampoline +-- isolate coroutine environments +function _coroutine:isolate(isolate) + self._ISOLATED = isolate end -- get the current timer task @@ -249,26 +248,35 @@ end -- update the current directory hash of current coroutine function scheduler:_co_curdir_update(curdir) + -- get running coroutine + local running = self:co_running() + if not running then + return + end + -- save the current directory hash curdir = curdir or os.curdir() local curdir_hash = hash.uuid4(path.absolute(curdir)):sub(1, 8) self._CO_CURDIR_HASH = curdir_hash -- save the current directory for each coroutine - local running = self:co_running() - if running then - local co_curdirs = self._CO_CURDIRS - if not co_curdirs then - co_curdirs = {} - self._CO_CURDIRS = co_curdirs - end - co_curdirs[running] = {curdir_hash, curdir} + local co_curdirs = self._CO_CURDIRS + if not co_curdirs then + co_curdirs = {} + self._CO_CURDIRS = co_curdirs end + co_curdirs[running] = {curdir_hash, curdir} end -- update the current environments hash of current coroutine function scheduler:_co_curenvs_update(envs) + -- get running coroutine + local running = self:co_running() + if not running or not running:is_isolated() then + return + end + -- save the current directory hash local envs_hash = "" envs = envs or os.getenvs() @@ -279,15 +287,12 @@ function scheduler:_co_curenvs_update(envs) self._CO_CURENVS_HASH = envs_hash -- save the current directory for each coroutine - local running = self:co_running() - if running then - local co_curenvs = self._CO_CURENVS - if not co_curenvs then - co_curenvs = {} - self._CO_CURENVS = co_curenvs - end - co_curenvs[running] = {envs_hash, envs} + local co_curenvs = self._CO_CURENVS + if not co_curenvs then + co_curenvs = {} + self._CO_CURENVS = co_curenvs end + co_curenvs[running] = {envs_hash, envs} end -- resume it's waiting coroutine if all coroutines are dead in group @@ -339,8 +344,15 @@ end -- start a new named coroutine task function scheduler:co_start_named(coname, cotask, ...) + return self:co_start_withopt({name = coname}, cotask, ...) +end + +-- start a new coroutine task with options +function scheduler:co_start_withopt(opt, cotask, ...) -- check coroutine task + opt = opt or {} + local coname = opt.name if not cotask then return nil, string.format("cannot start coroutine, invalid cotask(%s/%s)", coname and coname or "anonymous", cotask) end @@ -356,6 +368,9 @@ function scheduler:co_start_named(coname, cotask, ...) self._CO_COUNT = self:co_count() - 1 end end)) + if opt.isolate then + co:isolate(true) + end self:co_tasks()[co:thread()] = co self._CO_COUNT = self:co_count() + 1 if self._STARTED then @@ -393,14 +408,14 @@ function scheduler:co_suspend(...) local running = assert(self:co_running()) local curdir = self._CO_CURDIR_HASH local olddir = self._CO_CURDIRS and self._CO_CURDIRS[running] or nil - if olddir and curdir ~= olddir[1] and not running:is_trampoline() then -- hash changed? + if olddir and curdir ~= olddir[1] then -- hash changed? os.cd(olddir[2]) end -- if the current environments has been changed? restore it local curenvs = self._CO_CURENVS_HASH local oldenvs = self._CO_CURENVS and self._CO_CURENVS[running] or nil - if oldenvs and curenvs ~= oldenvs[1] and not running:is_trampoline() then -- hash changed? + if oldenvs and curenvs ~= oldenvs[1] and running:is_isolated() then -- hash changed? os.setenvs(oldenvs[2]) end |
