emacs-diffs
[Top][All Lists]
Advanced

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

master 2bac9d4693 3/3: Handle request serial wraparound more correctly


From: Po Lu
Subject: master 2bac9d4693 3/3: Handle request serial wraparound more correctly
Date: Sat, 12 Nov 2022 06:01:42 -0500 (EST)

branch: master
commit 2bac9d469398c0453e8026430e0f84a74a7b602f
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Handle request serial wraparound more correctly
    
    * src/xterm.c (X_COMPARE_SERIALS): Remove macro.
    (x_is_serial_more_than, x_is_serial_more_than_or_equal_to)
    (x_is_serial_less_than, x_is_serial_less_than_or_equal_to): New
    functions.
    (x_find_error_handler, x_request_can_fail)
    (x_clean_failable_requests, x_stop_ignoring_errors): Use those
    functions to perform request serial comparison.
---
 src/xterm.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 53 insertions(+), 17 deletions(-)

diff --git a/src/xterm.c b/src/xterm.c
index b1e74199d7..e50f669e67 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -912,11 +912,6 @@ struct x_selection_request_event
 
 struct x_selection_request_event *pending_selection_requests;
 
-/* Compare two request serials A and B with OP, handling
-   wraparound.  */
-#define X_COMPARE_SERIALS(a, op ,b) \
-  (((long) (a) - (long) (b)) op 0)
-
 struct x_atom_ref
 {
   /* Atom name.  */
@@ -25084,6 +25079,48 @@ static struct x_error_message_stack *x_error_message;
 /* The amount of items (depth) in that stack.  */
 int x_error_message_count;
 
+/* Compare various request serials while handling wraparound.  Treat a
+   difference of more than X_ULONG_MAX / 2 as wraparound.
+
+   Note that these functions truncate serials to 32 bits before
+   comparison.  */
+
+static bool
+x_is_serial_more_than (unsigned int a, unsigned int b)
+{
+  if (a > b)
+    return true;
+
+  return (b - a > X_ULONG_MAX / 2);
+}
+
+static bool
+x_is_serial_more_than_or_equal_to (unsigned int a, unsigned int b)
+{
+  if (a >= b)
+    return true;
+
+  return (b - a > X_ULONG_MAX / 2);
+}
+
+static bool
+x_is_serial_less_than (unsigned int a, unsigned int b)
+{
+  if (a < b)
+    return true;
+
+  return (a - b > X_ULONG_MAX / 2);
+}
+
+static bool
+x_is_serial_less_than_or_equal_to (unsigned int a, unsigned int b)
+{
+  if (a <= b)
+    return true;
+
+  return (a - b > X_ULONG_MAX / 2);
+}
+
 static struct x_error_message_stack *
 x_find_error_handler (Display *dpy, XErrorEvent *event)
 {
@@ -25093,8 +25130,8 @@ x_find_error_handler (Display *dpy, XErrorEvent *event)
 
   while (stack)
     {
-      if (X_COMPARE_SERIALS (event->serial, >=,
-                            stack->first_request)
+      if (x_is_serial_more_than_or_equal_to (event->serial,
+                                            stack->first_request)
          && dpy == stack->dpy)
        return stack;
 
@@ -25197,11 +25234,11 @@ x_request_can_fail (struct x_display_info *dpyinfo,
        failable_requests < dpyinfo->next_failable_request;
        failable_requests++)
     {
-      if (X_COMPARE_SERIALS (request, >=,
-                            failable_requests->start)
+      if (x_is_serial_more_than_or_equal_to (request,
+                                            failable_requests->start)
          && (!failable_requests->end
-             || X_COMPARE_SERIALS (request, <=,
-                                   failable_requests->end)))
+             || x_is_serial_less_than_or_equal_to (request,
+                                                   failable_requests->end)))
        return failable_requests;
     }
 
@@ -25219,11 +25256,11 @@ x_clean_failable_requests (struct x_display_info 
*dpyinfo)
 
   for (first = dpyinfo->failable_requests; first < last; first++)
     {
-      if (X_COMPARE_SERIALS (first->start, >,
-                            LastKnownRequestProcessed (dpyinfo->display))
+      if (x_is_serial_more_than (first->start,
+                                LastKnownRequestProcessed (dpyinfo->display))
          || !first->end
-         || X_COMPARE_SERIALS (first->end, >,
-                               LastKnownRequestProcessed (dpyinfo->display)))
+         || x_is_serial_more_than (first->end,
+                                   LastKnownRequestProcessed 
(dpyinfo->display)))
        break;
     }
 
@@ -25302,8 +25339,7 @@ x_stop_ignoring_errors (struct x_display_info *dpyinfo)
   /* Abort if no request was made since
      `x_ignore_errors_for_next_request'.  */
 
-  if (X_COMPARE_SERIALS (range->end, <,
-                        range->start))
+  if (x_is_serial_less_than (range->end, range->start))
     emacs_abort ();
 
 #ifdef HAVE_GTK3



reply via email to

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