Closed dmik closed 6 years ago
Note that using DosSleep(1)
in the waitpid(WNOHANG)
would only be a workaround because there is no guarantee that the scheduler will switch right away to the worker thread to let it add WAITINFO. Although DosSleep(1)
will give up the current time slice to threads with even a lower priority, there is no guarantee that all other threads will get their chance to execute and that the worker thread, even if it gets executed, will be able to insert WAITINFO before its timeslice ends. Some other approach needs to be found.
BTW, although I can't find a direct indication that by the time SIGCHLD is delivered, waitpid
must succeed for that pid, there is an indirect proof: many SIGCHLD handler examples include a call to wait
or waitpid
. E.g. here https://stackoverflow.com/questions/2377811/tracking-the-death-of-a-child-process or here https://www.linuxquestions.org/questions/programming-9/how-a-father-process-know-which-child-process-send-the-signal-sigchld-266290/.
Anyway, currently this scenario is not guaranteed to work in kLIBC. If you compile a test case with the SIGCHLD handler doing waitpid
, you will get the latter returning 0 quite often (at least, it happens here with Qt and the testcase from https://github.com/bitwiseworks/qtbase-os2/issues/42. (Note that normally we don't do waitpid
in the SIGCHLD handler in Qt but I added it there for testing purposes).
With the above commit, both the simple Qt test case and the real tst_QDir test case work like a charm. And I haven't got any regressions so far.
kLIBC needs to guarantee that by the time SIGCHLD is delivered,
waitpid(WNOHANG)
for that child will return its status instead of 0 (which means the child is still running and no status info is available). Currently, it's not the case — depending on how the OS/2 task scheduler switches threads, it may not work as such. I believe this is a violation of POSIX.From https://github.com/bitwiseworks/qtbase-os2/issues/42#issuecomment-431535368: