> > For example, we might happen to call from govim -> Vim while Vim is in the 
> > middle of handling a listener_add callback that itself calls ch_evalexpr 
> > which results in a call Vim ->govim.
>
> Can this actually happen?  Is this considered a "safe" situation then?

Yes I think it can. See below for an example.

> I assume adding a zero tick timer wouldn't help there because vim could just 
> schedule the timer callback within the listener callback.

I think you're right. The timer-based solution was something of a stab
in the dark. However, trying it and this discussion has, I think,
brought me to the "right" answer.

Consider the following example (requires Go to be installed):
https://gist.github.com/myitcv/8a55f106a604584164d50e82a31d28ef

    vi -u slow_function.vim

Then:

    :call MyFunc()

The sequence here (which you can see from Vim screen,
/tmp/vim_channel.log and /tmp/slow_job.log) is as follows:

* the channel is established between Vim and slow_job.go
* we call MyFunc()
* MyFunc calls ch_evalexpr which is blocking; MyFunc does not, at this
point, return therefore
* slow_job.go receives the message from Vim's ch_evalexpr call:

{'Comment':'hello from Vim', 'Delay': '10s', 'Calls':[['ex', 'echom
"Hello from govim"']]}

* slow_job.go does some logging, then it makes the calls requested in
the message
* slow_job.go calls back into Vim with the channel command: ['ex',
'echom "Hello from govim"']
* Vim shows this message, but note MyFunc is still blocked on
ch_evalexpr (and hence so is the user)
* slow_job.go then sleeps for the requested 10s
* slow_job.go then returns, which allows ch_evalexpr to return, which
allows MyFunc() to return, at which point the user can continue

The above example is slightly contrived, because the ex call from
slow_job.go into Vim happens whilst Vim is blocked executing the
remote MyJob() function.

Things can go wrong when the call from govim (i.e. in place of
slow_job.go) to Vim happens at any random time (and they do happen at
random times). Because sometimes it's the case that Vim is in the
middle of something where we then get a "cannot do this here" error in
response to the call from govim -> Vim. I think the canonical example
here is when Vim is in the middle of a listener_add callback, but a) I
might be wrong on this and b) there could be other cases. We see the
classic race condition of "govim starts to call Vim just as Vim starts
to call govim" regularly.

The answer here is I think to keep track on the Vim side (in the govim
VimScript shim) of the number of active ch_evalexpr calls. Instead of
scheduling with a timer_start as I previously suggested, we could do
the following:

* if a "sensitive" call from govim -> Vim comes in and there are no
active ch_evalexpr calls from Vim -> govim, then handle immediately
* if, however, there are active ch_evalexpr calls, add the request to
the end of a pending queue
* when the number of active ch_evalexpr calls reaches zero, process
the pending queue in order

We can keep track of all of this from within the govim VimScript shim.

I think we also have a handle on the calls that are "sensitive".

Any thoughts on the above analysis/suggestion?

Thanks

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/CACoUkn46ptnswUQTXfRu%3DhH9TyKwoXmCa7%3DUH4knRw6NK8RENQ%40mail.gmail.com.

Raspunde prin e-mail lui