{"action":"created","issue":{"url":"https://api.github.com/repos/klemens-morgenstern/boost-process/issues/143","repository_url":"https://api.github.com/repos/klemens-morgenstern/boost-process","labels_url":"https://api.github.com/repos/klemens-morgenstern/boost-process/issues/143/labels{/name}","comments_url":"https://api.github.com/repos/klemens-morgenstern/boost-process/issues/143/comments","events_url":"https://api.github.com/repos/klemens-morgenstern/boost-process/issues/143/events","html_url":"https://github.com/klemens-morgenstern/boost-process/issues/143","id":297869332,"number":143,"title":"Same io_context required for all child instances on UNIX","user":{"login":"amerry","id":8223327,"avatar_url":"https://avatars0.githubusercontent.com/u/8223327?v=4","gravatar_id":"","url":"https://api.github.com/users/amerry","html_url":"https://github.com/amerry","followers_url":"https://api.github.com/users/amerry/followers","following_url":"https://api.github.com/users/amerry/following{/other_user}","gists_url":"https://api.github.com/users/amerry/gists{/gist_id}","starred_url":"https://api.github.com/users/amerry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amerry/subscriptions","organizations_url":"https://api.github.com/users/amerry/orgs","repos_url":"https://api.github.com/users/amerry/repos","events_url":"https://api.github.com/users/amerry/events{/privacy}","received_events_url":"https://api.github.com/users/amerry/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2018-02-16T17:54:11Z","updated_at":"2018-02-20T10:14:33Z","closed_at":null,"author_association":"NONE","body":"This is an issue discussed in the comments of #99, #109 and #112. I hope you don't mind me pulling it out into a separate issue - hopefully this will be easier for people to find and track, as this applies to waiting and exit statuses in general, and not just `wait_for` and `wait_until`. I've summarised my understanding of the problem below.\r\n\r\nWhen you pass an `io_context` into the constructor of a `child` instance, it installs a service on that `io_context` that will watch for `SIGCHLD` and call `::waitpid(0, ...)`, catching *any* exited child process.\r\n\r\nIf you use different `io_context` instances for difference `child` instances, those `::waitpid` calls will race (actually, I believe one will always win, based on when the signal handler services were installed). This means that some `child` instances will not receive any notification of having exited, and so won't find out about their exit status.\r\n\r\nI think this should be solvable in the same way that ASIO solves the \"global state\" issue with signals - by passing the updates around the different `sigchld_service` instances.\r\n\r\nHowever, this will not solve the issue for `child` instances that you don't pass any `io_context` into at all. I'm not sure how you might solve that."},"comment":{"url":"https://api.github.com/repos/klemens-morgenstern/boost-process/issues/comments/366930505","html_url":"https://github.com/klemens-morgenstern/boost-process/issues/143#issuecomment-366930505","issue_url":"https://api.github.com/repos/klemens-morgenstern/boost-process/issues/143","id":366930505,"user":{"login":"klemens-morgenstern","id":8020376,"avatar_url":"https://avatars1.githubusercontent.com/u/8020376?v=4","gravatar_id":"","url":"https://api.github.com/users/klemens-morgenstern","html_url":"https://github.com/klemens-morgenstern","followers_url":"https://api.github.com/users/klemens-morgenstern/followers","following_url":"https://api.github.com/users/klemens-morgenstern/following{/other_user}","gists_url":"https://api.github.com/users/klemens-morgenstern/gists{/gist_id}","starred_url":"https://api.github.com/users/klemens-morgenstern/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/klemens-morgenstern/subscriptions","organizations_url":"https://api.github.com/users/klemens-morgenstern/orgs","repos_url":"https://api.github.com/users/klemens-morgenstern/repos","events_url":"https://api.github.com/users/klemens-morgenstern/events{/privacy}","received_events_url":"https://api.github.com/users/klemens-morgenstern/received_events","type":"User","site_admin":false},"created_at":"2018-02-20T10:14:33Z","updated_at":"2018-02-20T10:14:33Z","author_association":"OWNER","body":"The problem with the services would be that it would only work for other services, which would be a problem, because you might try to wait another way (e.g. using `child().wait`).\r\n\r\nI think it's just a bug is [here](https://github.com/klemens-morgenstern/boost-process/blob/develop/include/boost/process/detail/posix/sigchld_service.hpp#L81), the `::waitpid` should specify the `pid` we are waiting for.\r\n\r\nSecondly, when I call [signal](http://man7.org/linux/man-pages/man2/signal.2.html) I get the old handler. Now would it be appropriate to check if the signal is for the current `PID` and if not so call the prior one? E.g. in pseudo code:\r\n\r\n```\r\nstruct handler\r\n{\r\n    pid_t pid;\r\n    signalhandler_t old_sig = signal(*this /*wouldn't work, I know*/, SIGCHLD);\r\n\r\n    std::function<void()> handler;\r\n   void operator()()\r\n   {\r\n       auto res = ::waitpid(pid, WNOHANG);\r\n       if (res == 0) //right, pid, has not changed state, ignore\r\n           return;\r\n       else if (res > 0)\r\n           handler();\r\n       else //wrong pid, another state changed\r\n       {\r\n            if ((old_sig != SIG_DFL) && (old_sig != SIG_IGN))\r\n                  (*old_sig)(); //call the prior one\r\n       }\r\n   }\r\n};\r\n```"}}
{"actor":{"display_login":"klemens-morgenstern"}}