Commit 5114b3a2 authored by Eli Zaretskii's avatar Eli Zaretskii

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)
parent 4381015b
......@@ -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
......
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment