@@ -2296,6 +2296,32 @@ static auto next_waitpid_timeout(std::chrono::milliseconds this_timeout) {
2296
2296
2297
2297
#endif
2298
2298
2299
+ future<int > reactor::do_waitpid (pid_t pid) {
2300
+ return do_with (int {}, std::chrono::milliseconds (0 ), [pid, this ](int & wstatus,
2301
+ std::chrono::milliseconds& wait_timeout) {
2302
+ return repeat_until_value ([this ,
2303
+ pid,
2304
+ &wstatus,
2305
+ &wait_timeout] {
2306
+ return _thread_pool->submit <syscall_result<pid_t >>([pid, &wstatus] {
2307
+ return wrap_syscall<pid_t >(::waitpid (pid, &wstatus, WNOHANG));
2308
+ }).then ([&wstatus, &wait_timeout](syscall_result<pid_t > ret) mutable {
2309
+ if (ret.result == 0 ) {
2310
+ wait_timeout = next_waitpid_timeout (wait_timeout);
2311
+ return ::seastar::sleep (wait_timeout).then ([] {
2312
+ return make_ready_future<std::optional<int >>();
2313
+ });
2314
+ } else if (ret.result > 0 ) {
2315
+ return make_ready_future<std::optional<int >>(wstatus);
2316
+ } else {
2317
+ ret.throw_if_error ();
2318
+ return make_ready_future<std::optional<int >>(-1 );
2319
+ }
2320
+ });
2321
+ });
2322
+ });
2323
+ }
2324
+
2299
2325
future<int > reactor::waitpid (pid_t pid) {
2300
2326
return _thread_pool->submit <syscall_result<int >>([pid] {
2301
2327
return wrap_syscall<int >(syscall (__NR_pidfd_open, pid, O_NONBLOCK));
@@ -2304,39 +2330,11 @@ future<int> reactor::waitpid(pid_t pid) {
2304
2330
// pidfd_open() was introduced in linux 5.3, so the pidfd.error could be ENOSYS on
2305
2331
// older kernels. But it could be other error like EMFILE or ENFILE. anyway, we
2306
2332
// should always waitpid().
2307
- return do_with (int {}, std::chrono::milliseconds (0 ), [pid, this ](int & wstatus,
2308
- std::chrono::milliseconds& wait_timeout) {
2309
- return repeat_until_value ([this ,
2310
- pid,
2311
- &wstatus,
2312
- &wait_timeout] {
2313
- return _thread_pool->submit <syscall_result<pid_t >>([pid, &wstatus] {
2314
- return wrap_syscall<pid_t >(::waitpid (pid, &wstatus, WNOHANG));
2315
- }).then ([&wstatus, &wait_timeout] (syscall_result<pid_t > ret) mutable {
2316
- if (ret.result == 0 ) {
2317
- wait_timeout = next_waitpid_timeout (wait_timeout);
2318
- return ::seastar::sleep (wait_timeout).then ([] {
2319
- return make_ready_future<std::optional<int >>();
2320
- });
2321
- } else if (ret.result > 0 ) {
2322
- return make_ready_future<std::optional<int >>(wstatus);
2323
- } else {
2324
- ret.throw_if_error ();
2325
- return make_ready_future<std::optional<int >>(-1 );
2326
- }
2327
- });
2328
- });
2329
- });
2333
+ return do_waitpid (pid);
2330
2334
} else {
2331
- return do_with (pollable_fd (file_desc::from_fd (pidfd.result )), int {}, [pid, this ](auto & pidfd, int & wstatus) {
2332
- return pidfd.readable ().then ([pid, &wstatus, this ] {
2333
- return _thread_pool->submit <syscall_result<pid_t >>([pid, &wstatus] {
2334
- return wrap_syscall<pid_t >(::waitpid (pid, &wstatus, WNOHANG));
2335
- });
2336
- }).then ([&wstatus] (syscall_result<pid_t > ret) {
2337
- ret.throw_if_error ();
2338
- assert (ret.result > 0 );
2339
- return make_ready_future<int >(wstatus);
2335
+ return do_with (pollable_fd (file_desc::from_fd (pidfd.result )), [pid, this ](auto & pidfd) {
2336
+ return pidfd.readable ().then ([pid, this ] {
2337
+ return do_waitpid (pid);
2340
2338
});
2341
2339
});
2342
2340
}
0 commit comments