long check_due_timer(void);
void stop_timer(timer_T *timer);
int set_ref_in_timer(int copyID);
+int timer_valid(timer_T *timer);
void timer_free_all(void);
void f_timer_info(typval_T *argvars, typval_T *rettv);
void f_timer_pause(typval_T *argvars, typval_T *rettv);
call assert_equal(0, len(info))
endfunc
+def Test_timer_stopall_with_popup()
+ # Create a popup that times out after ten seconds.
+ # Another timer will fire in half a second and close it early after stopping
+ # all timers.
+ var pop = popup_create('Popup', {time: 10000})
+ var tmr = timer_start(500, (_) => {
+ timer_stopall()
+ popup_clear()
+ })
+ sleep 1
+ assert_equal([], timer_info(tmr))
+ assert_equal([], popup_list())
+enddef
+
func Test_timer_paused()
let g:test_is_flaky = 1
let g:val = 0
return abort;
}
+/*
+ * Return TRUE if "timer" exists in the list of timers.
+ */
+ int
+timer_valid(timer_T *timer)
+{
+ if (timer == NULL)
+ return FALSE;
+ for (timer_T *t = first_timer; t != NULL; t = t->tr_next)
+ if (t == timer)
+ return TRUE;
+ return FALSE;
+}
+
# if defined(EXITFREE) || defined(PROTO)
void
timer_free_all()
{
- timer_T *timer;
-
while (first_timer != NULL)
{
- timer = first_timer;
+ timer_T *timer = first_timer;
remove_timer(timer);
free_timer(timer);
}
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 682,
/**/
681,
/**/
close_buffer(win, win->w_buffer, 0, FALSE, FALSE);
}
# if defined(FEAT_TIMERS)
- if (win->w_popup_timer != NULL)
+ // the timer may have been cleared, making the pointer invalid
+ if (timer_valid(win->w_popup_timer))
stop_timer(win->w_popup_timer);
# endif
vim_free(win->w_frame);