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

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Mon Mar  8 21:01:38 2010 +0100

native: fix rt_cond_*wait return value overwriting

This fix uses errno to remember, at the time of the epilogue, the value
returned by the prologue. It will not work if cond_*wait are interrupted
by signals, and the signal handler uses a system call which overrides errno.

---

 ksrc/skins/native/syscall.c |   32 +++++++++++++++++++++++++-------
 1 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/ksrc/skins/native/syscall.c b/ksrc/skins/native/syscall.c
index 40e5cfd..320eaaf 100644
--- a/ksrc/skins/native/syscall.c
+++ b/ksrc/skins/native/syscall.c
@@ -41,6 +41,8 @@
 #include <native/buffer.h>
 #include <native/misc.h>
 
+#define rt_task_errno (*xnthread_get_errno_location(xnpod_current_thread()))
+
 /*
  * This file implements the Xenomai syscall wrappers.  All skin
  * services (re-)check the object descriptor they are passed; so there
@@ -1837,11 +1839,11 @@ static int __rt_cond_wait_prologue(struct pt_regs *regs)
 {
        RT_COND_PLACEHOLDER cph, mph;
        xntmode_t timeout_mode;
+       int err, perr = 0;
        unsigned lockcnt;
        RT_MUTEX *mutex;
        RT_COND *cond;
        RTIME timeout;
-       int err;
 
        if (__xn_safe_copy_from_user(&cph, (void __user *)__xn_reg_arg1(regs),
                                     sizeof(cph)))
@@ -1869,15 +1871,27 @@ static int __rt_cond_wait_prologue(struct pt_regs *regs)
 
        err = rt_cond_wait_prologue(cond, mutex, &lockcnt, timeout_mode, 
timeout);
 
-       if (err == 0 || err == -ETIMEDOUT)
+       switch(err) {
+       case 0:
+       case -ETIMEDOUT:
+       case -EIDRM:
+               perr = rt_task_errno = err;
                err = rt_cond_wait_epilogue(mutex, lockcnt);
-       
-       if (err == -EINTR && __xn_reg_arg3(regs)
+               break;
+
+       case -EINTR:
+               perr = err;
+               rt_task_errno = 0; /* epilogue should return 0. */
+               break;
+       }
+
+       if (err == -EINTR
+           && __xn_reg_arg3(regs)
            && __xn_safe_copy_to_user((void __user *)__xn_reg_arg3(regs),
                                      &lockcnt, sizeof(lockcnt)))
                return -EFAULT;
 
-       return err;
+       return err == 0 ? perr : err;
 }
 
 /*
@@ -1889,6 +1903,7 @@ static int __rt_cond_wait_epilogue(struct pt_regs *regs)
        RT_COND_PLACEHOLDER mph;
        unsigned lockcnt;
        RT_MUTEX *mutex;
+       int err;
 
        if (__xn_safe_copy_from_user(&mph, (void __user *)__xn_reg_arg1(regs),
                                     sizeof(mph)))
@@ -1901,7 +1916,9 @@ static int __rt_cond_wait_epilogue(struct pt_regs *regs)
 
        lockcnt = __xn_reg_arg2(regs);
 
-       return rt_cond_wait_epilogue(mutex, lockcnt);
+       err = rt_cond_wait_epilogue(mutex, lockcnt);
+
+       return err == 0 ? rt_task_errno : err;
 }
 
 /*
@@ -4090,7 +4107,8 @@ static xnsysent_t __systab[] = {
        [__native_cond_bind] = {&__rt_cond_bind, __xn_exec_conforming},
        [__native_cond_delete] = {&__rt_cond_delete, __xn_exec_any},
        [__native_cond_wait_prologue] = 
-               {&__rt_cond_wait_prologue, __xn_exec_primary},
+               {&__rt_cond_wait_prologue, 
+                __xn_exec_primary | __xn_exec_norestart},
        [__native_cond_wait_epilogue] = 
                {&__rt_cond_wait_epilogue, __xn_exec_primary},
        [__native_cond_signal] = {&__rt_cond_signal, __xn_exec_any},


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

Reply via email to