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;
     }
 }