1
0
forked from aniani/vim

patch 9.0.0967: leaking memory from autocmd windows

Problem:    Leaking memory from autocmd windows.
Solution:   Free window when auc_win is not NULL.
This commit is contained in:
Bram Moolenaar
2022-11-28 20:34:52 +00:00
parent f86490ed4f
commit 84497cd06f
7 changed files with 21 additions and 20 deletions

View File

@@ -653,12 +653,7 @@ free_all_autocmds(void)
} }
ga_clear(&augroups); ga_clear(&augroups);
for (int i = 0; i < AUCMD_WIN_COUNT; ++i) // aucmd_win[] is freed in win_free_all()
if (aucmd_win[i].auc_win_used)
{
aucmd_win[i].auc_win_used = FALSE;
win_remove(aucmd_win[i].auc_win, NULL);
}
} }
#endif #endif
@@ -1553,12 +1548,11 @@ aucmd_prepbuf(
for (auc_idx = 0; auc_idx < AUCMD_WIN_COUNT; ++auc_idx) for (auc_idx = 0; auc_idx < AUCMD_WIN_COUNT; ++auc_idx)
if (!aucmd_win[auc_idx].auc_win_used) if (!aucmd_win[auc_idx].auc_win_used)
{ {
auc_win = win_alloc_popup_win(); if (aucmd_win[auc_idx].auc_win == NULL)
aucmd_win[auc_idx].auc_win = win_alloc_popup_win();
auc_win = aucmd_win[auc_idx].auc_win;
if (auc_win != NULL) if (auc_win != NULL)
{
aucmd_win[auc_idx].auc_win = auc_win;
aucmd_win[auc_idx].auc_win_used = TRUE; aucmd_win[auc_idx].auc_win_used = TRUE;
}
break; break;
} }
@@ -1667,6 +1661,9 @@ win_found:
// Remove the window and frame from the tree of frames. // Remove the window and frame from the tree of frames.
(void)winframe_remove(curwin, &dummy, NULL); (void)winframe_remove(curwin, &dummy, NULL);
win_remove(curwin, NULL); win_remove(curwin, NULL);
// The window is marked as not used, but it is not freed, it can be
// used again.
aucmd_win[aco->use_aucmd_win_idx].auc_win_used = FALSE; aucmd_win[aco->use_aucmd_win_idx].auc_win_used = FALSE;
last_status(FALSE); // may need to remove last status line last_status(FALSE); // may need to remove last status line

View File

@@ -5084,8 +5084,9 @@ garbage_collect(int testing)
FOR_ALL_TAB_WINDOWS(tp, wp) FOR_ALL_TAB_WINDOWS(tp, wp)
abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID, abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
NULL, NULL); NULL, NULL);
// window-local variables in autocmd windows
for (int i = 0; i < AUCMD_WIN_COUNT; ++i) for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
if (aucmd_win[i].auc_win_used) if (aucmd_win[i].auc_win != NULL)
abort = abort || set_ref_in_item( abort = abort || set_ref_in_item(
&aucmd_win[i].auc_win->w_winvar.di_tv, copyID, NULL, NULL); &aucmd_win[i].auc_win->w_winvar.di_tv, copyID, NULL, NULL);
#ifdef FEAT_PROP_POPUP #ifdef FEAT_PROP_POPUP

View File

@@ -984,8 +984,9 @@ EXTERN win_T *curwin; // currently active window
#define AUCMD_WIN_COUNT 5 #define AUCMD_WIN_COUNT 5
typedef struct { typedef struct {
win_T *auc_win; // window used in aucmd_prepbuf() win_T *auc_win; // Window used in aucmd_prepbuf(). When not NULL the
int auc_win_used; // this auc_win is being used // window has been allocated.
int auc_win_used; // This auc_win is being used.
} aucmdwin_T; } aucmdwin_T;
EXTERN aucmdwin_T aucmd_win[AUCMD_WIN_COUNT]; EXTERN aucmdwin_T aucmd_win[AUCMD_WIN_COUNT];

View File

@@ -6639,10 +6639,10 @@ load_dummy_buffer(
// restore curwin/curbuf and a few other things // restore curwin/curbuf and a few other things
aucmd_restbuf(&aco); aucmd_restbuf(&aco);
}
if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe)) if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe))
wipe_buffer(newbuf_to_wipe.br_buf, FALSE); wipe_buffer(newbuf_to_wipe.br_buf, FALSE);
}
// Add back the "dummy" flag, otherwise buflist_findname_stat() won't // Add back the "dummy" flag, otherwise buflist_findname_stat() won't
// skip it. // skip it.

View File

@@ -2439,7 +2439,7 @@ retry:
FOR_ALL_TAB_WINDOWS(tp, wp) FOR_ALL_TAB_WINDOWS(tp, wp)
win_free_lsize(wp); win_free_lsize(wp);
for (int i = 0; i < AUCMD_WIN_COUNT; ++i) for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
if (aucmd_win[i].auc_win_used) if (aucmd_win[i].auc_win != NULL)
win_free_lsize(aucmd_win[i].auc_win); win_free_lsize(aucmd_win[i].auc_win);
#ifdef FEAT_PROP_POPUP #ifdef FEAT_PROP_POPUP
// global popup windows // global popup windows
@@ -2484,7 +2484,7 @@ retry:
} }
} }
for (int i = 0; i < AUCMD_WIN_COUNT; ++i) for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
if (aucmd_win[i].auc_win_used if (aucmd_win[i].auc_win != NULL
&& aucmd_win[i].auc_win->w_lines == NULL && aucmd_win[i].auc_win->w_lines == NULL
&& win_alloc_lines(aucmd_win[i].auc_win) == FAIL) && win_alloc_lines(aucmd_win[i].auc_win) == FAIL)
{ {

View File

@@ -695,6 +695,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 */
/**/
967,
/**/ /**/
966, 966,
/**/ /**/

View File

@@ -3293,10 +3293,10 @@ win_free_all(void)
tabpage_close(TRUE); tabpage_close(TRUE);
for (int i = 0; i < AUCMD_WIN_COUNT; ++i) for (int i = 0; i < AUCMD_WIN_COUNT; ++i)
if (aucmd_win[i].auc_win_used) if (aucmd_win[i].auc_win != NULL)
{ {
(void)win_free_mem(aucmd_win[i].auc_win, &dummy, NULL); (void)win_free_mem(aucmd_win[i].auc_win, &dummy, NULL);
aucmd_win[i].auc_win_used = FALSE; aucmd_win[i].auc_win = NULL;
} }
while (firstwin != NULL) while (firstwin != NULL)