From: Ken Raeburn Date: Wed, 7 Oct 2015 10:04:01 +0000 (-0400) Subject: Introduce x_uncatch_errors_after_check to reduce XSync calls. X-Git-Tag: emacs-25.0.90~1166 X-Git-Url: https://code.delx.au/gnu-emacs/commitdiff_plain/5504ede9518053e619b2cc4bb01ce6eff254d3c8 Introduce x_uncatch_errors_after_check to reduce XSync calls. Both x_had_errors_p and x_check_errors call XSync, so if they're immediately followed by x_uncatch_errors, its XSync call will be redundant, resulting in a wasted round trip to the X server. * src/xterm.c (x_uncatch_errors_after_check): New routine; a copy of x_uncatch_errors without the XSync call. (XTmouse_position, x_wm_supports): * src/xfns.c (x_set_mouse_color): * src/xmenu.c (Fx_menu_bar_open_internal): * src/xselect.c (x_own_selection, x_get_foreign_selection): (Fx_get_atom_name): Call it instead of x_uncatch_errors. * src/xterm.h (x_uncatch_errors_after_check): Declare. --- diff --git a/src/xfns.c b/src/xfns.c index f78e541f74..898359cb8f 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -759,7 +759,7 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval) /* Check and report errors with the above calls. */ x_check_errors (dpy, "can't set cursor shape: %s"); - x_uncatch_errors (); + x_uncatch_errors_after_check (); { XColor fore_color, back_color; diff --git a/src/xmenu.c b/src/xmenu.c index f183c70b11..192ed89e2c 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -325,7 +325,7 @@ If FRAME is nil or not given, use the selected frame. */) /* Child of win. */ &child); error_p = x_had_errors_p (FRAME_X_DISPLAY (f)); - x_uncatch_errors (); + x_uncatch_errors_after_check (); if (! error_p) { diff --git a/src/xselect.c b/src/xselect.c index 9aaa10c6ef..9a7e6974cd 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -316,7 +316,7 @@ x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value, x_catch_errors (display); XSetSelectionOwner (display, selection_atom, selecting_window, timestamp); x_check_errors (display, "Can't set selection: %s"); - x_uncatch_errors (); + x_uncatch_errors_after_check (); unblock_input (); /* Now update the local cache */ @@ -1179,7 +1179,7 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type, XConvertSelection (display, selection_atom, type_atom, target_property, requestor_window, requestor_time); x_check_errors (display, "Can't convert selection: %s"); - x_uncatch_errors (); + x_uncatch_errors_after_check (); /* Prepare to block until the reply has been read. */ reading_selection_window = requestor_window; @@ -2364,7 +2364,7 @@ If the value is 0 or the atom is not known, return the empty string. */) x_catch_errors (dpy); name = atom ? XGetAtomName (dpy, atom) : empty; had_errors_p = x_had_errors_p (dpy); - x_uncatch_errors (); + x_uncatch_errors_after_check (); if (!had_errors_p) ret = build_string (name); diff --git a/src/xterm.c b/src/xterm.c index cd6cdb044c..6e870c5ebb 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -4992,7 +4992,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, if (x_had_errors_p (FRAME_X_DISPLAY (*fp))) f1 = 0; - x_uncatch_errors (); + x_uncatch_errors_after_check (); /* If not, is it one of our scroll bars? */ if (! f1) @@ -9217,7 +9217,10 @@ x_error_catcher (Display *display, XErrorEvent *event) Calling x_check_errors signals an Emacs error if an X error has occurred since the last call to x_catch_errors or x_check_errors. - Calling x_uncatch_errors resumes the normal error handling. */ + Calling x_uncatch_errors resumes the normal error handling. + Calling x_uncatch_errors_after_check is similar, but skips an XSync + to the server, and should be used only immediately after + x_had_errors_p or x_check_errors. */ void x_catch_errors (Display *dpy) @@ -9233,6 +9236,25 @@ x_catch_errors (Display *dpy) x_error_message = data; } +/* Undo the last x_catch_errors call. + DPY should be the display that was passed to x_catch_errors. + + This version should be used only if the immediately preceding + X-protocol-related thing was x_check_errors or x_had_error_p, both + of which issue XSync calls, so we don't need to re-sync here. */ + +void +x_uncatch_errors_after_check (void) +{ + struct x_error_message_stack *tmp; + + block_input (); + tmp = x_error_message; + x_error_message = x_error_message->prev; + xfree (tmp); + unblock_input (); +} + /* Undo the last x_catch_errors call. DPY should be the display that was passed to x_catch_errors. */ @@ -9928,7 +9950,7 @@ x_wm_supports (struct frame *f, Atom want_atom) XSelectInput (dpy, wmcheck_window, StructureNotifyMask); if (x_had_errors_p (dpy)) { - x_uncatch_errors (); + x_uncatch_errors_after_check (); unblock_input (); return false; } diff --git a/src/xterm.h b/src/xterm.h index d8edbc208f..fe3455ff7c 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1030,6 +1030,7 @@ extern void x_check_errors (Display *, const char *) ATTRIBUTE_FORMAT_PRINTF (2, 0); extern bool x_had_errors_p (Display *); extern void x_uncatch_errors (void); +extern void x_uncatch_errors_after_check (void); extern void x_clear_errors (Display *); extern void xembed_request_focus (struct frame *); extern void x_ewmh_activate_frame (struct frame *);