comparison src/ex_cmds2.c @ 10066:dc1610dc910f v7.4.2304

commit https://github.com/vim/vim/commit/417ccd7138d4d230d328de8b0d3892dd82ff1bee Author: Bram Moolenaar <Bram@vim.org> Date: Thu Sep 1 21:26:20 2016 +0200 patch 7.4.2304 Problem: In a timer callback the timer itself can't be found or stopped. (Thinca) Solution: Do not remove the timer from the list, remember whether it was freed.
author Christian Brabandt <cb@256bit.org>
date Thu, 01 Sep 2016 21:30:05 +0200
parents 4aead6a9b7a9
children 32bd4001e398
comparison
equal deleted inserted replaced
10065:e22dde82d394 10066:dc1610dc910f
1088 1088
1089 # if defined(FEAT_TIMERS) || defined(PROTO) 1089 # if defined(FEAT_TIMERS) || defined(PROTO)
1090 static timer_T *first_timer = NULL; 1090 static timer_T *first_timer = NULL;
1091 static int last_timer_id = 0; 1091 static int last_timer_id = 0;
1092 1092
1093 static timer_T *current_timer = NULL;
1094 static int free_current_timer = FALSE;
1095
1093 /* 1096 /*
1094 * Insert a timer in the list of timers. 1097 * Insert a timer in the list of timers.
1095 */ 1098 */
1096 static void 1099 static void
1097 insert_timer(timer_T *timer) 1100 insert_timer(timer_T *timer)
1119 } 1122 }
1120 1123
1121 static void 1124 static void
1122 free_timer(timer_T *timer) 1125 free_timer(timer_T *timer)
1123 { 1126 {
1124 free_callback(timer->tr_callback, timer->tr_partial); 1127 if (timer == current_timer)
1125 vim_free(timer); 1128 free_current_timer = TRUE;
1129 else
1130 {
1131 free_callback(timer->tr_callback, timer->tr_partial);
1132 vim_free(timer);
1133 }
1126 } 1134 }
1127 1135
1128 /* 1136 /*
1129 * Create a timer and return it. NULL if out of memory. 1137 * Create a timer and return it. NULL if out of memory.
1130 * Caller should set the callback. 1138 * Caller should set the callback.
1198 this_due = (timer->tr_due.tv_sec - now.tv_sec) * 1000 1206 this_due = (timer->tr_due.tv_sec - now.tv_sec) * 1000
1199 + (timer->tr_due.tv_usec - now.tv_usec) / 1000; 1207 + (timer->tr_due.tv_usec - now.tv_usec) / 1000;
1200 # endif 1208 # endif
1201 if (this_due <= 1) 1209 if (this_due <= 1)
1202 { 1210 {
1203 remove_timer(timer); 1211 current_timer = timer;
1212 free_current_timer = FALSE;
1204 timer_callback(timer); 1213 timer_callback(timer);
1214 current_timer = NULL;
1215
1205 did_one = TRUE; 1216 did_one = TRUE;
1206 if (timer->tr_repeat != 0) 1217 if (timer->tr_repeat != 0 && !free_current_timer)
1207 { 1218 {
1208 profile_setlimit(timer->tr_interval, &timer->tr_due); 1219 profile_setlimit(timer->tr_interval, &timer->tr_due);
1209 if (timer->tr_repeat > 0) 1220 if (timer->tr_repeat > 0)
1210 --timer->tr_repeat; 1221 --timer->tr_repeat;
1211 insert_timer(timer);
1212 } 1222 }
1213 else 1223 else
1224 {
1214 free_timer(timer); 1225 free_timer(timer);
1226 remove_timer(timer);
1227 }
1215 /* the callback may do anything, start all over */ 1228 /* the callback may do anything, start all over */
1216 break; 1229 break;
1217 } 1230 }
1218 if (next_due == -1 || next_due > this_due) 1231 if (next_due == -1 || next_due > this_due)
1219 next_due = this_due; 1232 next_due = this_due;