[mutter/wip/xtoglsync-3-10: 4/4] MetaSyncRing: disable after a number of reboot attempts



commit 78522c99863f37154123d733b6845aa0deb65cb1
Author: Rui Matos <tiagomatos gmail com>
Date:   Tue May 13 12:47:31 2014 +0200

    MetaSyncRing: disable after a number of reboot attempts
    
    If we have had to reboot this number of times, something is definitely
    wrong and we're likely to just make things worse by continuing to try,
    so let's err on the side of caution and disable ourselves.

 src/compositor/compositor.c     |    4 +-
 src/compositor/meta-sync-ring.c |   60 +++++++++++++++++++++++++++++++++-----
 src/compositor/meta-sync-ring.h |    4 +-
 3 files changed, 56 insertions(+), 12 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index add1ed6..aa23fcb 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -1522,7 +1522,7 @@ meta_pre_paint_func (gpointer data)
        * GLX buffers.
        */
       if (compositor->have_x11_sync_object)
-        meta_sync_ring_insert_wait ();
+        compositor->have_x11_sync_object = meta_sync_ring_insert_wait ();
       else
         XSync (compositor->display->xdisplay, False);
     }
@@ -1538,7 +1538,7 @@ meta_post_paint_func (gpointer data)
   if (compositor->frame_has_updated_xsurfaces)
     {
       if (compositor->have_x11_sync_object)
-        meta_sync_ring_after_frame ();
+        compositor->have_x11_sync_object = meta_sync_ring_after_frame ();
 
       compositor->frame_has_updated_xsurfaces = FALSE;
     }
diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c
index c17c814..d29d13e 100644
--- a/src/compositor/meta-sync-ring.c
+++ b/src/compositor/meta-sync-ring.c
@@ -57,6 +57,7 @@
 
 #define NUM_SYNCS 10
 #define MAX_SYNC_WAIT_TIME (1 * 1000 * 1000 * 1000) /* one sec */
+#define MAX_REBOOT_ATTEMPTS 2
 
 typedef enum
 {
@@ -90,6 +91,8 @@ typedef struct
   guint current_sync_idx;
   MetaSync *current_sync;
   guint warmup_syncs;
+
+  guint reboots;
 } MetaSyncRing;
 
 static MetaSyncRing meta_sync_ring = { 0 };
@@ -115,6 +118,9 @@ static GLsync           (*meta_gl_import_sync) (GLenum external_sync_type,
 static MetaSyncRing *
 meta_sync_ring_get (void)
 {
+  if (meta_sync_ring.reboots > MAX_REBOOT_ATTEMPTS)
+    return NULL;
+
   return &meta_sync_ring;
 }
 
@@ -302,8 +308,13 @@ alarm_event_predicate (Display  *dpy,
                        XEvent   *event,
                        XPointer  data)
 {
+  int xsync_event_base;
   MetaSyncRing *ring = meta_sync_ring_get ();
-  int xsync_event_base = meta_display_get_sync_event_base (ring->display);
+
+  if (!ring)
+    return False;
+
+  xsync_event_base = meta_display_get_sync_event_base (ring->display);
 
   if (event->type == xsync_event_base + XSyncAlarmNotify)
     {
@@ -356,6 +367,9 @@ meta_sync_ring_init (MetaDisplay *display)
   guint i;
   MetaSyncRing *ring = meta_sync_ring_get ();
 
+  if (!ring)
+    return FALSE;
+
   g_return_val_if_fail (display != NULL, FALSE);
   g_return_val_if_fail (ring->display == NULL, FALSE);
 
@@ -392,6 +406,9 @@ meta_sync_ring_destroy (void)
   guint i;
   MetaSyncRing *ring = meta_sync_ring_get ();
 
+  if (!ring)
+    return;
+
   g_return_if_fail (ring->display != NULL);
 
   ring->current_sync_idx = 0;
@@ -406,18 +423,35 @@ meta_sync_ring_destroy (void)
   ring->display = NULL;
 }
 
-static void
+static gboolean
 meta_sync_ring_reboot (MetaDisplay *display)
 {
+  MetaSyncRing *ring = meta_sync_ring_get ();
+
+  if (!ring)
+    return FALSE;
+
   meta_sync_ring_destroy ();
-  meta_sync_ring_init (display);
+
+  ring->reboots += 1;
+
+  if (!meta_sync_ring_get ())
+    {
+      meta_warning ("MetaSyncRing: Too many reboots -- disabling\n");
+      return FALSE;
+    }
+
+  return meta_sync_ring_init (display);
 }
 
-void
+gboolean
 meta_sync_ring_after_frame (void)
 {
   MetaSyncRing *ring = meta_sync_ring_get ();
 
+  if (!ring)
+    return FALSE;
+
   g_return_if_fail (ring->display != NULL);
 
   if (ring->warmup_syncs >= NUM_SYNCS / 2)
@@ -435,8 +469,7 @@ meta_sync_ring_after_frame (void)
       if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED)
         {
           meta_warning ("MetaSyncRing: Timed out waiting for sync object.\n");
-          meta_sync_ring_reboot (ring->display);
-          return;
+          return meta_sync_ring_reboot (ring->display);
         }
 
       meta_sync_reset (sync_to_reset);
@@ -450,22 +483,30 @@ meta_sync_ring_after_frame (void)
   ring->current_sync_idx %= NUM_SYNCS;
 
   ring->current_sync = ring->syncs_array[ring->current_sync_idx];
+
+  return TRUE;
 }
 
-void
+gboolean
 meta_sync_ring_insert_wait (void)
 {
   MetaSyncRing *ring = meta_sync_ring_get ();
 
+  if (!ring)
+    return FALSE;
+
   g_return_if_fail (ring->display != NULL);
 
   if (ring->current_sync->state != META_SYNC_STATE_READY)
     {
       meta_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?\n");
-      meta_sync_ring_reboot (ring->display);
+      if (!meta_sync_ring_reboot (ring->display))
+        return FALSE;
     }
 
   meta_sync_insert (ring->current_sync);
+
+  return TRUE;
 }
 
 void
@@ -474,6 +515,9 @@ meta_sync_ring_handle_event (XSyncAlarmNotifyEvent *event)
   MetaSync *sync;
   MetaSyncRing *ring = meta_sync_ring_get ();
 
+  if (!ring)
+    return;
+
   g_return_if_fail (ring->display != NULL);
 
   sync = g_hash_table_lookup (ring->alarm_to_sync, (gpointer) event->alarm);
diff --git a/src/compositor/meta-sync-ring.h b/src/compositor/meta-sync-ring.h
index b0d2275..81d0aa0 100644
--- a/src/compositor/meta-sync-ring.h
+++ b/src/compositor/meta-sync-ring.h
@@ -10,8 +10,8 @@
 
 gboolean meta_sync_ring_init (MetaDisplay *dpy);
 void meta_sync_ring_destroy (void);
-void meta_sync_ring_after_frame (void);
-void meta_sync_ring_insert_wait (void);
+gboolean meta_sync_ring_after_frame (void);
+gboolean meta_sync_ring_insert_wait (void);
 void meta_sync_ring_handle_event (XSyncAlarmNotifyEvent *event);
 
 #endif  /* _META_SYNC_RING_H_ */


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