Skip to content

Commit 417ccd7

Browse files
committed
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.
1 parent 779f2fc commit 417ccd7

3 files changed

Lines changed: 35 additions & 5 deletions

File tree

src/ex_cmds2.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,9 @@ profile_zero(proftime_T *tm)
10901090
static timer_T *first_timer = NULL;
10911091
static int last_timer_id = 0;
10921092

1093+
static timer_T *current_timer = NULL;
1094+
static int free_current_timer = FALSE;
1095+
10931096
/*
10941097
* Insert a timer in the list of timers.
10951098
*/
@@ -1121,8 +1124,13 @@ remove_timer(timer_T *timer)
11211124
static void
11221125
free_timer(timer_T *timer)
11231126
{
1124-
free_callback(timer->tr_callback, timer->tr_partial);
1125-
vim_free(timer);
1127+
if (timer == current_timer)
1128+
free_current_timer = TRUE;
1129+
else
1130+
{
1131+
free_callback(timer->tr_callback, timer->tr_partial);
1132+
vim_free(timer);
1133+
}
11261134
}
11271135

11281136
/*
@@ -1200,18 +1208,23 @@ check_due_timer(void)
12001208
# endif
12011209
if (this_due <= 1)
12021210
{
1203-
remove_timer(timer);
1211+
current_timer = timer;
1212+
free_current_timer = FALSE;
12041213
timer_callback(timer);
1214+
current_timer = NULL;
1215+
12051216
did_one = TRUE;
1206-
if (timer->tr_repeat != 0)
1217+
if (timer->tr_repeat != 0 && !free_current_timer)
12071218
{
12081219
profile_setlimit(timer->tr_interval, &timer->tr_due);
12091220
if (timer->tr_repeat > 0)
12101221
--timer->tr_repeat;
1211-
insert_timer(timer);
12121222
}
12131223
else
1224+
{
12141225
free_timer(timer);
1226+
remove_timer(timer);
1227+
}
12151228
/* the callback may do anything, start all over */
12161229
break;
12171230
}

src/testdir/test_timers.vim

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,19 @@ func Test_paused()
128128
endif
129129
endfunc
130130

131+
func StopMyself(timer)
132+
let g:called += 1
133+
if g:called == 2
134+
call timer_stop(a:timer)
135+
endif
136+
endfunc
137+
138+
func Test_delete_myself()
139+
let g:called = 0
140+
let t = timer_start(10, 'StopMyself', {'repeat': -1})
141+
call WaitFor('g:called == 2')
142+
call assert_equal(2, g:called)
143+
call assert_equal([], timer_info(t))
144+
endfunc
145+
131146
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,8 @@ static char *(features[]) =
763763

764764
static int included_patches[] =
765765
{ /* Add new patch number below this line */
766+
/**/
767+
2304,
766768
/**/
767769
2303,
768770
/**/

0 commit comments

Comments
 (0)