Module: xenomai-forge
Branch: next
Commit: 872dd35632193ff9bd3fa0561987dc23f6b20cc6
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=872dd35632193ff9bd3fa0561987dc23f6b20cc6

Author: Philippe Gerum <r...@xenomai.org>
Date:   Wed Jun  5 16:33:39 2013 +0200

copperplate/timerobj: queue+arm timers atomically wrt the carrier thread

---

 lib/copperplate/timerobj.c |   17 ++++++++++++++---
 1 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/lib/copperplate/timerobj.c b/lib/copperplate/timerobj.c
index 9e61bcd..53c55f7 100644
--- a/lib/copperplate/timerobj.c
+++ b/lib/copperplate/timerobj.c
@@ -299,14 +299,25 @@ int timerobj_start(struct timerobj *tmobj,
 {
        tmobj->handler = handler;
        tmobj->itspec = *it;
+
+       /*
+        * We hold the queue lock long enough to prevent the timer
+        * from being dequeued by the carrier thread before it has
+        * been armed, e.g. the user handler might destroy it under
+        * our feet if so, causing timer_settime() to fail, which
+        * would in turn lead to a double-deletion if the caller
+        * happens to check the return code then drop the timer
+        * (again).
+        */
        write_lock_nocancel(&svlock);
-       timerobj_enqueue(tmobj);
-       write_unlock(&svlock);
-       timerobj_unlock(tmobj);
 
        if (__RT(timer_settime(tmobj->timer, TIMER_ABSTIME, it, NULL)))
                return __bt(-errno);
 
+       timerobj_enqueue(tmobj);
+       write_unlock(&svlock);
+       timerobj_unlock(tmobj);
+
        return 0;
 }
 


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to