forked from aniani/vim
patch 9.0.0361: removing a listener may result in a memory leak
Problem: Removing a listener may result in a memory leak and remove subsequent listerns. Solution: Init the "prev" pointer only once. (Yegappan Lakshmanan, closes #11039)
This commit is contained in:
parent
35d21c6830
commit
956be4678f
@ -362,6 +362,7 @@ invoke_listeners(buf_T *buf)
|
|||||||
int save_updating_screen = updating_screen;
|
int save_updating_screen = updating_screen;
|
||||||
static int recursive = FALSE;
|
static int recursive = FALSE;
|
||||||
listener_T *next;
|
listener_T *next;
|
||||||
|
listener_T *prev;
|
||||||
|
|
||||||
if (buf->b_recorded_changes == NULL // nothing changed
|
if (buf->b_recorded_changes == NULL // nothing changed
|
||||||
|| buf->b_listener == NULL // no listeners
|
|| buf->b_listener == NULL // no listeners
|
||||||
@ -406,10 +407,9 @@ invoke_listeners(buf_T *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If f_listener_remove() was called may have to remove a listener now.
|
// If f_listener_remove() was called may have to remove a listener now.
|
||||||
|
prev = NULL;
|
||||||
for (lnr = buf->b_listener; lnr != NULL; lnr = next)
|
for (lnr = buf->b_listener; lnr != NULL; lnr = next)
|
||||||
{
|
{
|
||||||
listener_T *prev = NULL;
|
|
||||||
|
|
||||||
next = lnr->lr_next;
|
next = lnr->lr_next;
|
||||||
if (lnr->lr_id == 0)
|
if (lnr->lr_id == 0)
|
||||||
remove_listener(buf, lnr, prev);
|
remove_listener(buf, lnr, prev);
|
||||||
|
@ -387,6 +387,37 @@ func Test_remove_listener_in_callback()
|
|||||||
unlet g:listener_called
|
unlet g:listener_called
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" When multiple listeners are registered, remove one listener and verify the
|
||||||
|
" other listener is still called
|
||||||
|
func Test_remove_one_listener_in_callback()
|
||||||
|
new
|
||||||
|
let g:listener1_called = 0
|
||||||
|
let g:listener2_called = 0
|
||||||
|
let s:ID1 = listener_add('Listener1')
|
||||||
|
let s:ID2 = listener_add('Listener2')
|
||||||
|
func Listener1(...)
|
||||||
|
call listener_remove(s:ID1)
|
||||||
|
let g:listener1_called += 1
|
||||||
|
endfunc
|
||||||
|
func Listener2(...)
|
||||||
|
let g:listener2_called += 1
|
||||||
|
endfunc
|
||||||
|
call setline(1, ['foo'])
|
||||||
|
call feedkeys("~", 'xt')
|
||||||
|
call listener_flush()
|
||||||
|
call feedkeys("~", 'xt')
|
||||||
|
call listener_flush()
|
||||||
|
call assert_equal(1, g:listener1_called)
|
||||||
|
call assert_equal(2, g:listener2_called)
|
||||||
|
|
||||||
|
call listener_remove(s:ID2)
|
||||||
|
bwipe!
|
||||||
|
delfunc Listener1
|
||||||
|
delfunc Listener2
|
||||||
|
unlet g:listener1_called
|
||||||
|
unlet g:listener2_called
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_no_change_for_empty_undo()
|
func Test_no_change_for_empty_undo()
|
||||||
new
|
new
|
||||||
let text = ['some word here', 'second line']
|
let text = ['some word here', 'second line']
|
||||||
|
@ -707,6 +707,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 */
|
||||||
|
/**/
|
||||||
|
361,
|
||||||
/**/
|
/**/
|
||||||
360,
|
360,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user