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

Author: Matthias Schneider <ma30002...@yahoo.de>
Date:   Tue Apr  8 09:03:12 2014 +0200

copperplate: handle syscall restart upon EINTR

---

 lib/copperplate/notifier.c  |   33 ++++++++++++++++++++++++---------
 lib/copperplate/threadobj.c |   12 ++++++++++--
 2 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/lib/copperplate/notifier.c b/lib/copperplate/notifier.c
index 86744d4..64812d7 100644
--- a/lib/copperplate/notifier.c
+++ b/lib/copperplate/notifier.c
@@ -60,7 +60,9 @@ static void notifier_sighandler(int sig, siginfo_t *siginfo, 
void *uc)
                 * notified.
                 */
                rfds = notifier_rset;
-               ret = __STD(select(max_rfildes + 1, &rfds, NULL, NULL, &tv));
+               do
+                       ret = __STD(select(max_rfildes + 1, &rfds, NULL, NULL, 
&tv));
+               while (ret == -1 && errno == EINTR);
                if (ret <= 0)
                        goto hand_over;
        }
@@ -86,9 +88,13 @@ static void notifier_sighandler(int sig, siginfo_t *siginfo, 
void *uc)
                if (nf->owner && nf->owner != tid)
                        continue;
 
-               while (__STD(read(nf->psfd[0], &c, 1)) > 0)
-                       /* Callee must run async-safe code only. */
-                       nf->callback(nf);
+               do {
+                       ret = __STD(read(nf->psfd[0], &c, 1)); 
+                       if (ret > 0)
+                               /* Callee must run async-safe code only. */
+                               nf->callback(nf);
+               } while (ret > 0 || (ret == -1 && errno == EINTR));
+
                return;
        }
 
@@ -239,8 +245,11 @@ int notifier_signal(struct notifier *nf)
         * since we may be immediately preempted by the notification
         * signal in case we notify the current thread.
         */
-       if (kick)
-               ret = __STD(write(fd, &c, 1));
+       if (kick) {
+               do
+                       ret = __STD(write(fd, &c, 1));
+               while (ret == -1 && errno == EINTR);
+       }
 
        return 0;
 }
@@ -268,8 +277,11 @@ int notifier_release(struct notifier *nf)
 
        read_unlock(&nf->lock);
 
-       if (kick)
-               ret = __STD(write(fd, &c, 1));
+       if (kick) {
+               do
+                       ret = __STD(write(fd, &c, 1)); 
+               while (ret == -1 && errno == EINTR);
+       }
 
        return 0;
 }
@@ -279,7 +291,10 @@ int notifier_wait(const struct notifier *nf) /* sighandler 
context */
        int ret;
        char c;
 
-       ret = __STD(read(nf->pwfd[0], &c, 1));
+       do
+               ret = __STD(read(nf->pwfd[0], &c, 1)); 
+       while (ret == -1 && errno == EINTR);
+
        assert(ret == 1); (void)ret;
 
        return 0;
diff --git a/lib/copperplate/threadobj.c b/lib/copperplate/threadobj.c
index 79fcdb2..d82473d 100644
--- a/lib/copperplate/threadobj.c
+++ b/lib/copperplate/threadobj.c
@@ -1093,7 +1093,9 @@ int threadobj_sleep(struct timespec *ts)
         */
        current->run_state = __THREAD_S_DELAYED;
        threadobj_save_timeout(&current->core, ts);
-       ret = -__RT(clock_nanosleep(CLOCK_COPPERPLATE, TIMER_ABSTIME, ts, 
NULL));
+       do
+               ret = -__RT(clock_nanosleep(CLOCK_COPPERPLATE, TIMER_ABSTIME, 
ts, NULL));
+       while (ret == -EINTR);
        current->run_state = __THREAD_S_RUNNING;
 
        return ret;
@@ -1152,13 +1154,19 @@ static void cancel_sync(struct threadobj *thobj) /* 
thobj->lock held */
 
        pthread_cancel(tid);
 
+       if (sem) {
+               do
+                       ret = __STD(sem_wait(sem));
+               while (ret == -1 && errno == EINTR);
+       }
+
        /*
         * Not being able to sync up with the cancelled thread is not
         * considered fatal, despite it's likely bad news for sure, so
         * that we can keep on cleaning up the mess, hoping for the
         * best.
         */
-       if (sem == NULL || __STD(sem_wait(sem)))
+       if (sem == NULL || ret)
                warning("cannot sync with thread finalizer, %s",
                        symerror(sem ? -errno : ret));
        if (sem) {


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

Reply via email to