summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/forkfd
Commit message (Collapse)AuthorAgeFilesLines
* Fix forkfd on OS X 10.7 and earlierThiago Macieira2015-01-231-1/+12
| | | | | | | | | | | | | | | | | | | | | | | | dtruss logs show that the signal handler does enter and is active, since it does the first waitid() call, but then returns immediately: waitid(0x0, 0x0, 0x7FFF62D7C468) = 0 0 sigreturn(0x7FFF62D7C9A0, 0x1E, 0x0) = 0 Err#-2 Since there was no error return, we conclude that si_pid was zero on return. Source code for OS X 10.7 confirms that si_pid is set to zero unconditionally, which is rather stupid: http://fxr.watson.org/fxr/source/bsd/kern/kern_exit.c?v=xnu-1699.24.8#L1330 This is fixed for OS X 10.8: http://fxr.watson.org/fxr/source/bsd/kern/kern_exit.c?v=xnu-2050.18.24#L1399 Without that information, we have to scan each child anyway, so just disable the waitid() solution on OS X. This is a "hammer" solution which will get forkfd working. We can later try and detect at runtime whether waitid() is working. Change-Id: Ic5d393bfd36e48a193fcffff13bb584927cdeafe Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
* Fix compilation of non-waittid forkfd() outside of LinuxThiago Macieira2015-01-231-2/+2
| | | | | | | | | | | | | | | POSIX.1 does not guarantee the presence of the si_utime and si_stime members. So instead of trying to set those members to zero, ask the compiler to initialize everything for us. This was found on OS X when HAVE_WAITTID was removed. forkfd.c:192:11: error: no member named 'si_utime' in '__siginfo' forkfd.c:193:11: error: no member named 'si_stime' in '__siginfo' Change-Id: Ic5d393bfd36e48a193fcffff13b90aa6ccf592ae Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
* Use waitid with WNOWAIT in forkfdThiago Macieira2015-01-231-2/+88
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The previous implementation required one syscall per child we're waiting on to see which one exited. That means the algorithm was O(n). This implementation uses WNOWAIT to find out which child exited and then goes straight to that one. So it's O(1) on the number of children, but runs 2 * number_of_children_that_exited + 1 syscalls, assuming there are no race conditions with other threads. If there are or if a child not started by forkfd exits, we'll still iterate over each child we're managing to see which one exited. It modifies the existing code so that it will do a waitid() with WNOWAIT to check on the status of the child: if the child has exited, we'll try to lock the entry so only one thread will do the final wait(). In the case we read the PID, then the child exited, was reaped by another thread, the PID got recycled and that child exited again, we'll fail to lock the ProcessInfo entry so no harm comes. If by an absurd coincidence this other child was started by forkfd() and its ProcessInfo is exactly the one we are looking at, then we'll succeed in locking but that's a benign race: we'll do what the other thread was trying to do and the other thread will give up. Future improvements to the algorithm are discussed in the Gerrit change. Change-Id: Ie74836dbc388cd9b3fa375a41a8d944602a32df1 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Fix forkfd build when O_CLOEXEC isn't defined.Thiago Macieira2015-01-162-3/+3
| | | | | | | | | | | | | | | | | | O_CLOEXEC was introduced with the 2008 revision of POSIX.1 and it's the only way of doing child processes safely with fork(2) in multithreaded applications. But we need to support pre-2008 systems, so we can't use that constant. So let's just choose two arbitrary values for both of our constants -- we need to change both because we need to be sure that FFD_CLOEXEC won't be the same as FFD_NONBLOCK. Linux will probably implement them to the O_ constants, like epoll, signalfd and inotify have done. Change-Id: I20a5aa6e6264e7a219e19759eeb8747e01df05ff Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
* Import forkfd into qtbaseThiago Macieira2014-11-043-0/+629
forkfd is a tool that I designed to facilitate spawning sub-processes. It's implemented in C, not C++, so that it could be used by other libraries as well. To work in all platforms Qt supports and with all compilers Qt is known to work with, we'll need to replace the generic GCC atomics that are provided here. Change-Id: I0a6f86cc220a7c52c8d4284bb7140c56d5cf836a Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>