[ovs-dev] [PATCH] Use pthread_sigmask() in place of sigprocmask(), for thread safety.

Ben Pfaff blp at nicira.com
Wed May 1 18:38:38 UTC 2013


POSIX says that multithreaded programs must not use sigprocmask() but must
use pthread_sigmask() instead.  This commit makes that replacement.

The actual use of signals in Open vSwitch is still not thread safe
following this commit, but this change is a necessary prerequisite for
fixing the other problems.

Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 lib/process.c |    6 +++---
 lib/signals.c |    9 +++++----
 lib/signals.h |    4 ++--
 lib/timeval.c |    4 ++--
 4 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/lib/process.c b/lib/process.c
index 795a136..9fe742c 100644
--- a/lib/process.c
+++ b/lib/process.c
@@ -640,7 +640,7 @@ sigchld_is_blocked(void)
 {
     sigset_t sigs;
 
-    xsigprocmask(SIG_SETMASK, NULL, &sigs);
+    xpthread_sigmask(SIG_SETMASK, NULL, &sigs);
     return sigismember(&sigs, SIGCHLD);
 }
 
@@ -651,11 +651,11 @@ block_sigchld(sigset_t *oldsigs)
 
     sigemptyset(&sigchld);
     sigaddset(&sigchld, SIGCHLD);
-    xsigprocmask(SIG_BLOCK, &sigchld, oldsigs);
+    xpthread_sigmask(SIG_BLOCK, &sigchld, oldsigs);
 }
 
 static void
 unblock_sigchld(const sigset_t *oldsigs)
 {
-    xsigprocmask(SIG_SETMASK, oldsigs, NULL);
+    xpthread_sigmask(SIG_SETMASK, oldsigs, NULL);
 }
diff --git a/lib/signals.c b/lib/signals.c
index 06c2e75..f31bc52 100644
--- a/lib/signals.c
+++ b/lib/signals.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -168,9 +168,10 @@ xsigaction(int signum, const struct sigaction *new, struct sigaction *old)
 }
 
 void
-xsigprocmask(int how, const sigset_t *new, sigset_t *old)
+xpthread_sigmask(int how, const sigset_t *new, sigset_t *old)
 {
-    if (sigprocmask(how, new, old)) {
-        VLOG_FATAL("sigprocmask failed (%s)", strerror(errno));
+    int error = pthread_sigmask(how, new, old);
+    if (error) {
+        VLOG_FATAL("pthread_sigmask failed (%s)", strerror(error));
     }
 }
diff --git a/lib/signals.h b/lib/signals.h
index ac96b0f..641bcbb 100644
--- a/lib/signals.h
+++ b/lib/signals.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011 Nicira, Inc.
+ * Copyright (c) 2008, 2011, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,6 +31,6 @@ void signal_wait(struct signal *);
 const char *signal_name(int signum);
 
 void xsigaction(int signum, const struct sigaction *, struct sigaction *old);
-void xsigprocmask(int how, const sigset_t *, sigset_t *old);
+void xpthread_sigmask(int how, const sigset_t *, sigset_t *old);
 
 #endif /* signals.h */
diff --git a/lib/timeval.c b/lib/timeval.c
index 163de1e..f687c96 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -454,13 +454,13 @@ block_sigalrm(sigset_t *oldsigs)
     sigset_t sigalrm;
     sigemptyset(&sigalrm);
     sigaddset(&sigalrm, SIGALRM);
-    xsigprocmask(SIG_BLOCK, &sigalrm, oldsigs);
+    xpthread_sigmask(SIG_BLOCK, &sigalrm, oldsigs);
 }
 
 static void
 unblock_sigalrm(const sigset_t *oldsigs)
 {
-    xsigprocmask(SIG_SETMASK, oldsigs, NULL);
+    xpthread_sigmask(SIG_SETMASK, oldsigs, NULL);
 }
 
 long long int
-- 
1.7.2.5




More information about the dev mailing list