summaryrefslogtreecommitdiff
path: root/src/evalfunc.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-09-05 22:45:28 +0200
committerBram Moolenaar <Bram@vim.org>2016-09-05 22:45:28 +0200
commit75537a93e985ef32e6c267b06ce93629855dd983 (patch)
tree80759514ecc4498257f04f3d23e82d8be31b8e6d /src/evalfunc.c
parent33a80eeb859a78ba93432da6fa585786cfd77249 (diff)
downloadvim-git-75537a93e985ef32e6c267b06ce93629855dd983.tar.gz
patch 7.4.2332v7.4.2332
Problem: Crash when stop_timer() is called in a callback of a callback. Vim hangs when the timer callback uses too much time. Solution: Set tr_id to -1 when a timer is to be deleted. Don't keep calling callbacks forever. (Ozaki Kiichi)
Diffstat (limited to 'src/evalfunc.c')
-rw-r--r--src/evalfunc.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 1c1dcf712..906fa39af 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -12398,12 +12398,14 @@ f_timer_pause(typval_T *argvars, typval_T *rettv UNUSED)
static void
f_timer_start(typval_T *argvars, typval_T *rettv)
{
- long msec = (long)get_tv_number(&argvars[0]);
- timer_T *timer;
- int repeat = 0;
- char_u *callback;
- dict_T *dict;
+ long msec = (long)get_tv_number(&argvars[0]);
+ timer_T *timer;
+ int repeat = 0;
+ char_u *callback;
+ dict_T *dict;
+ partial_T *partial;
+ rettv->vval.v_number = -1;
if (check_secure())
return;
if (argvars[2].v_type != VAR_UNKNOWN)
@@ -12418,13 +12420,13 @@ f_timer_start(typval_T *argvars, typval_T *rettv)
repeat = get_dict_number(dict, (char_u *)"repeat");
}
- timer = create_timer(msec, repeat);
- callback = get_callback(&argvars[1], &timer->tr_partial);
+ callback = get_callback(&argvars[1], &partial);
if (callback == NULL)
- {
- stop_timer(timer);
- rettv->vval.v_number = -1;
- }
+ return;
+
+ timer = create_timer(msec, repeat);
+ if (timer == NULL)
+ free_callback(callback, partial);
else
{
if (timer->tr_partial == NULL)
@@ -12432,7 +12434,8 @@ f_timer_start(typval_T *argvars, typval_T *rettv)
else
/* pointer into the partial */
timer->tr_callback = callback;
- rettv->vval.v_number = timer->tr_id;
+ timer->tr_partial = partial;
+ rettv->vval.v_number = (varnumber_T)timer->tr_id;
}
}