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,
|
autoload_t::autoload_t(const wcstring &env_var_name_var,
|
||||||
command_removed_function_t cmd_removed_callback,
|
command_removed_function_t cmd_removed_callback)
|
||||||
const builtin_script_t *const scripts, size_t script_count)
|
|
||||||
: lock(),
|
: lock(),
|
||||||
env_var_name(env_var_name_var),
|
env_var_name(env_var_name_var),
|
||||||
builtin_scripts(scripts),
|
|
||||||
builtin_script_count(script_count),
|
|
||||||
command_removed(cmd_removed_callback) {
|
command_removed(cmd_removed_callback) {
|
||||||
pthread_mutex_init(&lock, NULL);
|
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);
|
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.
|
/// Check whether the given command is loaded.
|
||||||
bool autoload_t::has_tried_loading(const wcstring &cmd) {
|
bool autoload_t::has_tried_loading(const wcstring &cmd) {
|
||||||
scoped_lock locker(lock);
|
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.
|
// The source of the script will end up here.
|
||||||
wcstring script_source;
|
wcstring script_source;
|
||||||
bool has_script_source = false;
|
|
||||||
|
|
||||||
// Whether we found an accessible file.
|
// Whether we found an accessible file.
|
||||||
bool found_file = false;
|
bool found_file = false;
|
||||||
|
|
||||||
// Look for built-in scripts via a binary search.
|
// Iterate over path searching for suitable completion files.
|
||||||
const builtin_script_t *matching_builtin_script = NULL;
|
for (size_t i = 0; i < path_list.size() && !found_file; i++) {
|
||||||
if (builtin_script_count > 0) {
|
wcstring next = path_list.at(i);
|
||||||
const builtin_script_t test_script = {cmd.c_str(), NULL};
|
wcstring path = next + L"/" + cmd + L".fish";
|
||||||
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);
|
|
||||||
|
|
||||||
// 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);
|
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.
|
// Generate the source if we need to load it.
|
||||||
func->is_internalized = true;
|
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
|
// Remove any loaded command because we are going to reload it. Note that this
|
||||||
// load it down below.
|
// will deadlock if command_removed calls back into us.
|
||||||
if (really_load) func->is_loaded = true;
|
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) {
|
// If no file or builtin script was found we insert a placeholder function. Later we only
|
||||||
// Iterate over path searching for suitable completion files.
|
// research if the current time is at least five seconds later. This way, the files won't be
|
||||||
for (size_t i = 0; i < path_list.size() && !found_file; i++) {
|
// searched over and over again.
|
||||||
wcstring next = path_list.at(i);
|
if (!found_file && script_source.empty()) {
|
||||||
wcstring path = next + L"/" + cmd + L".fish";
|
scoped_lock locker(lock);
|
||||||
|
// Generate a placeholder.
|
||||||
const file_access_attempt_t access = access_file(path, R_OK);
|
autoload_function_t *func = this->get(cmd);
|
||||||
if (!access.accessible) {
|
if (!func) {
|
||||||
continue;
|
if (really_load) {
|
||||||
|
this->insert(cmd, autoload_function_t(true));
|
||||||
|
} else {
|
||||||
|
this->insert(cmd, autoload_function_t(true));
|
||||||
}
|
}
|
||||||
|
func = this->get(cmd);
|
||||||
// Now we're actually going to take the lock.
|
assert(func);
|
||||||
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->access.last_checked = time(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a script, either built-in or a file source, then run it.
|
// 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.
|
// Do nothing on failure.
|
||||||
exec_subshell(script_source, false /* do not apply exit status */);
|
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 reloaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
return found_file || has_script_source;
|
return found_file || !script_source.empty();
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,11 +40,6 @@ struct autoload_function_t {
|
||||||
bool is_internalized;
|
bool is_internalized;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct builtin_script_t {
|
|
||||||
const wchar_t *name;
|
|
||||||
const char *def;
|
|
||||||
};
|
|
||||||
|
|
||||||
class env_vars_snapshot_t;
|
class env_vars_snapshot_t;
|
||||||
|
|
||||||
/// Class representing a path from which we can autoload and the autoloaded contents.
|
/// 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;
|
pthread_mutex_t lock;
|
||||||
/// The environment variable name.
|
/// The environment variable name.
|
||||||
const wcstring env_var_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.
|
/// The path from which we most recently autoloaded.
|
||||||
wcstring last_path;
|
wcstring last_path;
|
||||||
/// the most reecently autoloaded path, tokenized (split on separators).
|
/// 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.
|
// Create an autoload_t for the given environment variable name.
|
||||||
autoload_t(const wcstring &env_var_name_var,
|
autoload_t(const wcstring &env_var_name_var,
|
||||||
command_removed_function_t callback,
|
command_removed_function_t callback);
|
||||||
const builtin_script_t *scripts = NULL,
|
|
||||||
size_t script_count = 0);
|
|
||||||
|
|
||||||
~autoload_t();
|
~autoload_t();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue