libxl: timeouts: Record deregistration when one occurs
authorIan Jackson <Ian.Jackson@eu.citrix.com>
Fri, 31 Jan 2014 15:07:55 +0000 (15:07 +0000)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Thu, 6 Feb 2014 14:24:16 +0000 (14:24 +0000)
When a timeout has occurred, it is deregistered.  However, we failed
to record this fact by updating etime->func.  As a result,
libxl__ev_time_isregistered would say `true' for a timeout which has
already happened.

It is necessary to clear etime->func before the callback, because the
callback might want to reinstate the timeout, or might free the etime
(or its containing struct) entirely.

The results are that we might try to have the timeout occur again
(causing problems for the call site), and/or corrupt the timeout list.

This fixes the timedereg event system unit test.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Jim Fehlig <jfehlig@suse.com>
Cc: Ian Campbell <Ian.Campbell@citrix.com>
Acked-by: Ian Campbell <Ian.Campbell@citrix.com>
tools/libxl/libxl_event.c

index 5a99932d9637fc51f55a105361ed5b6b4745e54b..ea8c7444618a16c5454e08347575930ed112667a 100644 (file)
@@ -387,7 +387,9 @@ static void time_occurs(libxl__egc *egc, libxl__ev_time *etime)
         etime, (unsigned long)etime->abs.tv_sec,
         (unsigned long)etime->abs.tv_usec);
 
-    etime->func(egc, etime, &etime->abs);
+    libxl__ev_time_callback *func = etime->func;
+    etime->func = 0;
+    func(egc, etime, &etime->abs);
 }