From 3f970c20f9afd5c9a1cc14d7f69882e13f6aaf1b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 11 Sep 2012 15:36:54 +0200 Subject: [PATCH] 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. Change-Id: I62dc8f5fa14c1dd453d13e4053c642bd78fbc468 Reviewed-by: Qt Doc Bot Reviewed-by: Oswald Buddenhagen Reviewed-by: Shane Kearns Reviewed-by: Peter Hartmann --- src/corelib/io/qprocess_unix.cpp | 6 +++++- src/network/socket/qnativesocketengine_unix.cpp | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index d3c2cd9..137702c 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -953,11 +953,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.load()) { + // 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.store(1); } } diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 4b22f1c..c73bbed 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -103,11 +103,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.load()) { + // 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.store(1); } #else // Posix signals are not supported by the underlying platform -- 2.7.4