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.

Raspunde prin e-mail lui