aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-11-29 19:02:29 +0800
committerzeertzjq <zeertzjq@outlook.com>2022-11-29 20:36:31 +0800
commit95f5cf96912727a1ede055211645ac9779f3da44 (patch)
treedd2c01f384b4c3713a1d9c5b976cd7c0f8c91fcd
parent3173d07564e7cdf0834099a379f0faf480c76224 (diff)
downloadrneovim-95f5cf96912727a1ede055211645ac9779f3da44.tar.gz
rneovim-95f5cf96912727a1ede055211645ac9779f3da44.tar.bz2
rneovim-95f5cf96912727a1ede055211645ac9779f3da44.zip
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. https://github.com/vim/vim/commit/84497cd06f06516f6ce727ea00c47792ce16dc70 Co-authored-by: Bram Moolenaar <Bram@vim.org>
-rw-r--r--src/nvim/autocmd.c15
-rw-r--r--src/nvim/eval.c3
-rw-r--r--src/nvim/globals.h5
-rw-r--r--src/nvim/window.c10
4 files changed, 17 insertions, 16 deletions
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index 17dac87013..6efb05ab45 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -665,12 +665,7 @@ void free_all_autocmds(void)
})
map_destroy(int, String)(&map_augroup_id_to_name);
- for (int i = 0; i < AUCMD_WIN_COUNT; ++i) {
- if (aucmd_win[i].auc_win_used) {
- aucmd_win[i].auc_win_used = false;
- win_remove(aucmd_win[i].auc_win, NULL);
- }
- }
+ // aucmd_win[] is freed in win_free_all()
}
#endif
@@ -1418,10 +1413,12 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
if (win == NULL) {
for (auc_idx = 0; auc_idx < AUCMD_WIN_COUNT; auc_idx++) {
if (!aucmd_win[auc_idx].auc_win_used) {
- win_alloc_aucmd_win(auc_idx);
+ if (aucmd_win[auc_idx].auc_win == NULL) {
+ win_alloc_aucmd_win(auc_idx);
+ need_append = false;
+ }
auc_win = aucmd_win[auc_idx].auc_win;
aucmd_win[auc_idx].auc_win_used = true;
- need_append = false;
break;
}
}
@@ -1520,6 +1517,8 @@ win_found:
grid_free(&curwin->w_grid_alloc);
}
+ // 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;
if (!valid_tabpage_win(curtab)) {
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index d316d60efa..c4afd6934c 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -4174,8 +4174,9 @@ bool garbage_collect(bool testing)
ABORTING(set_ref_in_fmark)(wp->w_jumplist[i].fmark, copyID);
}
}
+ // window-local variables in autocmd windows
for (int i = 0; i < AUCMD_WIN_COUNT; i++) {
- if (aucmd_win[i].auc_win_used) {
+ if (aucmd_win[i].auc_win != NULL) {
ABORTING(set_ref_in_item)(&aucmd_win[i].auc_win->w_winvar.di_tv, copyID, NULL, NULL);
}
}
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index feeaae1d7f..9b4ef66b14 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -429,8 +429,9 @@ EXTERN win_T *curwin; // currently active window
enum { AUCMD_WIN_COUNT = 5, };
typedef struct {
- win_T *auc_win; ///< window used in aucmd_prepbuf()
- int auc_win_used; ///< this auc_win is being used
+ win_T *auc_win; ///< Window used in aucmd_prepbuf(). When not NULL the
+ ///< window has been allocated.
+ bool auc_win_used; ///< This auc_win is being used.
} aucmdwin_T;
EXTERN aucmdwin_T aucmd_win[AUCMD_WIN_COUNT];
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 984287cf81..2927855073 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -3092,18 +3092,18 @@ void win_free_all(void)
win_remove(lastwin, NULL);
int dummy;
(void)win_free_mem(wp, &dummy, NULL);
- for (int i = 0; i < AUCMD_WIN_COUNT; ++i) {
+ for (int i = 0; i < AUCMD_WIN_COUNT; i++) {
if (aucmd_win[i].auc_win == wp) {
- aucmd_win[i].auc_win_used = false;
+ aucmd_win[i].auc_win = NULL;
}
}
}
- for (int i = 0; i < AUCMD_WIN_COUNT; ++i) {
- if (aucmd_win[i].auc_win_used) {
+ for (int i = 0; i < AUCMD_WIN_COUNT; i++) {
+ if (aucmd_win[i].auc_win != NULL) {
int dummy;
(void)win_free_mem(aucmd_win[i].auc_win, &dummy, NULL);
- aucmd_win[i].auc_win_used = false;
+ aucmd_win[i].auc_win = NULL;
}
}