Fix a few things about dmon

Ensure that we call coroutine.yield when scanning recursively.

Do not use a weak-key based on project dir when adding the job for rescan.
Since "dir" was not unique many threads were missing.

Ensure we do not block waiting for events if there are pending rescan.
This commit is contained in:
Francesco Abbate 2021-07-23 23:04:57 +02:00
parent fe5e1dc57c
commit 7098043e6e
1 changed files with 12 additions and 5 deletions

View File

@ -116,7 +116,8 @@ end
-- When recursing "root" will always be the same, only "path" will change. -- When recursing "root" will always be the same, only "path" will change.
-- Returns a list of file "items". In eash item the "filename" will be the -- Returns a list of file "items". In eash item the "filename" will be the
-- complete file path relative to "root" *without* the trailing '/'. -- complete file path relative to "root" *without* the trailing '/'.
local function get_directory_files(root, path, t, recursive) local function get_directory_files(root, path, t, recursive, begin_hook)
if begin_hook then begin_hook() end
local size_limit = config.file_size_limit * 10e5 local size_limit = config.file_size_limit * 10e5
local all = system.list_dir(root .. path) or {} local all = system.list_dir(root .. path) or {}
local dirs, files = {}, {} local dirs, files = {}, {}
@ -138,7 +139,7 @@ local function get_directory_files(root, path, t, recursive)
for _, f in ipairs(dirs) do for _, f in ipairs(dirs) do
table.insert(t, f) table.insert(t, f)
if recursive and entries_count <= max_entries then if recursive and entries_count <= max_entries then
local subdir_t, subdir_count = get_directory_files(root, PATHSEP .. f.filename, t, recursive) local subdir_t, subdir_count = get_directory_files(root, PATHSEP .. f.filename, t, recursive, begin_hook)
entries_count = entries_count + subdir_count entries_count = entries_count + subdir_count
f.scanned = true f.scanned = true
end end
@ -274,7 +275,7 @@ local function files_list_replace(a, i1, i2, b)
end end
local function rescan_project_subdir(dir, filename_rooted) local function rescan_project_subdir(dir, filename_rooted)
local new_files = get_directory_files(dir.name, filename_rooted, {}, true) local new_files = get_directory_files(dir.name, filename_rooted, {}, true, coroutine.yield)
local index, n = 0, #dir.files local index, n = 0, #dir.files
if filename_rooted ~= "" then if filename_rooted ~= "" then
local filename = strip_leading_path(filename_rooted) local filename = strip_leading_path(filename_rooted)
@ -1013,6 +1014,12 @@ end
local scheduled_rescan = {} local scheduled_rescan = {}
function core.has_pending_rescan()
for _ in pairs(scheduled_rescan) do
return true
end
end
function core.dir_rescan_add_job(dir, filepath) function core.dir_rescan_add_job(dir, filepath)
local dirpath = filepath:match("^(.+)[/\\].+$") local dirpath = filepath:match("^(.+)[/\\].+$")
local dirpath_rooted = dirpath and PATHSEP .. dirpath or "" local dirpath_rooted = dirpath and PATHSEP .. dirpath or ""
@ -1051,7 +1058,7 @@ function core.dir_rescan_add_job(dir, filepath)
end end
coroutine.yield(0.2) coroutine.yield(0.2)
end end
end, dir) end)
end end
@ -1212,7 +1219,7 @@ function core.run()
local did_redraw = core.step() local did_redraw = core.step()
local need_more_work = run_threads() local need_more_work = run_threads()
if core.restart_request then break end if core.restart_request then break end
if not did_redraw and not need_more_work then if not did_redraw and not need_more_work and not core.has_pending_rescan() then
idle_iterations = idle_iterations + 1 idle_iterations = idle_iterations + 1
-- do not wait of events at idle_iterations = 1 to give a chance at core.step to run -- do not wait of events at idle_iterations = 1 to give a chance at core.step to run
-- and set "redraw" flag. -- and set "redraw" flag.