mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:8.2.1905: the wininfo list may contain stale entries (#14884)
Problem: The wininfo list may contain stale entries.
Solution: When closing a window remove any other entry where the window
pointer is NULL.
4882d98339
This commit is contained in:
parent
d83bc835b6
commit
8bd6990084
@ -840,11 +840,7 @@ static void clear_wininfo(buf_T *buf)
|
|||||||
while (buf->b_wininfo != NULL) {
|
while (buf->b_wininfo != NULL) {
|
||||||
wip = buf->b_wininfo;
|
wip = buf->b_wininfo;
|
||||||
buf->b_wininfo = wip->wi_next;
|
buf->b_wininfo = wip->wi_next;
|
||||||
if (wip->wi_optset) {
|
free_wininfo(wip, buf);
|
||||||
clear_winopt(&wip->wi_opt);
|
|
||||||
deleteFoldRecurse(buf, &wip->wi_folds);
|
|
||||||
}
|
|
||||||
xfree(wip);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4597,6 +4597,18 @@ static win_T *win_alloc(win_T *after, int hidden)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Free one wininfo_T.
|
||||||
|
void
|
||||||
|
free_wininfo(wininfo_T *wip, buf_T *bp)
|
||||||
|
{
|
||||||
|
if (wip->wi_optset) {
|
||||||
|
clear_winopt(&wip->wi_opt);
|
||||||
|
deleteFoldRecurse(bp, &wip->wi_folds);
|
||||||
|
}
|
||||||
|
xfree(wip);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove window 'wp' from the window list and free the structure.
|
* Remove window 'wp' from the window list and free the structure.
|
||||||
*/
|
*/
|
||||||
@ -4647,10 +4659,31 @@ win_free (
|
|||||||
/* Remove the window from the b_wininfo lists, it may happen that the
|
/* Remove the window from the b_wininfo lists, it may happen that the
|
||||||
* freed memory is re-used for another window. */
|
* freed memory is re-used for another window. */
|
||||||
FOR_ALL_BUFFERS(buf) {
|
FOR_ALL_BUFFERS(buf) {
|
||||||
for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next)
|
for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) {
|
||||||
if (wip->wi_win == wp)
|
if (wip->wi_win == wp) {
|
||||||
|
wininfo_T *wip2;
|
||||||
|
|
||||||
|
// If there already is an entry with "wi_win" set to NULL it
|
||||||
|
// must be removed, it would never be used.
|
||||||
|
for (wip2 = buf->b_wininfo; wip2 != NULL; wip2 = wip2->wi_next) {
|
||||||
|
if (wip2->wi_win == NULL) {
|
||||||
|
if (wip2->wi_next != NULL) {
|
||||||
|
wip2->wi_next->wi_prev = wip2->wi_prev;
|
||||||
|
}
|
||||||
|
if (wip2->wi_prev == NULL) {
|
||||||
|
buf->b_wininfo = wip2->wi_next;
|
||||||
|
} else {
|
||||||
|
wip2->wi_prev->wi_next = wip2->wi_next;
|
||||||
|
}
|
||||||
|
free_wininfo(wip2, buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wip->wi_win = NULL;
|
wip->wi_win = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
clear_matches(wp);
|
clear_matches(wp);
|
||||||
|
|
||||||
|
@ -166,4 +166,36 @@ describe('memory usage', function()
|
|||||||
check_result({before=before, after=after, last=last},
|
check_result({before=before, after=after, last=last},
|
||||||
pcall(ok, last.last < upper))
|
pcall(ok, last.last < upper))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('releases memory when closing windows when folds exist', function()
|
||||||
|
local pid = eval('getpid()')
|
||||||
|
source([[
|
||||||
|
new
|
||||||
|
" Insert lines
|
||||||
|
call nvim_buf_set_lines(0, 0, 0, v:false, repeat([''], 999))
|
||||||
|
" Create folds
|
||||||
|
normal! gg
|
||||||
|
for _ in range(500)
|
||||||
|
normal! zfjj
|
||||||
|
endfor
|
||||||
|
]])
|
||||||
|
poke_eventloop()
|
||||||
|
local before = monitor_memory_usage(pid)
|
||||||
|
source([[
|
||||||
|
" Split and close window multiple times
|
||||||
|
for _ in range(1000)
|
||||||
|
split
|
||||||
|
close
|
||||||
|
endfor
|
||||||
|
]])
|
||||||
|
poke_eventloop()
|
||||||
|
local after = monitor_memory_usage(pid)
|
||||||
|
source('bwipe!')
|
||||||
|
poke_eventloop()
|
||||||
|
-- Allow for an increase of 5% in memory usage, which accommodates minor fluctuation,
|
||||||
|
-- but is small enough that if memory were not released (prior to PR #14884), the test
|
||||||
|
-- would fail.
|
||||||
|
local upper = before.last * 1.05
|
||||||
|
check_result({before=before, after=after}, pcall(ok, after.last <= upper))
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user