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(¤t->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