[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master af152ffab1: Don't freeze if the compositing manager crashes
From: |
Po Lu |
Subject: |
master af152ffab1: Don't freeze if the compositing manager crashes |
Date: |
Fri, 29 Jul 2022 21:42:24 -0400 (EDT) |
branch: master
commit af152ffab15174838f11075248353ce66ace1635
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Don't freeze if the compositing manager crashes
* src/xterm.c (x_if_event): New function, like XIfEvent but with
a timeout.
(x_sync_wait_for_frame_drawn_event): Disable frame
synchronization if x_if_event times out after 1 second.
---
src/xterm.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 59 insertions(+), 2 deletions(-)
diff --git a/src/xterm.c b/src/xterm.c
index 60eab0f9b0..9f8afa61cf 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -6597,6 +6597,55 @@ x_set_frame_alpha (struct frame *f)
***********************************************************************/
#if defined HAVE_XSYNC && !defined USE_GTK
+
+/* Wait for an event matching PREDICATE to show up in the event
+ queue, or TIMEOUT to elapse.
+
+ If TIMEOUT passes without an event being found, return 1.
+ Otherwise, return 0 and behave as XIfEvent would. */
+
+static int
+x_if_event (Display *dpy, XEvent *event_return,
+ Bool (*predicate) (Display *, XEvent *, XPointer),
+ XPointer arg, struct timespec timeout)
+{
+ struct timespec current_time, target;
+ int fd;
+ fd_set fds;
+
+ fd = ConnectionNumber (dpy);
+ current_time = current_timespec ();
+ target = timespec_add (current_time, timeout);
+
+ while (true)
+ {
+ /* Get events into the queue. */
+ XSync (dpy, False);
+
+ /* Check if an event is now in the queue. */
+ if (XCheckIfEvent (dpy, event_return, predicate, arg))
+ return 0;
+
+ /* Calculate the timeout. */
+ current_time = current_timespec ();
+ timeout = timespec_sub (target, current_time);
+
+ /* If not, wait for some input to show up on the X connection,
+ or for the timeout to elapse. */
+ FD_ZERO (&fds);
+ FD_SET (fd, &fds);
+
+ /* If this fails due to an IO error, XSync will call the IO
+ error handler. */
+ pselect (fd + 1, &fds, NULL, NULL, &timeout, NULL);
+
+ /* Timeout elapsed. */
+ current_time = current_timespec ();
+ if (timespec_cmp (target, current_time) < 0)
+ return 1;
+ }
+}
+
static Bool
x_sync_is_frame_drawn_event (Display *dpy, XEvent *event,
XPointer user_data)
@@ -6632,8 +6681,16 @@ x_sync_wait_for_frame_drawn_event (struct frame *f)
return;
/* Wait for the frame drawn message to arrive. */
- XIfEvent (FRAME_X_DISPLAY (f), &event,
- x_sync_is_frame_drawn_event, (XPointer) f);
+ if (x_if_event (FRAME_X_DISPLAY (f), &event,
+ x_sync_is_frame_drawn_event, (XPointer) f,
+ make_timespec (1, 0)))
+ {
+ /* TODO: display this warning in the echo area. */
+ fprintf (stderr, "Warning: compositing manager spent more than 1 second "
+ "drawing a frame. Frame synchronization has been disabled\n");
+ FRAME_X_OUTPUT (f)->use_vsync_p = false;
+ }
+
FRAME_X_WAITING_FOR_DRAW (f) = false;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master af152ffab1: Don't freeze if the compositing manager crashes,
Po Lu <=