mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 04:43:10 +00:00
Remove support for the builtin_script_t feature
This was an old experiment to compile scripts directly into the shell itself, reducing the amount of I/O performed at startup. It has not been used for a long time. Time to remove it.
This commit is contained in:
parent
6db372133d
commit
e8d90dbf4b
2 changed files with 60 additions and 111 deletions
158
src/autoload.cpp
158
src/autoload.cpp
|
@ -47,12 +47,9 @@ file_access_attempt_t access_file(const wcstring &path, int mode) {
|
|||
}
|
||||
|
||||
autoload_t::autoload_t(const wcstring &env_var_name_var,
|
||||
command_removed_function_t cmd_removed_callback,
|
||||
const builtin_script_t *const scripts, size_t script_count)
|
||||
command_removed_function_t cmd_removed_callback)
|
||||
: lock(),
|
||||
env_var_name(env_var_name_var),
|
||||
builtin_scripts(scripts),
|
||||
builtin_script_count(script_count),
|
||||
command_removed(cmd_removed_callback) {
|
||||
pthread_mutex_init(&lock, NULL);
|
||||
}
|
||||
|
@ -123,11 +120,6 @@ bool autoload_t::can_load(const wcstring &cmd, const env_vars_snapshot_t &vars)
|
|||
return this->locate_file_and_maybe_load_it(cmd, false, false, path_list);
|
||||
}
|
||||
|
||||
static bool script_name_precedes_script_name(const builtin_script_t &script1,
|
||||
const builtin_script_t &script2) {
|
||||
return wcscmp(script1.name, script2.name) < 0;
|
||||
}
|
||||
|
||||
/// Check whether the given command is loaded.
|
||||
bool autoload_t::has_tried_loading(const wcstring &cmd) {
|
||||
scoped_lock locker(lock);
|
||||
|
@ -201,110 +193,78 @@ bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_
|
|||
|
||||
// The source of the script will end up here.
|
||||
wcstring script_source;
|
||||
bool has_script_source = false;
|
||||
|
||||
// Whether we found an accessible file.
|
||||
bool found_file = false;
|
||||
|
||||
// Look for built-in scripts via a binary search.
|
||||
const builtin_script_t *matching_builtin_script = NULL;
|
||||
if (builtin_script_count > 0) {
|
||||
const builtin_script_t test_script = {cmd.c_str(), NULL};
|
||||
const builtin_script_t *array_end = builtin_scripts + builtin_script_count;
|
||||
const builtin_script_t *found = std::lower_bound(builtin_scripts, array_end, test_script,
|
||||
script_name_precedes_script_name);
|
||||
if (found != array_end && !wcscmp(found->name, test_script.name)) {
|
||||
matching_builtin_script = found;
|
||||
}
|
||||
}
|
||||
if (matching_builtin_script) {
|
||||
has_script_source = true;
|
||||
script_source = str2wcstring(matching_builtin_script->def);
|
||||
// Iterate over path searching for suitable completion files.
|
||||
for (size_t i = 0; i < path_list.size() && !found_file; i++) {
|
||||
wcstring next = path_list.at(i);
|
||||
wcstring path = next + L"/" + cmd + L".fish";
|
||||
|
||||
// Make a node representing this function.
|
||||
const file_access_attempt_t access = access_file(path, R_OK);
|
||||
if (!access.accessible) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Now we're actually going to take the lock.
|
||||
scoped_lock locker(lock);
|
||||
autoload_function_t *func = this->get_autoloaded_function_with_creation(cmd, really_load);
|
||||
autoload_function_t *func = this->get(cmd);
|
||||
|
||||
// This function is internalized.
|
||||
func->is_internalized = true;
|
||||
// Generate the source if we need to load it.
|
||||
bool need_to_load_function =
|
||||
really_load &&
|
||||
(func == NULL || func->access.mod_time != access.mod_time || !func->is_loaded);
|
||||
if (need_to_load_function) {
|
||||
// Generate the script source.
|
||||
script_source = L"source " + escape_string(path, ESCAPE_ALL);
|
||||
|
||||
// It's a fiction to say the script is loaded at this point, but we're definitely going to
|
||||
// load it down below.
|
||||
if (really_load) func->is_loaded = true;
|
||||
// Remove any loaded command because we are going to reload it. Note that this
|
||||
// will deadlock if command_removed calls back into us.
|
||||
if (func && func->is_loaded) {
|
||||
command_removed(cmd);
|
||||
func->is_placeholder = false;
|
||||
}
|
||||
|
||||
// Mark that we're reloading it.
|
||||
reloaded = true;
|
||||
}
|
||||
|
||||
// Create the function if we haven't yet. This does not load it. Do not trigger
|
||||
// eviction unless we are actually loading, because we don't want to evict off of
|
||||
// the main thread.
|
||||
if (!func) func = get_autoloaded_function_with_creation(cmd, really_load);
|
||||
|
||||
// It's a fiction to say the script is loaded at this point, but we're definitely
|
||||
// going to load it down below.
|
||||
if (need_to_load_function) func->is_loaded = true;
|
||||
|
||||
// Unconditionally record our access time.
|
||||
func->access = access;
|
||||
found_file = true;
|
||||
}
|
||||
|
||||
if (!has_script_source) {
|
||||
// Iterate over path searching for suitable completion files.
|
||||
for (size_t i = 0; i < path_list.size() && !found_file; i++) {
|
||||
wcstring next = path_list.at(i);
|
||||
wcstring path = next + L"/" + cmd + L".fish";
|
||||
|
||||
const file_access_attempt_t access = access_file(path, R_OK);
|
||||
if (!access.accessible) {
|
||||
continue;
|
||||
// If no file or builtin script was found we insert a placeholder function. Later we only
|
||||
// research if the current time is at least five seconds later. This way, the files won't be
|
||||
// searched over and over again.
|
||||
if (!found_file && script_source.empty()) {
|
||||
scoped_lock locker(lock);
|
||||
// Generate a placeholder.
|
||||
autoload_function_t *func = this->get(cmd);
|
||||
if (!func) {
|
||||
if (really_load) {
|
||||
this->insert(cmd, autoload_function_t(true));
|
||||
} else {
|
||||
this->insert(cmd, autoload_function_t(true));
|
||||
}
|
||||
|
||||
// Now we're actually going to take the lock.
|
||||
scoped_lock locker(lock);
|
||||
autoload_function_t *func = this->get(cmd);
|
||||
|
||||
// Generate the source if we need to load it.
|
||||
bool need_to_load_function =
|
||||
really_load &&
|
||||
(func == NULL || func->access.mod_time != access.mod_time || !func->is_loaded);
|
||||
if (need_to_load_function) {
|
||||
// Generate the script source.
|
||||
wcstring esc = escape_string(path, 1);
|
||||
script_source = L"source " + esc;
|
||||
has_script_source = true;
|
||||
|
||||
// Remove any loaded command because we are going to reload it. Note that this
|
||||
// will deadlock if command_removed calls back into us.
|
||||
if (func && func->is_loaded) {
|
||||
command_removed(cmd);
|
||||
func->is_placeholder = false;
|
||||
}
|
||||
|
||||
// Mark that we're reloading it.
|
||||
reloaded = true;
|
||||
}
|
||||
|
||||
// Create the function if we haven't yet. This does not load it. Do not trigger
|
||||
// eviction unless we are actually loading, because we don't want to evict off of
|
||||
// the main thread.
|
||||
if (!func) func = get_autoloaded_function_with_creation(cmd, really_load);
|
||||
|
||||
// It's a fiction to say the script is loaded at this point, but we're definitely
|
||||
// going to load it down below.
|
||||
if (need_to_load_function) func->is_loaded = true;
|
||||
|
||||
// Unconditionally record our access time.
|
||||
func->access = access;
|
||||
found_file = true;
|
||||
}
|
||||
|
||||
// If no file or builtin script was found we insert a placeholder function. Later we only
|
||||
// research if the current time is at least five seconds later. This way, the files won't be
|
||||
// searched over and over again.
|
||||
if (!found_file && !has_script_source) {
|
||||
scoped_lock locker(lock);
|
||||
// Generate a placeholder.
|
||||
autoload_function_t *func = this->get(cmd);
|
||||
if (!func) {
|
||||
if (really_load) {
|
||||
this->insert(cmd, autoload_function_t(true));
|
||||
} else {
|
||||
this->insert(cmd, autoload_function_t(true));
|
||||
}
|
||||
func = this->get(cmd);
|
||||
assert(func);
|
||||
}
|
||||
func->access.last_checked = time(NULL);
|
||||
func = this->get(cmd);
|
||||
assert(func);
|
||||
}
|
||||
func->access.last_checked = time(NULL);
|
||||
}
|
||||
|
||||
// If we have a script, either built-in or a file source, then run it.
|
||||
if (really_load && has_script_source) {
|
||||
if (really_load && !script_source.empty()) {
|
||||
// Do nothing on failure.
|
||||
exec_subshell(script_source, false /* do not apply exit status */);
|
||||
}
|
||||
|
@ -313,5 +273,5 @@ bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_
|
|||
return reloaded;
|
||||
}
|
||||
|
||||
return found_file || has_script_source;
|
||||
return found_file || !script_source.empty();
|
||||
}
|
||||
|
|
|
@ -40,11 +40,6 @@ struct autoload_function_t {
|
|||
bool is_internalized;
|
||||
};
|
||||
|
||||
struct builtin_script_t {
|
||||
const wchar_t *name;
|
||||
const char *def;
|
||||
};
|
||||
|
||||
class env_vars_snapshot_t;
|
||||
|
||||
/// Class representing a path from which we can autoload and the autoloaded contents.
|
||||
|
@ -54,10 +49,6 @@ class autoload_t : public lru_cache_t<autoload_t, autoload_function_t> {
|
|||
pthread_mutex_t lock;
|
||||
/// The environment variable name.
|
||||
const wcstring env_var_name;
|
||||
/// Builtin script array.
|
||||
const struct builtin_script_t *const builtin_scripts;
|
||||
/// Builtin script count.
|
||||
const size_t builtin_script_count;
|
||||
/// The path from which we most recently autoloaded.
|
||||
wcstring last_path;
|
||||
/// the most reecently autoloaded path, tokenized (split on separators).
|
||||
|
@ -83,9 +74,7 @@ class autoload_t : public lru_cache_t<autoload_t, autoload_function_t> {
|
|||
|
||||
// Create an autoload_t for the given environment variable name.
|
||||
autoload_t(const wcstring &env_var_name_var,
|
||||
command_removed_function_t callback,
|
||||
const builtin_script_t *scripts = NULL,
|
||||
size_t script_count = 0);
|
||||
command_removed_function_t callback);
|
||||
|
||||
~autoload_t();
|
||||
|
||||
|
|
Loading…
Reference in a new issue