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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Fri May 10 15:48:23 2013 +0200

nucleus/sem, cond: allow reinitializing anon shared objects

We allow reinitializing shared anonymous semaphores and condvars.

Rationale: if the process creating such object exits, we may assume
that other processes sharing that object won't be able to keep on
running.

This avoids the requirement for applications running in pshared mode
to destroy these synchronization objects explicitly before exiting.

---

 kernel/cobalt/cond.c |   16 +++++++++++++---
 kernel/cobalt/sem.c  |   34 ++++++++++++++++++++++++----------
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/kernel/cobalt/cond.c b/kernel/cobalt/cond.c
index 1cb2cc7..538bf4f 100644
--- a/kernel/cobalt/cond.c
+++ b/kernel/cobalt/cond.c
@@ -98,6 +98,7 @@ pthread_cond_init(struct __shadow_cond *cnd, const 
pthread_condattr_t *attr)
 {
        xnflags_t synch_flags = XNSYNCH_PRIO | XNSYNCH_NOPIP;
        struct xnsys_ppd *sys_ppd;
+       struct xnholder *holder;
        cobalt_cond_t *cond;
        xnqueue_t *condq;
        spl_t s;
@@ -129,17 +130,26 @@ pthread_cond_init(struct __shadow_cond *cnd, const 
pthread_condattr_t *attr)
 
        condq = &cobalt_kqueues(attr->pshared)->condq;
 
+       /*
+        * We allow reinitializing a shared condvar. Rationale: since
+        * a condvar is inherently anonymous, if the process creating
+        * such condvar exits, we may assume that other processes
+        * sharing that condvar won't be able to keep on running.
+        */
        if (cnd->magic == COBALT_COND_MAGIC) {
-               xnholder_t *holder;
                for (holder = getheadq(condq); holder;
                     holder = nextq(condq, holder))
                        if (holder == &cnd->cond->link) {
-                               /* cond is already in the queue. */
+                               if (attr->pshared) {
+                                       cond_destroy_internal(cnd->cond,
+                                                             
cobalt_kqueues(1));
+                                       goto do_init;
+                               }
                                err = -EBUSY;
                                goto err_free_pending_signals;
                        }
        }
-
+do_init:
        cnd->attr = *attr;
        cnd->pending_signals_offset =
                xnheap_mapped_offset(&sys_ppd->sem_heap,
diff --git a/kernel/cobalt/sem.c b/kernel/cobalt/sem.c
index 32edafe..ec4d983 100644
--- a/kernel/cobalt/sem.c
+++ b/kernel/cobalt/sem.c
@@ -135,19 +135,33 @@ static int do_sem_init(struct __shadow_sem *sm, int 
flags, unsigned int value)
 
        xnlock_get_irqsave(&nklock, s);
 
+       if (sm->magic != COBALT_SEM_MAGIC &&
+           sm->magic != COBALT_NAMED_SEM_MAGIC &&
+           sm->magic == ~COBALT_NAMED_SEM_MAGIC)
+               goto do_init;
+
        semq = &cobalt_kqueues(!!(flags & SEM_PSHARED))->semq;
 
-       if (sm->magic == COBALT_SEM_MAGIC
-           || sm->magic == COBALT_NAMED_SEM_MAGIC
-           || sm->magic == ~COBALT_NAMED_SEM_MAGIC) {
-               for (holder = getheadq(semq); holder;
-                    holder = nextq(semq, holder))
-                       if (holder == &sm->sem->link) {
-                               ret = -EBUSY;
-                               goto err_lock_put;
+       /*
+        * Make sure we are not reinitializing a valid semaphore. As a
+        * special exception, we allow reinitializing a shared
+        * anonymous semaphore. Rationale: if the process creating
+        * such semaphore exits, we may assume that other processes
+        * sharing that semaphore won't be able to keep on running.
+        */
+       for (holder = getheadq(semq); holder;
+            holder = nextq(semq, holder))
+               if (holder == &sm->sem->link) {
+                       if ((flags & SEM_PSHARED) &&
+                           sm->magic == COBALT_SEM_MAGIC) {
+                               sem_destroy_inner(sm->sem, sem_kqueue(sm->sem));
+                               goto do_init;
                        }
-       }
+                       ret = -EBUSY;
+                       goto err_lock_put;
+               }
 
+do_init:
        ret = sem_init_inner(sem, flags, value);
        if (ret)
                goto err_lock_put;
@@ -158,7 +172,7 @@ static int do_sem_init(struct __shadow_sem *sm, int flags, 
unsigned int value)
 
        return 0;
 
-  err_lock_put:
+err_lock_put:
        xnlock_put_irqrestore(&nklock, s);
        xnfree(sem);
 


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

Reply via email to