summaryrefslogtreecommitdiff
path: root/src/w32font.c
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2017-02-23 18:15:05 +0200
committerEli Zaretskii <eliz@gnu.org>2017-02-23 18:15:05 +0200
commit5114b3a2047a9bcdb72fddf35e70201c16eb39a3 (patch)
treeee886ff5771ec6ae69c15a317f19741be31a7fab /src/w32font.c
parent4381015bd13c51cd47aad34bed82f40485d774d3 (diff)
downloademacs-5114b3a2047a9bcdb72fddf35e70201c16eb39a3.tar.gz
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)
Diffstat (limited to 'src/w32font.c')
-rw-r--r--src/w32font.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/w32font.c b/src/w32font.c
index eff1a78937a..37df1bc43c0 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