mirror of https://github.com/jetkvm/kvm.git
fix(audio): improve process termination handling in input supervisor
Add more robust process state checking and error handling during audio input server shutdown. Use signal 0 to verify process existence before killing and handle various edge cases. Also improve logging to better track shutdown outcomes.
This commit is contained in:
parent
dfbf9249b9
commit
950ca2bd99
|
@ -711,6 +711,9 @@ func cgoAudioReadEncode(buf []byte) (int, error) {
|
||||||
|
|
||||||
// Skip initialization check for now to avoid CGO compilation issues
|
// Skip initialization check for now to avoid CGO compilation issues
|
||||||
// TODO: Add proper initialization state checking
|
// TODO: Add proper initialization state checking
|
||||||
|
// Note: The C code already has comprehensive state tracking with capture_initialized,
|
||||||
|
// capture_initializing, playback_initialized, and playback_initializing flags.
|
||||||
|
// When CGO environment is properly configured, this should check C.capture_initialized.
|
||||||
|
|
||||||
n := C.jetkvm_audio_read_encode(unsafe.Pointer(&buf[0]))
|
n := C.jetkvm_audio_read_encode(unsafe.Pointer(&buf[0]))
|
||||||
if n < 0 {
|
if n < 0 {
|
||||||
|
|
|
@ -152,27 +152,49 @@ func (ais *AudioInputSupervisor) Stop() {
|
||||||
|
|
||||||
// Wait for graceful shutdown with timeout
|
// Wait for graceful shutdown with timeout
|
||||||
done := make(chan error, 1)
|
done := make(chan error, 1)
|
||||||
|
var waitErr error
|
||||||
go func() {
|
go func() {
|
||||||
done <- ais.cmd.Wait()
|
waitErr = ais.cmd.Wait()
|
||||||
|
done <- waitErr
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case <-done:
|
||||||
ais.logger.Info().Msg("Audio input server subprocess stopped gracefully")
|
if waitErr != nil {
|
||||||
|
ais.logger.Info().Err(waitErr).Msg("Audio input server subprocess stopped with error")
|
||||||
|
} else {
|
||||||
|
ais.logger.Info().Msg("Audio input server subprocess stopped gracefully")
|
||||||
|
}
|
||||||
case <-time.After(GetConfig().InputSupervisorTimeout):
|
case <-time.After(GetConfig().InputSupervisorTimeout):
|
||||||
// Force kill if graceful shutdown failed
|
// Force kill if graceful shutdown failed
|
||||||
ais.logger.Warn().Msg("Audio input server subprocess did not stop gracefully, force killing")
|
ais.logger.Warn().Msg("Audio input server subprocess did not stop gracefully, force killing")
|
||||||
// Check if process is still alive before attempting to kill
|
// Use a more robust approach to check if process is still alive
|
||||||
if ais.cmd != nil && ais.cmd.Process != nil {
|
if ais.cmd != nil && ais.cmd.Process != nil {
|
||||||
// Check process state to avoid "process already finished" error
|
// Try to send signal 0 to check if process exists
|
||||||
if ais.cmd.ProcessState == nil {
|
if err := ais.cmd.Process.Signal(syscall.Signal(0)); err == nil {
|
||||||
err := ais.cmd.Process.Kill()
|
// Process is still alive, force kill it
|
||||||
if err != nil {
|
if killErr := ais.cmd.Process.Kill(); killErr != nil {
|
||||||
ais.logger.Error().Err(err).Msg("Failed to kill audio input server subprocess")
|
// Only log error if it's not "process already finished"
|
||||||
|
if !strings.Contains(killErr.Error(), "process already finished") {
|
||||||
|
ais.logger.Error().Err(killErr).Msg("Failed to kill audio input server subprocess")
|
||||||
|
} else {
|
||||||
|
ais.logger.Debug().Msg("Audio input server subprocess already finished during kill attempt")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ais.logger.Info().Msg("Audio input server subprocess force killed successfully")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ais.logger.Info().Msg("Audio input server subprocess already finished")
|
ais.logger.Debug().Msg("Audio input server subprocess already finished")
|
||||||
}
|
}
|
||||||
|
// Wait a bit for the kill to take effect and collect the exit status
|
||||||
|
go func() {
|
||||||
|
select {
|
||||||
|
case <-done:
|
||||||
|
// Process finished
|
||||||
|
case <-time.After(1 * time.Second):
|
||||||
|
// Give up waiting
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue