From 93ae9f46e7947aeb2180e3b8a98b551fa143ba51 Mon Sep 17 00:00:00 2001 From: Martin Rudalics Date: Tue, 16 Jun 2015 15:09:24 +0200 Subject: [PATCH] Fix handling of image cache refcounts. (Bug#20802) This backports Eli Zaretskii's solution of this problem for W32 to X and NS. * src/nsfns.m (image_cache_refcount): Define unconditionally. (unwind_create_frame): If the image cache's reference count hasn't been updated yet, do that now. (Fx_create_frame): Set image_cache_refcount unconditionally. * src/xfns.c (image_cache_refcount): Define unconditionally. (unwind_create_frame): If the image cache's reference count hasn't been updated yet, do that now. (Fx_create_frame, x_create_tip_frame): Set image_cache_refcount unconditionally. * src/w32fns.c (image_cache_refcount): Make it a ptrdiff_t as on X and NS. --- src/nsfns.m | 15 +++++++++++---- src/w32fns.c | 3 ++- src/xfns.c | 17 ++++++++++++++--- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/nsfns.m b/src/nsfns.m index 6a2e2ff14a..286445c003 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -70,9 +70,7 @@ Lisp_Object Fx_open_connection (Lisp_Object, Lisp_Object, Lisp_Object); static Lisp_Object as_script, *as_result; static int as_status; -#ifdef GLYPH_DEBUG static ptrdiff_t image_cache_refcount; -#endif /* ========================================================================== @@ -1005,6 +1003,17 @@ unwind_create_frame (Lisp_Object frame) struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); #endif + /* If the frame's image cache refcount is still the same as our + private shadow variable, it means we are unwinding a frame + for which we didn't yet call init_frame_faces, where the + refcount is incremented. Therefore, we increment it here, so + that free_frame_faces, called in x_free_frame_resources + below, will not mistakenly decrement the counter that was not + incremented yet to account for this new frame. */ + if (FRAME_IMAGE_CACHE (f) != NULL + && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount) + FRAME_IMAGE_CACHE (f)->refcount++; + x_free_frame_resources (f); free_glyphs (f); @@ -1241,10 +1250,8 @@ This function is an internal primitive--use `make-frame' instead. */) x_default_parameter (f, parms, Qright_fringe, Qnil, "rightFringe", "RightFringe", RES_TYPE_NUMBER); -#ifdef GLYPH_DEBUG image_cache_refcount = FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; -#endif init_frame_faces (f); diff --git a/src/w32fns.c b/src/w32fns.c index c247a9b3b3..5f40729011 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -204,7 +204,8 @@ unsigned int msh_mousewheel = 0; static unsigned menu_free_timer = 0; #ifdef GLYPH_DEBUG -static int image_cache_refcount, dpyinfo_refcount; +static ptrdiff_t image_cache_refcount; +static int dpyinfo_refcount; #endif static HWND w32_visible_system_caret_hwnd; diff --git a/src/xfns.c b/src/xfns.c index 634881d0a6..d066043ae5 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -120,8 +120,8 @@ extern LWLIB_ID widget_id_tick; #define MAXREQUEST(dpy) (XMaxRequestSize (dpy)) -#ifdef GLYPH_DEBUG static ptrdiff_t image_cache_refcount; +#ifdef GLYPH_DEBUG static int dpyinfo_refcount; #endif @@ -2828,6 +2828,17 @@ unwind_create_frame (Lisp_Object frame) struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); #endif + /* If the frame's image cache refcount is still the same as our + private shadow variable, it means we are unwinding a frame + for which we didn't yet call init_frame_faces, where the + refcount is incremented. Therefore, we increment it here, so + that free_frame_faces, called in x_free_frame_resources + below, will not mistakenly decrement the counter that was not + incremented yet to account for this new frame. */ + if (FRAME_IMAGE_CACHE (f) != NULL + && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount) + FRAME_IMAGE_CACHE (f)->refcount++; + x_free_frame_resources (f); free_glyphs (f); @@ -3205,9 +3216,9 @@ This function is an internal primitive--use `make-frame' instead. */) "scrollBarBackground", "ScrollBarBackground", false); -#ifdef GLYPH_DEBUG image_cache_refcount = FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; +#ifdef GLYPH_DEBUG dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ @@ -5178,9 +5189,9 @@ x_create_tip_frame (struct x_display_info *dpyinfo, x_default_parameter (f, parms, Qborder_color, build_string ("black"), "borderColor", "BorderColor", RES_TYPE_STRING); -#ifdef GLYPH_DEBUG image_cache_refcount = FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; +#ifdef GLYPH_DEBUG dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ -- 2.39.2