[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master ef17247: Avoid segfaults due to image cache being c
From: |
Eli Zaretskii |
Subject: |
[Emacs-diffs] master ef17247: Avoid segfaults due to image cache being cleared during redisplay |
Date: |
Mon, 4 Feb 2019 12:44:34 -0500 (EST) |
branch: master
commit ef17247fe9cab2d59e470daad24314c868248b0a
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>
Avoid segfaults due to image cache being cleared during redisplay
* src/xdisp.c (redisplay_internal): Set the
inhibit_clear_image_cache flag of a frame while its windows
are being redisplayed, and reset the flag after the call top
update_frame returns.
* src/image.c (clear_image_cache): Do nothing if the frame's
inhibit_clear_image_cache flag is set. (Bug#34256)
* src/frame.h (struct frame): New flag inhibit_clear_image_cache.
---
src/frame.h | 4 ++++
src/image.c | 2 +-
src/xdisp.c | 15 ++++++++++++++-
3 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/src/frame.h b/src/frame.h
index ab3efdf..b7cbdd9 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -413,6 +413,10 @@ struct frame
/* Non-zero if this frame's faces need to be recomputed. */
bool_bf face_change : 1;
+ /* Non-zero if this frame's image cache cannot be freed because the
+ frame is in the process of being redisplayed. */
+ bool_bf inhibit_clear_image_cache : 1;
+
/* Bitfield area ends here. */
/* This frame's change stamp, set the last time window change
diff --git a/src/image.c b/src/image.c
index 57bbf3c..642bf67 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1554,7 +1554,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
{
struct image_cache *c = FRAME_IMAGE_CACHE (f);
- if (c)
+ if (c && !f->inhibit_clear_image_cache)
{
ptrdiff_t i, nfreed = 0;
diff --git a/src/xdisp.c b/src/xdisp.c
index b5034b5..0bffaeb 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -14431,7 +14431,17 @@ redisplay_internal (void)
FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
- redisplay_windows (FRAME_ROOT_WINDOW (f));
+ {
+
+ /* Don't allow freeing images for this frame as long
+ as the frame's update wasn't completed. This
+ prevents crashes when some Lisp that runs from
+ the various hooks or font-lock decides to clear
+ the frame's image cache, when the images in that
+ cache are referenced by the desired matrix. */
+ f->inhibit_clear_image_cache = true;
+ redisplay_windows (FRAME_ROOT_WINDOW (f));
+ }
/* Remember that the invisible frames need to be redisplayed next
time they're visible. */
else if (!REDISPLAY_SOME_P ())
@@ -14512,6 +14522,7 @@ redisplay_internal (void)
pending |= update_frame (f, false, false);
f->cursor_type_changed = false;
f->updated_p = true;
+ f->inhibit_clear_image_cache = false;
}
}
}
@@ -14539,6 +14550,7 @@ redisplay_internal (void)
}
else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
{
+ sf->inhibit_clear_image_cache = true;
displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
/* Use list_of_error, not Qerror, so that
we catch only errors and don't run the debugger. */
@@ -14594,6 +14606,7 @@ redisplay_internal (void)
XWINDOW (selected_window)->must_be_updated_p = true;
pending = update_frame (sf, false, false);
sf->cursor_type_changed = false;
+ sf->inhibit_clear_image_cache = false;
}
/* We may have called echo_area_display at the top of this
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master ef17247: Avoid segfaults due to image cache being cleared during redisplay,
Eli Zaretskii <=