timers: make timers work with zero timeout

This commit is contained in:
Björn Linse
2016-06-05 10:49:33 +02:00
parent 204f557a11
commit 2c39e0b03f
2 changed files with 17 additions and 0 deletions

View File

@@ -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)

View File

@@ -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