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 | |
| parent | a19a2e76fbd8abe1f592f013776a8776a758aa1f (diff) | |
isolate coroutine
Diffstat (limited to 'xmake/core/base')
| -rw-r--r-- | xmake/core/base/os.lua | 6 | ||||
| -rw-r--r-- | xmake/core/base/scheduler.lua | 65 |
2 files changed, 43 insertions, 28 deletions
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua index 8fe7457e9..bff650f5d 100644 --- a/xmake/core/base/os.lua +++ b/xmake/core/base/os.lua @@ -1002,7 +1002,7 @@ end function os.getenvs() local envs = os._CURENVS if not envs then --- print("os.getenvs") + print("os.getenvs") envs = {} for _, line in ipairs(os._getenvs()) do local p = line:find('=', 1, true) @@ -1051,7 +1051,6 @@ function os.setenvs(envs) return oldenvs end ---[[ os._setenv2 = os._setenv os._setenv = function (name, value) print("setenv", name, value) @@ -1062,7 +1061,7 @@ os._getenv = os.getenv os.getenv = function (name) print("getenv", name) return os._getenv(name) -end]] +end -- add environment variables -- e.g. envs["PATH"] = "/xxx:/yyy/foo" @@ -1073,6 +1072,7 @@ function os.addenvs(envs) for name, values in pairs(envs) do local ok local oldenv = oldenvs[name] + print("oldenv", name, oldenv) if oldenv == "" or oldenv == nil then ok = os._setenv(name, values) elseif not oldenv:startswith(values) then 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 |
