diff options
Diffstat (limited to 'src/3rdparty/forkfd/forkfd.c')
-rw-r--r-- | src/3rdparty/forkfd/forkfd.c | 79 |
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); |