emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 5114b3a: Avoid quitting inside a critical section o


From: Eli Zaretskii
Subject: [Emacs-diffs] master 5114b3a: Avoid quitting inside a critical section on MS-Windows
Date: Thu, 23 Feb 2017 11:16:55 -0500 (EST)

branch: master
commit 5114b3a2047a9bcdb72fddf35e70201c16eb39a3
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    Avoid quitting inside a critical section on MS-Windows
    
    * src/w32uniscribe.c (uniscribe_list_family):
    * src/w32font.c (w32font_list_family, w32font_text_extents)
    (w32font_list_internal, w32font_match_internal)
    (list_all_matching_fonts): Prevent quitting while these functions
    cons lists of fonts, to avoid leaving the critical section taken
    by the main thread, which will then cause any other thread
    attempting to enter the critical section to hang.  (Bug#25279)
---
 src/w32font.c      | 44 ++++++++++++++++++++++++++++++++++++++++++++
 src/w32uniscribe.c |  7 +++++++
 2 files changed, 51 insertions(+)

diff --git a/src/w32font.c b/src/w32font.c
index eff1a78..37df1bc 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -285,18 +285,25 @@ static Lisp_Object
 w32font_list_family (struct frame *f)
 {
   Lisp_Object list = Qnil;
+  Lisp_Object prev_quit = Vinhibit_quit;
   LOGFONT font_match_pattern;
   HDC dc;
 
   memset (&font_match_pattern, 0, sizeof (font_match_pattern));
   font_match_pattern.lfCharSet = DEFAULT_CHARSET;
 
+  /* Prevent quitting while EnumFontFamiliesEx runs and conses the
+     list it will return.  That's because get_frame_dc acquires the
+     critical section, so we cannot quit before we release it in
+     release_frame_dc.  */
+  Vinhibit_quit = Qt;
   dc = get_frame_dc (f);
 
   EnumFontFamiliesEx (dc, &font_match_pattern,
                       (FONTENUMPROC) add_font_name_to_list,
                       (LPARAM) &list, 0);
   release_frame_dc (f, dc);
+  Vinhibit_quit = prev_quit;
 
   return list;
 }
@@ -434,6 +441,7 @@ w32font_text_extents (struct font *font, unsigned *code,
   WORD *wcode;
   SIZE size;
   bool first;
+  Lisp_Object prev_quit = Vinhibit_quit;
 
   struct w32font_info *w32_font = (struct w32font_info *) font;
 
@@ -480,6 +488,12 @@ w32font_text_extents (struct font *font, unsigned *code,
                 is updated to pass in a frame.  */
              f = XFRAME (selected_frame);
 
+             /* Prevent quitting while EnumFontFamiliesEx runs and
+                conses the list it will return.  That's because
+                get_frame_dc acquires the critical section, so we
+                cannot quit before we release it in release_frame_dc.  */
+             prev_quit = Vinhibit_quit;
+             Vinhibit_quit = Qt;
              dc = get_frame_dc (f);
              old_font = SelectObject (dc, w32_font->hfont);
            }
@@ -520,6 +534,7 @@ w32font_text_extents (struct font *font, unsigned *code,
          /* Restore state and release DC.  */
          SelectObject (dc, old_font);
          release_frame_dc (f, dc);
+         Vinhibit_quit = prev_quit;
        }
       return;
     }
@@ -556,6 +571,12 @@ w32font_text_extents (struct font *font, unsigned *code,
         frame.  */
       f = XFRAME (selected_frame);
 
+      /* Prevent quitting while EnumFontFamiliesEx runs and conses the
+        list it will return.  That's because get_frame_dc acquires
+        the critical section, so we cannot quit before we release it
+        in release_frame_dc.  */
+      prev_quit = Vinhibit_quit;
+      Vinhibit_quit = Qt;
       dc = get_frame_dc (f);
       old_font = SelectObject (dc, w32_font->hfont);
     }
@@ -586,6 +607,7 @@ w32font_text_extents (struct font *font, unsigned *code,
   /* Restore state and release DC.  */
   SelectObject (dc, old_font);
   release_frame_dc (f, dc);
+  Vinhibit_quit = prev_quit;
 }
 
 /* w32 implementation of draw for font backend.
@@ -812,12 +834,20 @@ w32font_list_internal (struct frame *f, Lisp_Object 
font_spec,
     }
   else
     {
+      Lisp_Object prev_quit = Vinhibit_quit;
+
+      /* Prevent quitting while EnumFontFamiliesEx runs and conses the
+        list it will return.  That's because get_frame_dc acquires
+        the critical section, so we cannot quit before we release it
+        in release_frame_dc.  */
+      Vinhibit_quit = Qt;
       dc = get_frame_dc (f);
 
       EnumFontFamiliesEx (dc, &match_data.pattern,
                           (FONTENUMPROC) add_font_entity_to_list,
                           (LPARAM) &match_data, 0);
       release_frame_dc (f, dc);
+      Vinhibit_quit = prev_quit;
     }
 
   return match_data.list;
@@ -844,12 +874,19 @@ w32font_match_internal (struct frame *f, Lisp_Object 
font_spec,
   if (opentype_only)
     match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
 
+  /* Prevent quitting while EnumFontFamiliesEx runs and conses the
+     list it will return.  That's because get_frame_dc acquires the
+     critical section, so we cannot quit before we release it in
+     release_frame_dc.  */
+  Lisp_Object prev_quit = Vinhibit_quit;
+  Vinhibit_quit = Qt;
   dc = get_frame_dc (f);
 
   EnumFontFamiliesEx (dc, &match_data.pattern,
                       (FONTENUMPROC) add_one_font_entity_to_list,
                       (LPARAM) &match_data, 0);
   release_frame_dc (f, dc);
+  Vinhibit_quit = prev_quit;
 
   return NILP (match_data.list) ? Qnil : XCAR (match_data.list);
 }
@@ -2064,6 +2101,12 @@ list_all_matching_fonts (struct font_callback_data 
*match_data)
   Lisp_Object families = w32font_list_family (XFRAME (match_data->frame));
   struct frame *f = XFRAME (match_data->frame);
 
+  /* Prevent quitting while EnumFontFamiliesEx runs and conses the
+     list it will return.  That's because get_frame_dc acquires the
+     critical section, so we cannot quit before we release it in
+     release_frame_dc.  */
+  Lisp_Object prev_quit = Vinhibit_quit;
+  Vinhibit_quit = Qt;
   dc = get_frame_dc (f);
 
   while (!NILP (families))
@@ -2091,6 +2134,7 @@ list_all_matching_fonts (struct font_callback_data 
*match_data)
     }
 
   release_frame_dc (f, dc);
+  Vinhibit_quit = prev_quit;
 }
 
 static Lisp_Object
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c
index 1584d80..e405563 100644
--- a/src/w32uniscribe.c
+++ b/src/w32uniscribe.c
@@ -89,12 +89,19 @@ uniscribe_list_family (struct frame *f)
   /* Limit enumerated fonts to outline fonts to save time.  */
   font_match_pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
 
+  /* Prevent quitting while EnumFontFamiliesEx runs and conses the
+     list it will return.  That's because get_frame_dc acquires the
+     critical section, so we cannot quit before we release it in
+     release_frame_dc.  */
+  Lisp_Object prev_quit = Vinhibit_quit;
+  Vinhibit_quit = Qt;
   dc = get_frame_dc (f);
 
   EnumFontFamiliesEx (dc, &font_match_pattern,
                       (FONTENUMPROC) add_opentype_font_name_to_list,
                       (LPARAM) &list, 0);
   release_frame_dc (f, dc);
+  Vinhibit_quit = prev_quit;
 
   return list;
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]