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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Tue Sep 10 12:35:00 2013 +0200

cobalt/posix/sem: extend policy for deleting pended semaphores

Middleware may want deletion to be prevented for pended semaphores.

SEM_NOBUSYDEL is added to the set of policy-setting flags to
sem_init_np(), controlling how sem_destroy() behaves in case a thread
is waiting on the semaphore to be deleted.

---

 include/cobalt/uapi/sem.h |   13 +++++++------
 kernel/cobalt/posix/sem.c |   21 ++++++++++++++++-----
 2 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/include/cobalt/uapi/sem.h b/include/cobalt/uapi/sem.h
index 4ec3505..7206446 100644
--- a/include/cobalt/uapi/sem.h
+++ b/include/cobalt/uapi/sem.h
@@ -32,11 +32,12 @@ union cobalt_sem_union {
 };
 
 /* For Cobalt's sem_init_np() extension. */
-#define SEM_FIFO     0x1
-#define SEM_PULSE    0x2
-#define SEM_PSHARED  0x4
-#define SEM_REPORT   0x8
-#define SEM_WARNDEL  0x10
-#define SEM_RAWCLOCK 0x20
+#define SEM_FIFO       0x1
+#define SEM_PULSE      0x2
+#define SEM_PSHARED    0x4
+#define SEM_REPORT     0x8
+#define SEM_WARNDEL    0x10
+#define SEM_RAWCLOCK   0x20
+#define SEM_NOBUSYDEL  0x40
 
 #endif /* !_COBALT_UAPI_SEM_H */
diff --git a/kernel/cobalt/posix/sem.c b/kernel/cobalt/posix/sem.c
index e95c279..f3a5d1c 100644
--- a/kernel/cobalt/posix/sem.c
+++ b/kernel/cobalt/posix/sem.c
@@ -191,15 +191,20 @@ err_lock_put:
  *
  * @param sm the semaphore to be destroyed.
  *
- * @retval always 0 on success if SEM_WARNDEL was not mentioned via
- * sem_init_np().  If SEM_WARNDEL was mentioned, then a strictly
+ * @retval always 0 on success.  If SEM_WARNDEL was mentioned in
+ * sem_init_np(), the semaphore is deleted as requested and a strictly
  * positive value is returned to warn the caller if threads were
- * pending on the semaphore, or zero otherwise.
+ * pending on it, otherwise zero is returned. If SEM_NOBUSYDEL was
+ * mentioned in sem_init_np(), sem_destroy() may succeed only if no
+ * thread is waiting on the semaphore to delete, otherwise -EBUSY is
+ * returned.
  *
  * @retval -1 with @a errno set if:
  * - EINVAL, the semaphore @a sm is invalid or a named semaphore;
  * - EPERM, the semaphore @a sm is not process-shared and does not belong to 
the
  *   current process.
+ * - EBUSY, a thread is currently waiting on the semaphore @a sm with
+ * SEM_NOBUSYDEL set.
  *
  * @see
  * <a 
href="http://www.opengroup.org/onlinepubs/000095399/functions/sem_destroy.html";>
@@ -225,6 +230,12 @@ static int sem_destroy(struct __shadow_sem *sm)
                goto error;
        }
 
+       if ((sem->flags & SEM_NOBUSYDEL) != 0 &&
+           xnsynch_pended_p(&sem->synchbase)) {
+               ret = -EBUSY;
+               goto error;
+       }
+
        warn = sem->flags & SEM_WARNDEL;
        cobalt_mark_deleted(sm);
        cobalt_mark_deleted(sem);
@@ -1008,8 +1019,8 @@ int cobalt_sem_init_np(struct __shadow_sem __user *u_sem,
        if (__xn_safe_copy_from_user(&sm, u_sem, sizeof(sm)))
                return -EFAULT;
 
-       if (flags & ~(SEM_FIFO|SEM_PULSE|SEM_PSHARED|\
-                     SEM_REPORT|SEM_WARNDEL|SEM_RAWCLOCK))
+       if (flags & ~(SEM_FIFO|SEM_PULSE|SEM_PSHARED|SEM_REPORT|\
+                     SEM_WARNDEL|SEM_RAWCLOCK|SEM_NOBUSYDEL))
                return -EINVAL;
 
        err = do_sem_init(&sm, flags, value);


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

Reply via email to