Francois Gouget : testbot/Engine: Let event handlers add / remove events.

Alexandre Julliard julliard at winehq.org
Thu May 10 18:14:05 CDT 2018


Module: tools
Branch: master
Commit: a5d7bc263b1e355ee8b522812c8a0961d1d9d116
URL:    https://source.winehq.org/git/tools.git/?a=commit;h=a5d7bc263b1e355ee8b522812c8a0961d1d9d116

Author: Francois Gouget <fgouget at codeweavers.com>
Date:   Fri May 11 00:14:52 2018 +0200

testbot/Engine: Let event handlers add / remove events.

This makes it possible to handle events that happen at irregular
intervals: the event is created as non-repeating and the event handler
computes when the next event should happen and adds it.

Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 testbot/lib/WineTestBot/Engine/Events.pm | 70 ++++++++++++++++++--------------
 1 file changed, 40 insertions(+), 30 deletions(-)

diff --git a/testbot/lib/WineTestBot/Engine/Events.pm b/testbot/lib/WineTestBot/Engine/Events.pm
index 677debf..f1ab39a 100644
--- a/testbot/lib/WineTestBot/Engine/Events.pm
+++ b/testbot/lib/WineTestBot/Engine/Events.pm
@@ -37,10 +37,11 @@ sub AddEvent($$$$)
 {
   my ($Name, $Timeout, $Repeat, $HandlerFunc) = @_;
 
-  $Events{$Name} = {Expires => time() + $Timeout,
-                    Timeout => $Timeout,
-                    Repeat => $Repeat,
-                    HandlerFunc => $HandlerFunc};
+  $Events{$Name} = { Name => $Name,
+                     Expires => time() + $Timeout,
+                     Timeout => $Timeout,
+                     Repeat => $Repeat,
+                     HandlerFunc => $HandlerFunc };
 }
 
 sub DeleteEvent($)
@@ -54,42 +55,51 @@ sub EventScheduled($)
 {
   my ($Name) = @_;
 
-  return defined($Events{$Name});
+  return exists $Events{$Name};
 }
 
 sub RunEvents()
 {
   my $Now = time();
-  my $Next = undef;
-  foreach my $Name (keys %Events)
+  # Run expired events in their expiration order.
+  # Note that callbacks may add / remove events.
+  my @SortedEvents = sort { $a->{Expires} <=> $b->{Expires} } values %Events;
+  foreach my $Event (@SortedEvents)
   {
-    my $Event = $Events{$Name};
-    if (defined($Event))
+    if (!exists $Events{$Event->{Name}})
+    {
+      # This event got removed by a callback
+      next;
+    }
+
+    if ($Event->{Expires} > $Now)
+    {
+      # Since the events are sorted by expiration order,
+      # there is no other event to run.
+      last;
+    }
+
+    if ($Event->{Repeat})
     {
-      if ($Event->{Expires} <= $Now)
-      {
-        if ($Event->{Repeat})
-        {
-          $Event->{Expires} += $Event->{Timeout};
-          if (! defined($Next) || $Event->{Expires} - $Now < $Next)
-          {
-            $Next = $Event->{Expires} - $Now;
-          }
-        }
-        else
-        {
-          delete $Events{$Name};
-        }
-        &{$Event->{HandlerFunc}}();
-      }
-      elsif (! defined($Next) || $Event->{Expires} - $Now < $Next)
-      {
-        $Next = $Event->{Expires} - $Now;
-      }
+      $Event->{Expires} += $Event->{Timeout};
     }
+    else
+    {
+      delete $Events{$Event->{Name}};
+    }
+    &{$Event->{HandlerFunc}}();
   }
 
-  return $Next;
+  # Determine when the next event is due
+  my $Next = undef;
+  foreach my $Event (values %Events)
+  {
+    if (!defined $Next or $Event->{Expires} - $Now < $Next)
+    {
+      $Next = $Event->{Expires} - $Now;
+    }
+  }
+  return $Next <= 0 ? 1 : $Next;
 }
 
 1;




More information about the wine-cvs mailing list