From 2c39e0b03f083bac569901b62f0058559bacfc63 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 5 Jun 2016 10:49:33 +0200 Subject: timers: make timers work with zero timeout --- src/nvim/eval.c | 10 ++++++++++ test/functional/eval/timer_spec.lua | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index f5cffbc3e1..f45612a886 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -435,6 +435,7 @@ typedef struct { TimeWatcher tw; int timer_id; int repeat_count; + long timeout; bool stopped; ufunc_T *callback; } timer_T; @@ -16655,6 +16656,7 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv) timer = xmalloc(sizeof *timer); timer->stopped = false; timer->repeat_count = repeat; + timer->timeout = timeout; timer->timer_id = last_timer_id++; timer->callback = func; @@ -16709,6 +16711,14 @@ static void timer_due_cb(TimeWatcher *tw, void *data) call_user_func(timer->callback, ARRAY_SIZE(argv), argv, &rettv, curwin->w_cursor.lnum, curwin->w_cursor.lnum, NULL); clear_tv(&rettv); + + if (!timer->stopped && timer->timeout == 0) { + // special case: timeout=0 means the callback will be + // invoked again on the next event loop tick. + // we don't use uv_idle_t to not spin the event loop + // when the main loop is blocked. + time_watcher_start(&timer->tw, timer_due_cb, 0, 0); + } } static void timer_stop(timer_T *timer) diff --git a/test/functional/eval/timer_spec.lua b/test/functional/eval/timer_spec.lua index a31e942cdf..82b965c832 100644 --- a/test/functional/eval/timer_spec.lua +++ b/test/functional/eval/timer_spec.lua @@ -37,6 +37,13 @@ describe('timers', function() eq(2,eval("g:val")) end) + it('works with zero timeout', function() + -- timer_start does still not invoke the callback immediately + eq(0,eval("[timer_start(0, 'MyHandler', {'repeat': 1000}), g:val][1]")) + run(nil, nil, nil, 300) + eq(1000,eval("g:val")) + end) + it('can be started during sleep', function() nvim_async("command", "sleep 10") -- this also tests that remote requests works during sleep -- cgit