Mercurial > vim
diff src/evalfunc.c @ 10122:3db463d4df25 v7.4.2332
commit https://github.com/vim/vim/commit/75537a93e985ef32e6c267b06ce93629855dd983
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Sep 5 22:45:28 2016 +0200
patch 7.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)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Mon, 05 Sep 2016 23:00:07 +0200 |
parents | a6068b90c873 |
children | 776d0aef1d80 |
line wrap: on
line diff
--- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -12398,12 +12398,14 @@ f_timer_pause(typval_T *argvars, typval_ 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_ 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_ 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; } }