| 829 | } |
| 830 | |
| 831 | static cbm_proc_poll_t cbm_subprocess_poll_win(cbm_subprocess_t *process, cbm_proc_result_t *out) { |
| 832 | uint64_t now = cbm_now_ms(); |
| 833 | |
| 834 | if (!process->root_reaped) { |
| 835 | DWORD waited = WaitForSingleObject(process->process, 0); |
| 836 | if (waited == WAIT_OBJECT_0) { |
| 837 | DWORD code = 1; |
| 838 | (void)GetExitCodeProcess(process->process, &code); |
| 839 | cbm_win_capture_root(process, code); |
| 840 | } else if (waited == WAIT_FAILED) { |
| 841 | DWORD code = STILL_ACTIVE; |
| 842 | if (GetExitCodeProcess(process->process, &code) && code != STILL_ACTIVE) { |
| 843 | cbm_win_capture_root(process, code); |
| 844 | } else { |
| 845 | cbm_win_begin_termination(process, now); |
| 846 | cbm_win_force_tree(process, now); |
| 847 | } |
| 848 | } |
| 849 | } |
| 850 | |
| 851 | bool job_known = false; |
| 852 | bool job_active = cbm_win_job_active(process, &job_known); |
| 853 | if (!process->termination_started) { |
| 854 | if (cbm_subprocess_cancellation_requested(process)) { |
| 855 | cbm_win_begin_termination(process, now); |
| 856 | } else if (!process->root_reaped && process->quiet_timeout_ms > 0 && |
| 857 | now - process->last_activity_ms >= (uint64_t)process->quiet_timeout_ms) { |
| 858 | process->timed_out = true; |
| 859 | cbm_win_begin_termination(process, now); |
| 860 | } else if (process->root_reaped && job_active) { |
| 861 | /* Preserve the root's classification while draining escaped work. */ |
| 862 | cbm_win_begin_termination(process, now); |
| 863 | } |
| 864 | } |
| 865 | if (!job_known) { |
| 866 | cbm_win_begin_termination(process, now); |
| 867 | cbm_win_force_tree(process, now); |
| 868 | } |
| 869 | if (process->termination_started && job_active && !process->force_sent && |
| 870 | now - process->termination_started_ms >= (uint64_t)process->cancel_grace_ms) { |
| 871 | cbm_win_force_tree(process, now); |
| 872 | } |
| 873 | if (process->force_started_ms != 0 && |
| 874 | now - process->force_started_ms >= CBM_SUBPROCESS_FORCE_SETTLE_MS && |
| 875 | (!job_known || job_active || !process->root_reaped)) { |
| 876 | return cbm_subprocess_finish_failed(process, out); |
| 877 | } |
| 878 | if (process->root_reaped && !job_active) { |
| 879 | return cbm_subprocess_finish(process, out); |
| 880 | } |
| 881 | return CBM_PROC_POLL_RUNNING; |
| 882 | } |
| 883 | |
| 884 | #else /* POSIX */ |
| 885 |
no test coverage detected