Module: xenomai-forge Branch: next 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