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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Mon Apr 21 12:11:05 2014 +0200

boilerplate/debug: prevent deadlocking on printout lock acquisition

The notification signal (SIGNOTIFY) may cause the recipient thread to
suspend indefinitely, which may happen while holding the printout
serialization lock.

To prevent this, we block the notification signal (if) defined by the
underlying real-time core while holding such lock.

See http://www.xenomai.org/pipermail/xenomai/2014-April/030580.html.

---

 include/boilerplate/ancillaries.h    |    1 +
 include/cobalt/boilerplate/signal.h  |   10 ++++++++++
 include/mercury/boilerplate/signal.h |   15 +++++++++++++++
 lib/boilerplate/ancillaries.c        |    6 ++----
 lib/boilerplate/debug.c              |    6 ++----
 5 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/include/boilerplate/ancillaries.h 
b/include/boilerplate/ancillaries.h
index f1b4118..c8b4ec7 100644
--- a/include/boilerplate/ancillaries.h
+++ b/include/boilerplate/ancillaries.h
@@ -21,6 +21,7 @@
 #include <stdarg.h>
 #include <time.h>
 #include <pthread.h>
+#include <boilerplate/signal.h>
 
 extern struct timespec __init_date;
 
diff --git a/include/cobalt/boilerplate/signal.h 
b/include/cobalt/boilerplate/signal.h
index 2f7ca95..4807a51 100644
--- a/include/cobalt/boilerplate/signal.h
+++ b/include/cobalt/boilerplate/signal.h
@@ -20,4 +20,14 @@
 
 #include <cobalt/signal.h>
 
+#define SIGSAFE_LOCK_ENTRY(__safelock)                                 \
+       do {                                                            \
+               push_cleanup_lock(__safelock);                          \
+               write_lock(__safelock);
+
+#define SIGSAFE_LOCK_EXIT(__safelock)                                  \
+               write_unlock(__safelock);                               \
+               pop_cleanup_lock(&__safelock);                          \
+       } while (0)
+
 #endif /* _COBALT_BOILERPLATE_SIGNAL_H */
diff --git a/include/mercury/boilerplate/signal.h 
b/include/mercury/boilerplate/signal.h
index 61efda4..14523cd 100644
--- a/include/mercury/boilerplate/signal.h
+++ b/include/mercury/boilerplate/signal.h
@@ -27,4 +27,19 @@
 #define SIGNOTIFY      (SIGRTMIN + 8) /* Internal notification */
 #define SIGRELS                (SIGRTMIN + 9) /* Syscall abort */
 
+#define SIGSAFE_LOCK_ENTRY(__safelock)                                 \
+       do {                                                            \
+               sigset_t __safeset, __oldsafeset;                       \
+               sigemptyset(&__safeset);                                \
+               sigaddset(&__safeset, SIGNOTIFY);                       \
+               pthread_sigmask(SIG_BLOCK, &__safeset, &__oldsafeset);  \
+               push_cleanup_lock(__safelock);                          \
+               write_lock(__safelock);
+
+#define SIGSAFE_LOCK_EXIT(__safelock)                                  \
+               write_unlock(__safelock);                               \
+               pop_cleanup_lock(&__safelock);                          \
+               pthread_sigmask(SIG_SETMASK, &__oldsafeset, NULL);      \
+       } while (0)
+
 #endif /* _MERCURY_BOILERPLATE_SIGNAL_H */
diff --git a/lib/boilerplate/ancillaries.c b/lib/boilerplate/ancillaries.c
index 688aeee..2d5f532 100644
--- a/lib/boilerplate/ancillaries.c
+++ b/lib/boilerplate/ancillaries.c
@@ -48,8 +48,7 @@ void __printout(const char *name, const char *header,
        ms = ns / 1000000ULL;
        us = (ns % 1000000ULL) / 1000ULL;
 
-       push_cleanup_lock(&__printlock);
-       write_lock(&__printlock);
+       SIGSAFE_LOCK_ENTRY(&__printlock);
 
        fprintf(fp, "%4d\"%.3d.%.3d| ",
                (int)ms / 1000, (int)ms % 1000, (int)us);
@@ -62,8 +61,7 @@ void __printout(const char *name, const char *header,
        fputc('\n', fp);
        fflush(fp);
 
-       write_unlock(&__printlock);
-       pop_cleanup_lock(&__printlock);
+       SIGSAFE_LOCK_EXIT(&__printlock);
 }
 
 void __warning(const char *name, const char *fmt, va_list ap)
diff --git a/lib/boilerplate/debug.c b/lib/boilerplate/debug.c
index d77b1d9..d9c82b5 100644
--- a/lib/boilerplate/debug.c
+++ b/lib/boilerplate/debug.c
@@ -127,8 +127,7 @@ void backtrace_dump(struct backtrace_data *btd)
        if (btd == NULL)
                btd = &main_btd;
 
-       push_cleanup_lock(&__printlock);
-       read_lock(&__printlock);
+       SIGSAFE_LOCK_ENTRY(&__printlock);
 
        if (btd->inner == NULL)
                goto no_error;
@@ -149,8 +148,7 @@ void backtrace_dump(struct backtrace_data *btd)
        flush_backtrace(btd);
 
 no_error:
-       read_unlock(&__printlock);
-       pop_cleanup_lock(&__printlock);
+       SIGSAFE_LOCK_EXIT(&__printlock);
 }
 
 void backtrace_check(void)


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

Reply via email to