diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-09-01 21:26:20 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-09-01 21:26:20 +0200 |
commit | 417ccd7138d4d230d328de8b0d3892dd82ff1bee (patch) | |
tree | 9dbbb0b04dd9a3eba03b1d949348d1616b878aef /src | |
parent | 779f2fc3a7468e273897d2fd0672315812a2e3da (diff) | |
download | vim-git-417ccd7138d4d230d328de8b0d3892dd82ff1bee.tar.gz |
patch 7.4.2304v7.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.
Diffstat (limited to 'src')
-rw-r--r-- | src/ex_cmds2.c | 23 | ||||
-rw-r--r-- | src/testdir/test_timers.vim | 15 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 35 insertions, 5 deletions
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c index 85513af29..a76b05522 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -1090,6 +1090,9 @@ profile_zero(proftime_T *tm) static timer_T *first_timer = NULL; 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. */ @@ -1121,8 +1124,13 @@ remove_timer(timer_T *timer) static void free_timer(timer_T *timer) { - free_callback(timer->tr_callback, timer->tr_partial); - vim_free(timer); + if (timer == current_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 if (this_due <= 1) { - remove_timer(timer); + current_timer = timer; + free_current_timer = FALSE; timer_callback(timer); + current_timer = NULL; + did_one = TRUE; - if (timer->tr_repeat != 0) + if (timer->tr_repeat != 0 && !free_current_timer) { profile_setlimit(timer->tr_interval, &timer->tr_due); if (timer->tr_repeat > 0) --timer->tr_repeat; - insert_timer(timer); } else + { free_timer(timer); + remove_timer(timer); + } /* the callback may do anything, start all over */ break; } diff --git a/src/testdir/test_timers.vim b/src/testdir/test_timers.vim index 152f72502..e6e54a4cb 100644 --- a/src/testdir/test_timers.vim +++ b/src/testdir/test_timers.vim @@ -128,4 +128,19 @@ func Test_paused() endif 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 diff --git a/src/version.c b/src/version.c index edee28a67..b0ee536bd 100644 --- a/src/version.c +++ b/src/version.c @@ -764,6 +764,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2304, +/**/ 2303, /**/ 2302, |