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

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Sun Aug  1 19:02:08 2010 +0200

native: add cancellation points

---

 src/skins/native/cond.c  |   81 +++++++++++++++++++++++++++++++++++++++-------
 src/skins/native/intr.c  |   11 ++++++-
 src/skins/native/queue.c |   60 ++++++++++++++++++++++++++++++---
 src/skins/native/sem.c   |   22 +++++++++++-
 src/skins/native/task.c  |   46 ++++++++++++++++++++++----
 5 files changed, 192 insertions(+), 28 deletions(-)

diff --git a/src/skins/native/cond.c b/src/skins/native/cond.c
index f874678..cf7a639 100644
--- a/src/skins/native/cond.c
+++ b/src/skins/native/cond.c
@@ -16,6 +16,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 
+#include <pthread.h>
+
 #include <native/syscall.h>
 #include <native/mutex.h>
 #include <native/cond.h>
@@ -39,12 +41,40 @@ int rt_cond_delete(RT_COND *cond)
        return XENOMAI_SKINCALL1(__native_muxid, __native_cond_delete, cond);
 }
 
+struct rt_cond_cleanup_t {
+       RT_MUTEX *mutex;
+       unsigned saved_lockcnt;
+};
+
+static void __rt_cond_cleanup(void *data)
+{
+       struct rt_cond_cleanup_t *c = (struct rt_cond_cleanup_t *)data;
+       int err;
+
+       do {
+               err = XENOMAI_SKINCALL2(__native_muxid,
+                                       __native_cond_wait_epilogue, c->mutex,
+                                       c->saved_lockcnt);
+       } while (err == EINTR);
+
+#ifdef CONFIG_XENO_FASTSYNCH
+       c->mutex->lockcnt = c->saved_lockcnt;
+#endif /* CONFIG_XENO_FASTSYNCH */
+}
+
 int rt_cond_wait(RT_COND *cond, RT_MUTEX *mutex, RTIME timeout)
 {
-       int saved_lockcnt, err;
+       struct rt_cond_cleanup_t c = {
+               .mutex = mutex,
+       };
+       int err, oldtype;
+
+       pthread_cleanup_push(&__rt_cond_cleanup, &c);
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
 
 #ifdef CONFIG_XENO_FASTSYNCH
-       saved_lockcnt = mutex->lockcnt;
+       c.saved_lockcnt = mutex->lockcnt;
 
        err = XENOMAI_SKINCALL5(__native_muxid,
                                __native_cond_wait_prologue, cond, mutex,
@@ -53,54 +83,81 @@ int rt_cond_wait(RT_COND *cond, RT_MUTEX *mutex, RTIME 
timeout)
        while (err == -EINTR)
                err = XENOMAI_SKINCALL2(__native_muxid,
                                        __native_cond_wait_epilogue, mutex,
-                                       saved_lockcnt);
+                                       c.saved_lockcnt);
+
+       pthread_setcanceltype(oldtype, NULL);
 
-       mutex->lockcnt = saved_lockcnt;
+       pthread_cleanup_pop(0);
+
+       mutex->lockcnt = c.saved_lockcnt;
 
 #else /* !CONFIG_XENO_FASTSYNCH */
        err = XENOMAI_SKINCALL5(__native_muxid,
                                 __native_cond_wait_prologue, cond, mutex,
-                                &saved_lockcnt, XN_RELATIVE, &timeout);
+                                &c.saved_lockcnt, XN_RELATIVE, &timeout);
+
+       pthread_setcanceltype(oldtype, NULL);
+
+       pthread_cleanup_pop(0);
 
        while (err == -EINTR)
                err = XENOMAI_SKINCALL2(__native_muxid,
                                        __native_cond_wait_epilogue, mutex,
-                                       saved_lockcnt);
+                                       c.saved_lockcnt);
 
 #endif /* !CONFIG_XENO_FASTSYNCH */
 
+       pthread_testcancel();
+
        return err;
 }
 
 int rt_cond_wait_until(RT_COND *cond, RT_MUTEX *mutex, RTIME timeout)
 {
-       int saved_lockcnt, err;
+       struct rt_cond_cleanup_t c = {
+               .mutex = mutex,
+       };
+       int err, oldtype;
+
+       pthread_cleanup_push(&__rt_cond_cleanup, &c);
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
 
 #ifdef CONFIG_XENO_FASTSYNCH
-       saved_lockcnt = mutex->lockcnt;
+       c.saved_lockcnt = mutex->lockcnt;
 
        err = XENOMAI_SKINCALL5(__native_muxid,
                                __native_cond_wait_prologue, cond, mutex,
                                NULL, XN_REALTIME, &timeout);
 
+       pthread_setcanceltype(oldtype, NULL);
+
+       pthread_cleanup_pop(0);
+
        while (err == -EINTR)
                err = XENOMAI_SKINCALL2(__native_muxid,
                                        __native_cond_wait_epilogue, mutex,
-                                       saved_lockcnt);
+                                       c.saved_lockcnt);
 
-       mutex->lockcnt = saved_lockcnt;
+       mutex->lockcnt = c.saved_lockcnt;
 
 #else /* !CONFIG_XENO_FASTSYNCH */
        err = XENOMAI_SKINCALL5(__native_muxid,
                                __native_cond_wait_prologue, cond, mutex,
-                               &saved_lockcnt, XN_REALTIME, &timeout);
+                               &c.saved_lockcnt, XN_REALTIME, &timeout);
+
+       pthread_setcanceltype(oldtype, NULL);
+
+       pthread_cleanup_pop(0);
 
        while (err == -EINTR)
                err = XENOMAI_SKINCALL2(__native_muxid,
                                        __native_cond_wait_epilogue, mutex,
-                                       saved_lockcnt);
+                                       c.saved_lockcnt);
 #endif /* !CONFIG_XENO_FASTSYNCH */
 
+       pthread_testcancel();
+
        return err;
 }
 
diff --git a/src/skins/native/intr.c b/src/skins/native/intr.c
index 8dd6db8..e425706 100644
--- a/src/skins/native/intr.c
+++ b/src/skins/native/intr.c
@@ -18,6 +18,7 @@
 
 #include <sys/types.h>
 #include <stdio.h>
+#include <pthread.h>
 #include <native/syscall.h>
 #include <native/intr.h>
 
@@ -42,8 +43,16 @@ int rt_intr_delete(RT_INTR *intr)
 
 int rt_intr_wait(RT_INTR *intr, RTIME timeout)
 {
-       return XENOMAI_SKINCALL2(__native_muxid,
+       int err, oldtype;
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+       err = XENOMAI_SKINCALL2(__native_muxid,
                                 __native_intr_wait, intr, &timeout);
+
+       pthread_setcanceltype(oldtype, NULL);
+
+       return err;
 }
 
 int rt_intr_enable(RT_INTR *intr)
diff --git a/src/skins/native/queue.c b/src/skins/native/queue.c
index d104bd0..dd8cf70 100644
--- a/src/skins/native/queue.c
+++ b/src/skins/native/queue.c
@@ -124,42 +124,90 @@ int rt_queue_free(RT_QUEUE *q, void *buf)
 
 int rt_queue_send(RT_QUEUE *q, void *buf, size_t size, int mode)
 {
-       return XENOMAI_SKINCALL4(__native_muxid,
+       int err, oldtype;
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+       err = XENOMAI_SKINCALL4(__native_muxid,
                                 __native_queue_send, q, buf, size, mode);
+
+       pthread_setcanceltype(oldtype, NULL);
+
+       return err;
 }
 
 int rt_queue_write(RT_QUEUE *q, const void *buf, size_t size, int mode)
 {
-       return XENOMAI_SKINCALL4(__native_muxid,
+       int err, oldtype;
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+       err = XENOMAI_SKINCALL4(__native_muxid,
                                 __native_queue_write, q, buf, size, mode);
+
+       pthread_setcanceltype(oldtype, NULL);
+
+       return err;
 }
 
 ssize_t rt_queue_receive(RT_QUEUE *q, void **bufp, RTIME timeout)
 {
-       return XENOMAI_SKINCALL4(__native_muxid,
+       int err, oldtype;
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+       err = XENOMAI_SKINCALL4(__native_muxid,
                                 __native_queue_receive, q, bufp,
                                 XN_RELATIVE, &timeout);
+
+       pthread_setcanceltype(oldtype, NULL);
+
+       return err;
 }
 
 ssize_t rt_queue_receive_until(RT_QUEUE *q, void **bufp, RTIME timeout)
 {
-       return XENOMAI_SKINCALL4(__native_muxid,
+       int err, oldtype;
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+       err = XENOMAI_SKINCALL4(__native_muxid,
                                 __native_queue_receive, q, bufp,
                                 XN_REALTIME, &timeout);
+
+       pthread_setcanceltype(oldtype, NULL);
+
+       return err;
 }
 
 ssize_t rt_queue_read(RT_QUEUE *q, void *buf, size_t size, RTIME timeout)
 {
-       return XENOMAI_SKINCALL5(__native_muxid,
+       int err, oldtype;
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+       err = XENOMAI_SKINCALL5(__native_muxid,
                                 __native_queue_read, q, buf, size,
                                 XN_RELATIVE, &timeout);
+
+       pthread_setcanceltype(oldtype, NULL);
+
+       return err;
 }
 
 ssize_t rt_queue_read_until(RT_QUEUE *q, void *buf, size_t size, RTIME timeout)
 {
-       return XENOMAI_SKINCALL5(__native_muxid,
+       int err, oldtype;
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+       err = XENOMAI_SKINCALL5(__native_muxid,
                                 __native_queue_read, q, buf, size,
                                 XN_REALTIME, &timeout);
+
+       pthread_setcanceltype(oldtype, NULL);
+
+       return err;
 }
 
 int rt_queue_inquire(RT_QUEUE *q, RT_QUEUE_INFO *info)
diff --git a/src/skins/native/sem.c b/src/skins/native/sem.c
index 3b6ca70..8863e2c 100644
--- a/src/skins/native/sem.c
+++ b/src/skins/native/sem.c
@@ -16,6 +16,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 
+#include <pthread.h>
+
 #include <native/syscall.h>
 #include <native/sem.h>
 
@@ -40,14 +42,30 @@ int rt_sem_delete(RT_SEM *sem)
 
 int rt_sem_p(RT_SEM *sem, RTIME timeout)
 {
-       return XENOMAI_SKINCALL3(__native_muxid,
+       int err, oldtype;
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+       err = XENOMAI_SKINCALL3(__native_muxid,
                                 __native_sem_p, sem, XN_RELATIVE, &timeout);
+
+       pthread_setcanceltype(oldtype, NULL);
+
+       return err;
 }
 
 int rt_sem_p_until(RT_SEM *sem, RTIME timeout)
 {
-       return XENOMAI_SKINCALL3(__native_muxid,
+       int err, oldtype;
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+       err = XENOMAI_SKINCALL3(__native_muxid,
                                 __native_sem_p, sem, XN_REALTIME, &timeout);
+
+       pthread_setcanceltype(oldtype, NULL);
+
+       return err;
 }
 
 int rt_sem_v(RT_SEM *sem)
diff --git a/src/skins/native/task.c b/src/skins/native/task.c
index d975508..be4ea2c 100644
--- a/src/skins/native/task.c
+++ b/src/skins/native/task.c
@@ -24,6 +24,7 @@
 #include <pthread.h>
 #include <signal.h>
 #include <limits.h>
+#include <pthread.h>
 #include <native/syscall.h>
 #include <native/task.h>
 #include <asm-generic/bits/sigshadow.h>
@@ -191,7 +192,7 @@ int rt_task_shadow(RT_TASK *task, const char *name, int 
prio, int mode)
        if (pthread_getspecific(__native_tskey))
                /* Current task is already a native taks. */
                return -EBUSY;
-  
+
        self = malloc(sizeof(*self));
        if (!self)
                return -ENOMEM;
@@ -292,8 +293,16 @@ int rt_task_set_periodic(RT_TASK *task, RTIME idate, RTIME 
period)
 
 int rt_task_wait_period(unsigned long *overruns_r)
 {
-       return XENOMAI_SKINCALL1(__native_muxid,
+       int err, oldtype;
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+       err = XENOMAI_SKINCALL1(__native_muxid,
                                 __native_task_wait_period, overruns_r);
+
+       pthread_setcanceltype(oldtype, NULL);
+
+       return err;
 }
 
 int rt_task_set_priority(RT_TASK *task, int prio)
@@ -304,15 +313,29 @@ int rt_task_set_priority(RT_TASK *task, int prio)
 
 int rt_task_sleep(RTIME delay)
 {
-       return XENOMAI_SKINCALL1(__native_muxid, __native_task_sleep, &delay);
+       int err, oldtype;
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+       err = XENOMAI_SKINCALL1(__native_muxid, __native_task_sleep, &delay);
+
+       pthread_setcanceltype(oldtype, NULL);
 
+       return err;
 }
 
 int rt_task_sleep_until(RTIME date)
 {
-       return XENOMAI_SKINCALL1(__native_muxid, __native_task_sleep_until,
+       int err, oldtype;
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+       err = XENOMAI_SKINCALL1(__native_muxid, __native_task_sleep_until,
                                 &date);
 
+       pthread_setcanceltype(oldtype, NULL);
+
+       return err;
 }
 
 int rt_task_unblock(RT_TASK *task)
@@ -376,9 +399,18 @@ int rt_task_join(RT_TASK *task)
 ssize_t rt_task_send(RT_TASK *task,
                     RT_TASK_MCB *mcb_s, RT_TASK_MCB *mcb_r, RTIME timeout)
 {
-       return (ssize_t) XENOMAI_SKINCALL4(__native_muxid,
-                                          __native_task_send,
-                                          task, mcb_s, mcb_r, &timeout);
+       int oldtype;
+       ssize_t ret;
+
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+
+       ret = (ssize_t)XENOMAI_SKINCALL4(__native_muxid,
+                                        __native_task_send,
+                                        task, mcb_s, mcb_r, &timeout);
+
+       pthread_setcanceltype(oldtype, NULL);
+
+       return ret;
 }
 
 int rt_task_receive(RT_TASK_MCB *mcb_r, RTIME timeout)


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

Reply via email to