Fix double-scheduled timer problem caused by reloading the jobs file.
authorRichard W.M. Jones <rjones@redhat.com>
Wed, 22 Feb 2012 18:15:57 +0000 (18:15 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Wed, 22 Feb 2012 18:16:18 +0000 (18:16 +0000)
daemon/daemon.ml

index 6ccfcce..b38481c 100644 (file)
@@ -57,6 +57,14 @@ let server = ref None
 
 let esys = Unixqueue.standard_event_system ()
 
+(* The timer.  It's convenient to have this as a global variable
+ * because (a) there should only be one timer (which fires when the
+ * soonest every-job becomes ready), and (b) it's complicated to track
+ * that timer and avoid it getting double-scheduled (eg.  when we
+ * reload the jobs file) without having a global variable.
+ *)
+let timer_group = ref None
+
 let rec init j d =
   jobsdir := j;
   debug := d;
@@ -301,11 +309,11 @@ and schedule_next_everyjob () =
           (string_of_time_t t);
 
       (* Schedule them to run at time t. *)
-      let g = Unixqueue.new_group esys in
+      let g = new_timer_group () in
       let t_diff = t -. Unix.time () in
       let t_diff = if t_diff < 0. then 0. else t_diff in
       let run_jobs () =
-        Unixqueue.clear esys g;         (* Delete the timer. *)
+        delete_timer_group ();          (* Delete the timer. *)
         List.iter run_job jobs;
         schedule_next_everyjob ()
       in
@@ -313,6 +321,19 @@ and schedule_next_everyjob () =
     )
   )
 
+and new_timer_group () =
+  delete_timer_group ();
+  let g = Unixqueue.new_group esys in
+  timer_group := Some g;
+  g
+
+and delete_timer_group () =
+  match !timer_group with
+  | None -> ()
+  | Some g ->
+    Unixqueue.clear esys g;
+    timer_group := None
+
 and string_of_time_t t =
   let tm = gmtime t in
   sprintf "%04d-%02d-%02d %02d:%02d:%02d UTC"