summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2020-02-06 00:54:46 +0800
committerruki <[email protected]>2020-02-07 22:45:57 +0800
commitdfef2f8ca41884138c5105cc7cbf55a67510f54d (patch)
tree0b3f363f7a8758b9a1c6ec6f8650cd9e45f20a95
parentd40841b322485ec4200a857979b2ea77677a906a (diff)
fix curdir for scheduler
-rw-r--r--xmake/actions/require/impl/package.lua4
-rw-r--r--xmake/core/base/os.lua10
-rw-r--r--xmake/core/base/scheduler.lua41
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/find_program.lua2
-rw-r--r--xmake/modules/lib/detect/features.lua2
-rw-r--r--xmake/modules/lib/detect/has_flags.lua2
6 files changed, 50 insertions, 11 deletions
diff --git a/xmake/actions/require/impl/package.lua b/xmake/actions/require/impl/package.lua
index 6afb7b876..acbbcb193 100644
--- a/xmake/actions/require/impl/package.lua
+++ b/xmake/actions/require/impl/package.lua
@@ -577,9 +577,7 @@ function _install_packages(packages_install, packages_download)
end
end
if package == nil and #packages_pending > 0 then
- local curdir = os.curdir()
scheduler.co_yield()
- os.cd(curdir)
end
end
if package then
@@ -594,9 +592,7 @@ function _install_packages(packages_install, packages_download)
end
if not parallelize then
while installing_count > 0 do
- local curdir = os.curdir()
scheduler.co_yield()
- os.cd(curdir)
end
end
installing_count = installing_count + 1
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index 35099cc9e..a2c6eb3be 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -155,6 +155,11 @@ function os._ramdir()
return ramdir_root or nil
end
+-- set on change directory callback for scheduler
+function os._sched_chdir_set(chdir)
+ os._SCHED_CHDIR = chdir
+end
+
-- translate arguments for wildcard
function os.argw(argv)
@@ -459,6 +464,11 @@ function os.cd(dir)
return nil, string.format("cannot change directory %s, not found this directory %s", dir, os.strerror())
end
+ -- do chdir callback for scheduler
+ if os._SCHED_CHDIR then
+ os._SCHED_CHDIR(oldir, os.curdir())
+ end
+
-- ok
return oldir
end
diff --git a/xmake/core/base/scheduler.lua b/xmake/core/base/scheduler.lua
index 63829a913..a6ad21264 100644
--- a/xmake/core/base/scheduler.lua
+++ b/xmake/core/base/scheduler.lua
@@ -234,6 +234,26 @@ function scheduler:_poller_events_cb(obj, events)
return true
end
+-- update the current directory hash of current coroutine
+function scheduler:_co_curdir_update(curdir)
+
+ -- save the current directory hash
+ curdir = curdir or os.curdir()
+ local curdir_hash = hash.uuid4(path.absolute(curdir)):sub(1, 8)
+ self._CO_CURDIR = 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}
+ end
+end
+
-- get all suspended coroutine tasks
function scheduler:_co_tasks_suspended()
local co_tasks_suspended = self._CO_TASKS_SUSPENDED
@@ -306,6 +326,7 @@ function scheduler:co_start_named(coname, cotask, ...)
-- start coroutine
local co
co = _coroutine.new(coname, coroutine.create(function(...)
+ self:_co_curdir_update()
cotask(...)
self:co_tasks()[co:thread()] = nil
if self:co_count() > 0 then
@@ -341,7 +362,20 @@ end
-- suspend the current coroutine
function scheduler:co_suspend(...)
- return coroutine.yield(...)
+
+ -- suspend it
+ local results = table.pack(coroutine.yield(...))
+
+ -- if the current directory has been changed? restore it
+ local running = assert(self:co_running())
+ local curdir = self._CO_CURDIR
+ local olddir = self._CO_CURDIRS and self._CO_CURDIRS[running] or nil
+ if olddir and curdir ~= olddir[1] then -- hash changed?
+ os.cd(olddir[2])
+ end
+
+ -- return results
+ return table.unpack(results)
end
-- yield the current coroutine
@@ -710,6 +744,11 @@ function scheduler:runloop()
self._SUPPORT_EV_POLLER_CLEAR = true
end
+ -- set on change directory callback for scheduler
+ os._sched_chdir_set(function (oldir, curdir)
+ self:_co_curdir_update(curdir)
+ end)
+
-- start all ready coroutine tasks
local co_ready_tasks = self._CO_READY_TASKS
if co_ready_tasks then
diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua
index 0e5d500b2..120125687 100644
--- a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua
+++ b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua
@@ -242,9 +242,7 @@ function sandbox_lib_detect_find_program.main(name, opt)
local coroutine_running = scheduler.co_running()
if coroutine_running then
while checking ~= nil and checking == name do
- local curdir = os.curdir()
scheduler.co_yield()
- os.cd(curdir)
end
end
diff --git a/xmake/modules/lib/detect/features.lua b/xmake/modules/lib/detect/features.lua
index 60799c667..048ee85a6 100644
--- a/xmake/modules/lib/detect/features.lua
+++ b/xmake/modules/lib/detect/features.lua
@@ -61,9 +61,7 @@ function main(name, opt)
local coroutine_running = scheduler.co_running()
if coroutine_running then
while _g._checking ~= nil and _g._checking == key do
- local curdir = os.curdir()
scheduler.co_yield()
- os.cd(curdir)
end
end
diff --git a/xmake/modules/lib/detect/has_flags.lua b/xmake/modules/lib/detect/has_flags.lua
index 1abf466a7..833bbcf65 100644
--- a/xmake/modules/lib/detect/has_flags.lua
+++ b/xmake/modules/lib/detect/has_flags.lua
@@ -78,9 +78,7 @@ function main(name, flags, opt)
local coroutine_running = scheduler.co_running()
if coroutine_running then
while _g._checking ~= nil and _g._checking == key do
- local curdir = os.curdir()
scheduler.co_yield()
- os.cd(curdir)
end
end