fix potential iteration problem in Timer
authortom <tom@taco.desk.hq.powerset.com>
Fri, 21 Dec 2007 23:52:10 +0000 (21 15:52 -0800)
committertom <tom@taco.desk.hq.powerset.com>
Fri, 21 Dec 2007 23:52:10 +0000 (21 15:52 -0800)
History.txt
lib/god/timer.rb

index 34d08b1..863ab62 100644 (file)
@@ -1,3 +1,8 @@
+== 0.6.4 / 
+  * Bug Fixes
+    * Refactor Hub to clarify mutexing
+    * Eliminated potential iteration problem in Timer
+
 == 0.6.3 / 2007-12-18
   * Minor Enhancements
     * Output ProcessExits registration/deregistration info
index 913267a..8a3d4ce 100644 (file)
@@ -34,25 +34,33 @@ module God
           begin
             # get the current time
             t = Time.now.to_i
-          
+            
             # iterate over each event and trigger any that are due
-            @events.each do |event|
-              if t >= event.at
-                self.trigger(event)
-                @mutex.synchronize do
-                  @events.delete(event)
+            @mutex.synchronize do
+              triggered = []
+              
+              @events.each do |event|
+                if t >= event.at
+                  # trigger the event and mark it for removal
+                  self.trigger(event)
+                  triggered << event
+                else
+                  # events are ordered, so we can bail on first miss
+                  break
                 end
-              else
-                break
+              end
+              
+              # remove all triggered events
+              triggered.each do |event|
+                @events.delete(event)
               end
             end
-          
-            # sleep until next check
-            sleep INTERVAL
           rescue Exception => e
             message = format("Unhandled exception (%s): %s\n%s",
                              e.class, e.message, e.backtrace.join("\n"))
             applog(nil, :fatal, message)
+          ensure
+            # sleep until next check
             sleep INTERVAL
           end
         end