diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-09-05 22:45:28 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-09-05 22:45:28 +0200 |
commit | 75537a93e985ef32e6c267b06ce93629855dd983 (patch) | |
tree | 80759514ecc4498257f04f3d23e82d8be31b8e6d /src/evalfunc.c | |
parent | 33a80eeb859a78ba93432da6fa585786cfd77249 (diff) | |
download | vim-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.c | 27 |
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; } } |