On Wed, Jan 15, 2014 at 11:44 AM, Ben Fritz <[email protected]> wrote: > > I thought the idea of this patch, was to allow background threads to send Vim > a message, that says "when you get a chance, run function X". Then, at some > later point in time, when Vim is not busy, it will run function X *IN THE > MAIN THREAD*. Thus there should be no conflict between the deferred function > and the main thread. Am I correct in this? > > If so, plugin authors must simply ensure that function X is threadsafe with > the background functions in the same thread. This probably means making sure > that the background thread is DONE with whatever data function X will access, > until function X can run and is done with that data.
Yes but the main loop can't be frozen waiting for input if its going to handle asynchronous messages from other threads. Thats why plugin authors need to use cursorhold polls to receive updates from other threads or processes. This patch makes a relatively small change to the main_loop function so it will block waiting for arbitrary messages from the queue, where messages can be user input or deferred calls(Though it can easily be extended to handle other types of asynchronous events such as signals). Look at this section of the code: https://github.com/tarruda/vim/blob/event-loop/src/main.c#L1337-L1384 As you can see, the background thread will not call vgetc until its notified by the main thread(the 'input_notify()' call). So even if the main thread is doing something at the time user is typing, the background thread will still be frozen waiting for a signal from the main thread. That means its not possible for that two 'vgetc' calls happen at the time time. To illustrate, consider that at a certain point the main thread is waiting for messages, and the background thread is waiting for input. Now suppose that the following sequence of events happen: - Two chars are entered in a *very* fast sequence. For the sake of argument imagine they were entered at the same time but one after another - The background thread will read a single char with vgetc and the OS buffer will be left with one char. - The background thread will send an 'UserInput' message to the main thread and then will go back to sleep(not to vgetc) - The main thread will put the received char into special variables that will be inspected by vgetc before trying to read input(and so wont block the main thread) - The main thread will invoke normal_cmd as usual(which will itself invoke vgetc), eventually fall back into input_notify() and then block for more messages. - The background thread will wake, call vgetc, read the pending char from the OS buffer and then the process repeats. > On Wednesday, January 15, 2014 4:44:34 AM UTC-6, Ashley Hewson wrote: >> Thiago, >> >> I would love this to work and I thank you for your effort, but I'm quite >> doubtful that vgetc can be safely run in a background thread. It simply does >> too much work. Just to pick one example, it appears to be responsible for >> blinking the GUI cursor while it's waiting, which will obviously conflict >> with any screen updates the main thread is doing. Ashley, its possible that a 'DeferredCall' message arrives while the background thread is in the middle of running 'vgetc'. A DeferredCall will invoke a vimscript function and then will update the screen which might cause the race condition. Thanks for pointing that bug, I could not see it at first. That might be the reason I had to call XInitThreads in the GUI version. One possible fix is to synchronize the call to 'shell_rezise' (which does the screen update) with the call to vgetc from the background thread. When I get the time I will see if that works(If you test it sooner please send me updates). Its perfectly possible that we cant make vim thread safe without refactoring vgetc or other parts of the code. As the title says, the patch was more a proof-of-concept, and my main goal(other than making it thread-safe) was to build interest from the community and touch as little as possible of existing code(see the vungetc hack on the snippet I linked). In any case, I'm glad that you joined me in this "battle" :) Best regard Thiago -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
