summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2012-09-11 15:36:54 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-01-05 14:45:53 +0100
commitf31ff453c3f03ffae21ec9bcd64e9cd93547e6d2 (patch)
treed1ea50c22f491b81630281e6ea077026834d32d9
parentb36bf7507c02f0e3cf32abda49e295fdd94a4848 (diff)
downloadqt4-tools-f31ff453c3f03ffae21ec9bcd64e9cd93547e6d2.tar.gz
Fix thread-safety of qt_ignore_sigpipe
The testAndSet operation would mean another thread could see the value of 1 and proceed to write(2)/sendto(2) before SIGPIPE had been ignored. If the pipe or socket were already closed by then, a SIGPIPE would be delivered to the application with its default action: terminate. (cherry-picked from qtbase commit 3f970c20f9afd5c9a1cc14d7f69882e13f6aaf1b) Change-Id: I62dc8f5fa14c1dd453d13e4053c642bd78fbc468 Reviewed-by: Qt Doc Bot <qt_docbot@qt-project.org> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com> Reviewed-by: Shane Kearns <shane.kearns@accenture.com> Reviewed-by: Peter Hartmann <phartmann@rim.com>
-rw-r--r--src/corelib/io/qprocess_unix.cpp6
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp6
2 files changed, 10 insertions, 2 deletions
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 82d80dcb5b..2feb6a5727 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -962,11 +962,15 @@ static void qt_ignore_sigpipe()
{
// Set to ignore SIGPIPE once only.
static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0);
- if (atom.testAndSetRelaxed(0, 1)) {
+ if (!atom) {
+ // More than one thread could turn off SIGPIPE at the same time
+ // But that's acceptable because they all would be doing the same
+ // action
struct sigaction noaction;
memset(&noaction, 0, sizeof(noaction));
noaction.sa_handler = SIG_IGN;
::sigaction(SIGPIPE, &noaction, 0);
+ atom = 1;
}
}
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index b4e5126381..640a627eaf 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -106,11 +106,15 @@ static void qt_ignore_sigpipe()
#ifndef Q_NO_POSIX_SIGNALS
// Set to ignore SIGPIPE once only.
static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0);
- if (atom.testAndSetRelaxed(0, 1)) {
+ if (!atom) {
+ // More than one thread could turn off SIGPIPE at the same time
+ // But that's acceptable because they all would be doing the same
+ // action
struct sigaction noaction;
memset(&noaction, 0, sizeof(noaction));
noaction.sa_handler = SIG_IGN;
::sigaction(SIGPIPE, &noaction, 0);
+ atom = 1;
}
#else
// Posix signals are not supported by the underlying platform