-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
[RFC] Reimplement input functions on top of libuv #395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
||
static void initialize_event_loop() | ||
{ | ||
in_buffer.wpos = in_buffer.rpos = in_buffer.apos = in_buffer.fpos = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in_buffer is already 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it a good practice to be explicit?
I dont have a small test case now, but here's a copy/paste way to reproduce:
When you enter the editor, run the |
static uv_timer_t timer_req; | ||
static uv_handle_type read_stream_type; | ||
static InputBuffer in_buffer; | ||
static bool initialized = false, eof = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initialized
is only used in io_poll
. Can we make it local to io_poll
or
do we need this for later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I was planning to call the initalization function directly from main
. This is just temporary
@stefan991 / @philix how is this branch "looking" on OS X? |
@tarruda The UI looks good, I haven't got any crashes so far, resizing doesn't work (as described in my last comment: #395 (comment)). But there is a problem running the unittests:
The tests abort, but cmake doesn't get that there is an error.
|
@tarruda: found the error, it was introduced with #393. time_init() was not called in the unittests, simple fix:
|
@stefan991 thanks for finding and debugging the issue, do you want to send a PR with the fix? If not I will merge it in this branch. There's also the issue of cmake not detecting the test failure, can you look into this @jszakmeister ? |
@tarruda: I will do a quick pull request :) |
@tarruda Yes, I'll take a look tonight or early in the morning. |
@tarruda I had a few cycles over lunch. I pushed @stefan991's fix and an update to the cmake scripts to notice unit test failures. Sorry about that! |
Now that we can replace |
@oni-link I'm working on it
|
} | ||
|
||
/* Poll the system for user input */ | ||
PollResult io_poll(int32_t ms) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing static
for consistency.
In |
@oni-link I was aware of that. I think that should probably be handled in |
@oni-link |
Don't know if this belongs here, but |
@oni-link I have refactored to normalize(at least for a bit) the different semantics of reading from file descriptors pointing to files. The idea is to use an idle watcher(triggers an 'idle event' when there are no other pending events) to perform the actual reading synchronously. If no one has objections I will squash the commits, and vim "event loop"(where events are only keypresses) is now officially integrated with libuv event loop in a efficient way without multithreading. I was blind by not seeing UV_RUN_ONCE/UV_RUN_NOWAIT as simple a way to integrate vim with libuv, in my mind multithreading was the only possible path. After this we'll finally be able extend vim multitasking capabilities by simply adding libuv event listeners. Plugins, sockets, jobs, signals etc will all be polled by libuv and vim own event loop is only awaken when keys are placed in the read buffer. |
@tarruda With the idle_watcher the file read has the lowest priority. Would that be problematic in the future, when more and more events can be triggered? Or would that be in a different event loop? |
@oni-link I dont think that is a problem. When stdin is redirected from a file I can see two scenarios:
Even if it wasn't the case(if reading from a terminal fed by the user for example), having a low priority would only be a problem if vim is flooded with signals or input from other sources such as plugins, and even like that I doubt the user would notice any delays. |
The functions `mch_inchar`, `mch_breakcheck`, `mch_char_avail` were reimplemented on top of libuv. Here's how it works: - When Neovim needs to wait for characters, it will transfer control to libuv event loop. - When the libuv event loop gets user input, it will transfer control back to Neovim - Neovim uses the `input_read` function to get the actual data read by libuv. With this scheme its possible to keep Neovim single-threaded while enjoying the benefits provided by libuv. This commit leaves SIGWINCH broken for now
Merged, now need to fix signals |
@tarruda you have asked how stable this branch was on the Mac. I've been running I'm glad you divided #289 into smaller, more manageable diffs. |
Functions that interact with
read_cmd_fd
were implemented on top libuv, usinguv_run()
in conjunction withUV_RUN_ONCE
.This the input-related code extracted from #289 work, refactored to use a single thread. This is much simpler than listening for input from a background thread, while also letting us use libuv infrastructure for listening events from multiple sources without the added multithreading complexity. For example, this branch won't have the SIGTTIN problem detected by @oni-link, since there's no background thread reading input when Neovim starts a shell in the foreground.
RFC from @oni-link @mahkoh @philix @saghul @lslah @stefan991