[ostree] pull: Close another race



commit 96401717115be5843ced5c9eb31e5829c55436c4
Author: Colin Walters <walters verbum org>
Date:   Mon Jan 20 06:17:45 2014 -0500

    pull: Close another race
    
    Only send _IDLE messages if and only if we state transition the main
    thread (from idle -> !idle or !idle -> idle).  This ensures that we
    don't send IDLE, then get it back, and process that when we're !idle.

 src/libostree/ostree-repo-pull.c |   44 +++++++++++++++++--------------------
 1 files changed, 20 insertions(+), 24 deletions(-)
---
diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c
index cfbe81a..c95fb41 100644
--- a/src/libostree/ostree-repo-pull.c
+++ b/src/libostree/ostree-repo-pull.c
@@ -104,6 +104,7 @@ typedef struct {
   GHashTable       *requested_content; /* Maps object name to itself */
   guint             checking_metadata_scan_complete : 1;
   guint             metadata_scan_complete : 1;
+  gboolean          was_idle;
   guint             idle_serial;
   guint             n_outstanding_metadata_fetches;
   guint             n_outstanding_metadata_write_requests;
@@ -253,24 +254,6 @@ throw_async_error (OtPullData          *pull_data,
     }
 }
 
-static gboolean
-termination_condition (OtPullData           *pull_data,
-                       gboolean              current_fetch_idle,
-                       gboolean              current_write_idle)
-{
-  /* This is true in the phase when we're fetching refs */
-  if (pull_data->metadata_objects_to_scan == NULL)
-    {
-      if (!pull_data->fetching_sync_uri)
-        return TRUE;
-    }
-  else if (pull_data->metadata_scan_complete && current_fetch_idle && current_write_idle)
-    {
-      return TRUE;
-    }
-  return FALSE;
-}
-
 static void
 check_outstanding_requests_handle_error (OtPullData          *pull_data,
                                          GError              *error)
@@ -279,24 +262,37 @@ check_outstanding_requests_handle_error (OtPullData          *pull_data,
                                  pull_data->n_outstanding_content_fetches == 0);
   gboolean current_write_idle = (pull_data->n_outstanding_metadata_write_requests == 0 &&
                                  pull_data->n_outstanding_content_write_requests == 0);
+  gboolean current_idle = current_fetch_idle && current_write_idle;
 
   g_debug ("pull: scanning: %u fetching: %u staging: %u",
            !pull_data->metadata_scan_complete, !current_fetch_idle, !current_write_idle);
 
   throw_async_error (pull_data, error);
 
-  if (pull_data->metadata_objects_to_scan &&
-      !pull_data->checking_metadata_scan_complete &&
-      !pull_data->metadata_scan_complete &&
-      (current_fetch_idle && current_write_idle))
+  /* This is true in the phase when we're fetching refs */
+  if (pull_data->metadata_objects_to_scan == NULL)
+    {
+      if (!pull_data->fetching_sync_uri)
+        g_main_loop_quit (pull_data->loop);
+      return;
+    }
+
+  if (pull_data->was_idle && !current_idle)
     {
-      pull_data->checking_metadata_scan_complete = TRUE;
+      /* We transitioned to !idle */
+      g_debug ("pull: No longer idle");
       pull_data->idle_serial++;
+      pull_data->was_idle = FALSE;
+    }
+  else if (!pull_data->was_idle && current_idle)
+    {
+      pull_data->was_idle = TRUE;
       g_debug ("Sending new MSG_IDLE with serial %u", pull_data->idle_serial);
       ot_waitable_queue_push (pull_data->metadata_objects_to_scan,
                               pull_worker_message_new (PULL_MSG_IDLE, GUINT_TO_POINTER 
(pull_data->idle_serial)));
     }
-  else if (termination_condition (pull_data, current_fetch_idle, current_write_idle))
+
+  if (pull_data->metadata_scan_complete && current_idle)
     g_main_loop_quit (pull_data->loop);
 }
 


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