0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

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.
This commit is contained in:
Bram Moolenaar
2016-09-01 21:26:20 +02:00
parent 779f2fc3a7
commit 417ccd7138
3 changed files with 35 additions and 5 deletions

View File

@@ -1090,6 +1090,9 @@ profile_zero(proftime_T *tm)
static timer_T *first_timer = NULL; static timer_T *first_timer = NULL;
static int last_timer_id = 0; static int last_timer_id = 0;
static timer_T *current_timer = NULL;
static int free_current_timer = FALSE;
/* /*
* Insert a timer in the list of timers. * Insert a timer in the list of timers.
*/ */
@@ -1121,8 +1124,13 @@ remove_timer(timer_T *timer)
static void static void
free_timer(timer_T *timer) free_timer(timer_T *timer)
{ {
free_callback(timer->tr_callback, timer->tr_partial); if (timer == current_timer)
vim_free(timer); free_current_timer = TRUE;
else
{
free_callback(timer->tr_callback, timer->tr_partial);
vim_free(timer);
}
} }
/* /*
@@ -1200,18 +1208,23 @@ check_due_timer(void)
# endif # endif
if (this_due <= 1) if (this_due <= 1)
{ {
remove_timer(timer); current_timer = timer;
free_current_timer = FALSE;
timer_callback(timer); timer_callback(timer);
current_timer = NULL;
did_one = TRUE; did_one = TRUE;
if (timer->tr_repeat != 0) if (timer->tr_repeat != 0 && !free_current_timer)
{ {
profile_setlimit(timer->tr_interval, &timer->tr_due); profile_setlimit(timer->tr_interval, &timer->tr_due);
if (timer->tr_repeat > 0) if (timer->tr_repeat > 0)
--timer->tr_repeat; --timer->tr_repeat;
insert_timer(timer);
} }
else else
{
free_timer(timer); free_timer(timer);
remove_timer(timer);
}
/* the callback may do anything, start all over */ /* the callback may do anything, start all over */
break; break;
} }

View File

@@ -128,4 +128,19 @@ func Test_paused()
endif endif
endfunc endfunc
func StopMyself(timer)
let g:called += 1
if g:called == 2
call timer_stop(a:timer)
endif
endfunc
func Test_delete_myself()
let g:called = 0
let t = timer_start(10, 'StopMyself', {'repeat': -1})
call WaitFor('g:called == 2')
call assert_equal(2, g:called)
call assert_equal([], timer_info(t))
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@@ -763,6 +763,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
2304,
/**/ /**/
2303, 2303,
/**/ /**/