Module: xenomai-forge
Branch: master
Commit: 56c7b8ee683c2f2902050b67c37d82d7176ad524
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=56c7b8ee683c2f2902050b67c37d82d7176ad524

Author: Philippe Gerum <r...@xenomai.org>
Date:   Wed Dec 14 16:52:26 2011 +0100

cobalt/monitor: fix double-dequeuing upon GRANT+KICK race

---

 kernel/cobalt/monitor.c |    7 ++++++-
 kernel/cobalt/thread.c  |    1 +
 kernel/cobalt/thread.h  |    1 +
 3 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/kernel/cobalt/monitor.c b/kernel/cobalt/monitor.c
index 4e4ea4f..678ea6c 100644
--- a/kernel/cobalt/monitor.c
+++ b/kernel/cobalt/monitor.c
@@ -202,6 +202,7 @@ static int cobalt_monitor_wakeup(struct cobalt_monitor *mon)
                        xnsynch_wakeup_this_sleeper(&tid->monitor_synch,
                                                    &p->plink);
                        removeq(&mon->waiters, &tid->monitor_link);
+                       tid->monitor_queued = 0;
                        resched = 1;
                }
        }
@@ -278,6 +279,7 @@ int cobalt_monitor_wait(struct cobalt_monitor_shadow __user 
*u_monsh,
        else {
                *cur->threadbase.u_mode &= ~XNGRANT;
                appendq(&mon->waiters, &cur->monitor_link);
+               cur->monitor_queued = 1;
        }
        datp->flags |= COBALT_MONITOR_PENDED;
 
@@ -290,8 +292,11 @@ int cobalt_monitor_wait(struct cobalt_monitor_shadow 
__user *u_monsh,
                        goto out;
                }
 
-               if ((event & COBALT_MONITOR_WAITDRAIN) == 0)
+               if ((event & COBALT_MONITOR_WAITDRAIN) == 0 &&
+                   cur->monitor_queued) {
                        removeq(&mon->waiters, &cur->monitor_link);
+                       cur->monitor_queued = 0;
+               }
 
                if (emptyq_p(&mon->waiters) && !xnsynch_pended_p(&mon->drain))
                        datp->flags &= ~COBALT_MONITOR_PENDED;
diff --git a/kernel/cobalt/thread.c b/kernel/cobalt/thread.c
index 00086ac..c4120ad 100644
--- a/kernel/cobalt/thread.c
+++ b/kernel/cobalt/thread.c
@@ -451,6 +451,7 @@ static inline int pthread_create(pthread_t *tid, const 
pthread_attr_t * attr)
        thread->magic = COBALT_THREAD_MAGIC;
        xnsynch_init(&thread->monitor_synch, XNSYNCH_FIFO, NULL);
        inith(&thread->monitor_link);
+       thread->monitor_queued = 0;
        thread->sched_policy = thread->attr.policy;
 
        cobalt_timer_init_thread(thread);
diff --git a/kernel/cobalt/thread.h b/kernel/cobalt/thread.h
index 162cd42..5c819fb 100644
--- a/kernel/cobalt/thread.h
+++ b/kernel/cobalt/thread.h
@@ -74,6 +74,7 @@ struct cobalt_thread {
        /* Monitor wait object and link holder. */
        struct xnsynch monitor_synch;
        struct xnholder monitor_link;
+       int monitor_queued;
 
 #ifndef __XENO_SIM__
        struct cobalt_hkey hkey;


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to