summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/forkfd/forkfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/forkfd/forkfd.c')
-rw-r--r--src/3rdparty/forkfd/forkfd.c79
1 files changed, 47 insertions, 32 deletions
diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c
index a8205065c5..5710608d6d 100644
--- a/src/3rdparty/forkfd/forkfd.c
+++ b/src/3rdparty/forkfd/forkfd.c
@@ -1,37 +1,25 @@
/****************************************************************************
**
** Copyright (C) 2014 Intel Corporation
+** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
**
****************************************************************************/
@@ -58,6 +46,10 @@
# include <sys/eventfd.h>
#endif
+#if _POSIX_VERSION-0 >= 200809L || _XOPEN_VERSION-0 >= 500
+# define HAVE_WAITID 1
+#endif
+
#if defined(__APPLE__)
/* Up until OS X 10.7, waitid(P_ALL, ...) will return success, but will not
* fill in the details of the dead child. That means waitid is not useful to us.
@@ -66,11 +58,9 @@
*/
# include <Availability.h>
# include <AvailabilityMacros.h>
-# if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
-# define HAVE_WAITID 1
+# if MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
+# define HAVE_BROKEN_WAITID_ALL 1
# endif
-#elif _POSIX_VERSION-0 >= 200809L || _XOPEN_VERSION-0 >= 500
-# define HAVE_WAITID 1
#endif
#ifndef FFD_ATOMIC_RELAXED
@@ -115,6 +105,12 @@ static struct sigaction old_sigaction;
static pthread_once_t forkfd_initialization = PTHREAD_ONCE_INIT;
static ffd_atomic_int forkfd_status = FFD_ATOMIC_INIT(0);
+#ifdef HAVE_BROKEN_WAITID_ALL
+static int waitid_p_all_works = 0;
+#else
+static const int waitid_p_all_works = 1;
+#endif
+
static ProcessInfo *tryAllocateInSection(Header *header, ProcessInfo entries[], int maxCount)
{
/* we use ACQUIRE here because the signal handler might have released the PID */
@@ -246,6 +242,9 @@ static void sigchld_handler(int signum)
memset(&info, 0, sizeof info);
#ifdef HAVE_WAITID
+ if (!waitid_p_all_works)
+ goto search_arrays;
+
/* be optimistic: try to see if we can get the child that exited */
search_next_child:
/* waitid returns -1 ECHILD if there are no further children at all;
@@ -298,6 +297,8 @@ search_next_child:
* belongs to one of the chained SIGCHLD handlers. However, there might be another
* child that exited and does belong to us, so we need to check each one individually.
*/
+
+search_arrays:
#endif
for (i = 0; i < (int)sizeofarray(children.entries); ++i) {
@@ -352,6 +353,20 @@ chain_handler:
static void forkfd_initialize()
{
+#if defined(HAVE_BROKEN_WAITID_ALL)
+ pid_t pid = fork();
+ if (pid == 0) {
+ _exit(0);
+ } else if (pid > 0) {
+ siginfo_t info;
+ waitid(P_ALL, 0, &info, WNOWAIT | WEXITED);
+ waitid_p_all_works = (info.si_pid != 0);
+
+ // now really reap the child
+ waitid(P_PID, pid, &info, WEXITED);
+ }
+#endif
+
/* install our signal handler */
struct sigaction action;
memset(&action, 0, sizeof action);