diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-11-28 20:34:52 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-11-28 20:34:52 +0000 |
commit | 84497cd06f06516f6ce727ea00c47792ce16dc70 (patch) | |
tree | 5cba204eafbd2506cc306d610f646f23d65a2d9b /src | |
parent | f86490ed4fdab213a28f667abd055c023a73d645 (diff) |
patch 9.0.0967: leaking memory from autocmd windowsv9.0.0967
Problem: Leaking memory from autocmd windows.
Solution: Free window when auc_win is not NULL.
Diffstat (limited to 'src')
-rw-r--r-- | src/autocmd.c | 17 | ||||
-rw-r--r-- | src/eval.c | 3 | ||||
-rw-r--r-- | src/globals.h | 5 | ||||
-rw-r--r-- | src/quickfix.c | 6 | ||||
-rw-r--r-- | src/screen.c | 4 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/window.c | 4 |
7 files changed, 21 insertions, 20 deletions
diff --git a/src/autocmd.c b/src/autocmd.c index 3a08128133..aca990cb51 100644 --- a/src/autocmd.c +++ b/src/autocmd.c @@ -653,12 +653,7 @@ free_all_autocmds(void) } ga_clear(&augroups); - 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 @@ -1553,12 +1548,11 @@ aucmd_prepbuf( for (auc_idx = 0; auc_idx < AUCMD_WIN_COUNT; ++auc_idx) 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) - { - aucmd_win[auc_idx].auc_win = auc_win; aucmd_win[auc_idx].auc_win_used = TRUE; - } break; } @@ -1667,6 +1661,9 @@ win_found: // Remove the window and frame from the tree of frames. (void)winframe_remove(curwin, &dummy, 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; last_status(FALSE); // may need to remove last status line diff --git a/src/eval.c b/src/eval.c index c43158a29a..20883d4309 100644 --- a/src/eval.c +++ b/src/eval.c @@ -5084,8 +5084,9 @@ garbage_collect(int testing) FOR_ALL_TAB_WINDOWS(tp, wp) abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID, NULL, NULL); + // 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) abort = abort || set_ref_in_item( &aucmd_win[i].auc_win->w_winvar.di_tv, copyID, NULL, NULL); #ifdef FEAT_PROP_POPUP diff --git a/src/globals.h b/src/globals.h index eadff43c99..e69856801e 100644 --- a/src/globals.h +++ b/src/globals.h @@ -984,8 +984,9 @@ EXTERN win_T *curwin; // currently active window #define 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. + int auc_win_used; // This auc_win is being used. } aucmdwin_T; EXTERN aucmdwin_T aucmd_win[AUCMD_WIN_COUNT]; diff --git a/src/quickfix.c b/src/quickfix.c index e8716d2680..4c414e0ad9 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -6639,10 +6639,10 @@ load_dummy_buffer( // restore curwin/curbuf and a few other things aucmd_restbuf(&aco); - } - if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe)) - wipe_buffer(newbuf_to_wipe.br_buf, FALSE); + if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe)) + wipe_buffer(newbuf_to_wipe.br_buf, FALSE); + } // Add back the "dummy" flag, otherwise buflist_findname_stat() won't // skip it. diff --git a/src/screen.c b/src/screen.c index 3bf15d6c85..c5c6a7ac97 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2439,7 +2439,7 @@ retry: FOR_ALL_TAB_WINDOWS(tp, wp) win_free_lsize(wp); 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); #ifdef FEAT_PROP_POPUP // global popup windows @@ -2484,7 +2484,7 @@ retry: } } 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 && win_alloc_lines(aucmd_win[i].auc_win) == FAIL) { diff --git a/src/version.c b/src/version.c index 240def4532..395bb2ad73 100644 --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 967, +/**/ 966, /**/ 965, diff --git a/src/window.c b/src/window.c index 24f25d65b7..9a49cad8d1 100644 --- a/src/window.c +++ b/src/window.c @@ -3293,10 +3293,10 @@ win_free_all(void) tabpage_close(TRUE); 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); - aucmd_win[i].auc_win_used = FALSE; + aucmd_win[i].auc_win = NULL; } while (firstwin != NULL) |