brettwooldridge / NuProcess

Low-overhead, non-blocking I/O, external Process implementation for Java
Apache License 2.0
710 stars 84 forks source link

BasePosixProcess.destroy can fail racily if a process terminates on its own #130

Closed bturner closed 2 years ago

bturner commented 3 years ago

In Bitbucket Server we have various output handlers that can reach a point where they're satisfied with how much output they've processed before the process completes. When that happens, they call destroy() on the process to let it be terminated early.

However, in some cases our output handlers (which don't know if there's more data or not, given they haven't read it--and don't want to) reach that point and call destroy() at the same time as the process itself finishes outputting data and terminates on its own. When that happens, depending on the exact timing of our destroy() call, we get an error like this:

error   30-Jun-2021 10:05:44    java.lang.RuntimeException: Sending signal failed, return code: -1, last error: 3
error   30-Jun-2021 10:05:44        at com.zaxxer.nuprocess.internal.BasePosixProcess.checkReturnCode(BasePosixProcess.java:639)
error   30-Jun-2021 10:05:44        at com.zaxxer.nuprocess.internal.BasePosixProcess.destroy(BasePosixProcess.java:167)

last error: 3 is ESRCH, indicating no such process. In that case, destroy() should return cleanly because the process it was trying to destroy is no longer running.