diff options
author | bfredl <bjorn.linse@gmail.com> | 2023-04-25 13:39:28 +0200 |
---|---|---|
committer | bfredl <bjorn.linse@gmail.com> | 2023-04-25 21:30:19 +0200 |
commit | 5e569a47031d2a5b94cfadd67d5e76ba4651ac4d (patch) | |
tree | 4b60b1ea544dfeee77fa9dbb0c6e899b11347d28 | |
parent | 965ad7726f91c2597ef6eb7a740ae024da99ec9b (diff) | |
download | rneovim-5e569a47031d2a5b94cfadd67d5e76ba4651ac4d.tar.gz rneovim-5e569a47031d2a5b94cfadd67d5e76ba4651ac4d.tar.bz2 rneovim-5e569a47031d2a5b94cfadd67d5e76ba4651ac4d.zip |
refactor(fs): now it is time to get rid of fs_loop and fs_loop_mutex
Here's the headline: when run in sync mode (last argument cb=NULL),
these functions don't actually use the uv_loop_t.
An earlier version of this patch instead replaced fs_loop with
using main_loop.uv on the main thread and luv_loop() on luv worker
threads. However this made the code more complicated for no reason.
Also arbitrarily, half of these functions would attempt to handle
UV_ENOMEM by try_to_free_memory(). This would mostly happen
on windows because it needs to allocate a converted WCHAR buffer.
This should be a quite rare situation. Your system is pretty
much hosed already if you cannot allocate like 50 WCHAR:s.
Therefore, take the liberty of simply removing this fallback.
In addition, we tried to "recover" from ENOMEM in read()/readv()
this way which doesn't make any sense. The read buffer(s) are already
allocated at this point.
This would also be an issue when using these functions on a worker
thread, as try_to_free_memory() is not thread-safe. Currently
os_file_is_readable() and os_is_dir() is used by worker threads
(as part of nvim__get_runtime(), to implement require from 'rtp' in
threads).
In the end, these changes makes _all_ os/fs.c functions thread-safe,
and we thus don't need to document and maintain a thread-safe subset.
-rw-r--r-- | src/nvim/main.c | 6 | ||||
-rw-r--r-- | src/nvim/os/fs.c | 73 | ||||
-rw-r--r-- | test/unit/helpers.lua | 1 |
3 files changed, 10 insertions, 70 deletions
diff --git a/src/nvim/main.c b/src/nvim/main.c index 657f9c67f2..60390c3c60 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -266,10 +266,6 @@ int main(int argc, char **argv) // `argc` and `argv` are also copied, so that they can be changed. init_params(¶ms, argc, argv); - // Since os_open is called during the init_startuptime, we need to call - // fs_init before it. - fs_init(); - init_startuptime(¶ms); // Need to find "--clean" before actually parsing arguments. @@ -1479,7 +1475,7 @@ static void init_startuptime(mparm_T *paramp) { for (int i = 1; i < paramp->argc - 1; i++) { if (STRICMP(paramp->argv[i], "--startuptime") == 0) { - time_fd = os_fopen(paramp->argv[i + 1], "a"); + time_fd = fopen(paramp->argv[i + 1], "a"); time_start("--- NVIM STARTING ---"); break; } diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 872d9c9314..b13afba727 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -20,6 +20,7 @@ #include "nvim/globals.h" #include "nvim/log.h" #include "nvim/macros.h" +#include "nvim/main.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/option_defs.h" @@ -46,44 +47,13 @@ struct iovec; #define RUN_UV_FS_FUNC(ret, func, ...) \ do { \ - bool did_try_to_free = false; \ -uv_call_start: {} \ uv_fs_t req; \ - fs_loop_lock(); \ - ret = func(&fs_loop, &req, __VA_ARGS__); \ + ret = func(NULL, &req, __VA_ARGS__); \ uv_fs_req_cleanup(&req); \ - fs_loop_unlock(); \ - if (ret == UV_ENOMEM && !did_try_to_free) { \ - try_to_free_memory(); \ - did_try_to_free = true; \ - goto uv_call_start; \ - } \ } while (0) // Many fs functions from libuv return that value on success. static const int kLibuvSuccess = 0; -static uv_loop_t fs_loop; -static uv_mutex_t fs_loop_mutex; - -// Initialize the fs module -void fs_init(void) -{ - uv_loop_init(&fs_loop); - uv_mutex_init_recursive(&fs_loop_mutex); -} - -/// TODO(bfredl): some of these operations should -/// be possible to do the private libuv loop of the -/// thread, instead of contending the global fs loop -void fs_loop_lock(void) -{ - uv_mutex_lock(&fs_loop_mutex); -} - -void fs_loop_unlock(void) -{ - uv_mutex_unlock(&fs_loop_mutex); -} /// Changes the current directory to `path`. /// @@ -122,12 +92,9 @@ bool os_isrealdir(const char *name) FUNC_ATTR_NONNULL_ALL { uv_fs_t request; - fs_loop_lock(); - if (uv_fs_lstat(&fs_loop, &request, name, NULL) != kLibuvSuccess) { - fs_loop_unlock(); + if (uv_fs_lstat(NULL, &request, name, NULL) != kLibuvSuccess) { return false; } - fs_loop_unlock(); if (S_ISLNK(request.statbuf.st_mode)) { return false; } @@ -566,7 +533,6 @@ ptrdiff_t os_read(const int fd, bool *const ret_eof, char *const ret_buf, const return 0; } size_t read_bytes = 0; - bool did_try_to_free = false; while (read_bytes != size) { assert(size >= read_bytes); const ptrdiff_t cur_read_bytes = read(fd, ret_buf + read_bytes, @@ -581,10 +547,6 @@ ptrdiff_t os_read(const int fd, bool *const ret_eof, char *const ret_buf, const break; } else if (error == UV_EINTR || error == UV_EAGAIN) { continue; - } else if (error == UV_ENOMEM && !did_try_to_free) { - try_to_free_memory(); - did_try_to_free = true; - continue; } else { return (ptrdiff_t)error; } @@ -618,7 +580,6 @@ ptrdiff_t os_readv(const int fd, bool *const ret_eof, struct iovec *iov, size_t { *ret_eof = false; size_t read_bytes = 0; - bool did_try_to_free = false; size_t toread = 0; for (size_t i = 0; i < iov_size; i++) { // Overflow, trying to read too much data @@ -650,10 +611,6 @@ ptrdiff_t os_readv(const int fd, bool *const ret_eof, struct iovec *iov, size_t break; } else if (error == UV_EINTR || error == UV_EAGAIN) { continue; - } else if (error == UV_ENOMEM && !did_try_to_free) { - try_to_free_memory(); - did_try_to_free = true; - continue; } else { return (ptrdiff_t)error; } @@ -742,9 +699,7 @@ static int os_stat(const char *name, uv_stat_t *statbuf) return UV_EINVAL; } uv_fs_t request; - fs_loop_lock(); - int result = uv_fs_stat(&fs_loop, &request, name, NULL); - fs_loop_unlock(); + int result = uv_fs_stat(NULL, &request, name, NULL); if (result == kLibuvSuccess) { *statbuf = request.statbuf; } @@ -1028,9 +983,7 @@ int os_mkdtemp(const char *templ, char *path) FUNC_ATTR_NONNULL_ALL { uv_fs_t request; - fs_loop_lock(); - int result = uv_fs_mkdtemp(&fs_loop, &request, templ, NULL); - fs_loop_unlock(); + int result = uv_fs_mkdtemp(NULL, &request, templ, NULL); if (result == kLibuvSuccess) { xstrlcpy(path, request.path, TEMP_FILE_PATH_MAXLEN); } @@ -1057,9 +1010,7 @@ int os_rmdir(const char *path) bool os_scandir(Directory *dir, const char *path) FUNC_ATTR_NONNULL_ALL { - fs_loop_lock(); - int r = uv_fs_scandir(&fs_loop, &dir->request, path, 0, NULL); - fs_loop_unlock(); + int r = uv_fs_scandir(NULL, &dir->request, path, 0, NULL); if (r < 0) { os_closedir(dir); } @@ -1120,9 +1071,7 @@ bool os_fileinfo_link(const char *path, FileInfo *file_info) return false; } uv_fs_t request; - fs_loop_lock(); - bool ok = uv_fs_lstat(&fs_loop, &request, path, NULL) == kLibuvSuccess; - fs_loop_unlock(); + bool ok = uv_fs_lstat(NULL, &request, path, NULL) == kLibuvSuccess; if (ok) { file_info->stat = request.statbuf; } @@ -1140,8 +1089,7 @@ bool os_fileinfo_fd(int file_descriptor, FileInfo *file_info) { uv_fs_t request; CLEAR_POINTER(file_info); - fs_loop_lock(); - bool ok = uv_fs_fstat(&fs_loop, + bool ok = uv_fs_fstat(NULL, &request, file_descriptor, NULL) == kLibuvSuccess; @@ -1149,7 +1097,6 @@ bool os_fileinfo_fd(int file_descriptor, FileInfo *file_info) file_info->stat = request.statbuf; } uv_fs_req_cleanup(&request); - fs_loop_unlock(); return ok; } @@ -1266,8 +1213,7 @@ char *os_realpath(const char *name, char *buf) FUNC_ATTR_NONNULL_ARG(1) { uv_fs_t request; - fs_loop_lock(); - int result = uv_fs_realpath(&fs_loop, &request, name, NULL); + int result = uv_fs_realpath(NULL, &request, name, NULL); if (result == kLibuvSuccess) { if (buf == NULL) { buf = xmallocz(MAXPATHL); @@ -1275,7 +1221,6 @@ char *os_realpath(const char *name, char *buf) xstrlcpy(buf, request.ptr, MAXPATHL + 1); } uv_fs_req_cleanup(&request); - fs_loop_unlock(); return result == kLibuvSuccess ? buf : NULL; } diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua index 8fa6378d10..52769cd9e9 100644 --- a/test/unit/helpers.lua +++ b/test/unit/helpers.lua @@ -97,7 +97,6 @@ local init = only_separate(function() for _, c in ipairs(child_calls_init) do c.func(unpack(c.args)) end - libnvim.fs_init() libnvim.event_init() libnvim.early_init(nil) if child_calls_mod then |