diff --git a/internal/core/path.go b/internal/core/path.go index 9ad8d73c..47f7b92f 100644 --- a/internal/core/path.go +++ b/internal/core/path.go @@ -438,11 +438,6 @@ outer: rp.Close() } - if pa.onDemandCmd != nil { - pa.onDemandCmd.Close() - pa.Log(logger.Info, "runOnDemand command stopped") - } - if pa.stream != nil { pa.stream.close() } @@ -459,6 +454,16 @@ outer: } } + // close onDemandCmd after the source has been closed. + // this avoids a deadlock in which onDemandCmd is a + // RTSP publisher that sends a TEARDOWN request and waits + // for the response (like FFmpeg), but it can't since + /// the path is already waiting for the command to close. + if pa.onDemandCmd != nil { + pa.onDemandCmd.Close() + pa.Log(logger.Info, "runOnDemand command stopped") + } + pa.parent.OnPathClose(pa) } @@ -520,16 +525,21 @@ func (pa *path) onDemandCloseSource() { pa.source.(sourceStatic).Close() pa.source = nil } else { + if pa.source != nil { + pa.source.(publisher).Close() + pa.doPublisherRemove() + } + + // close onDemandCmd after the source has been closed. + // this avoids a deadlock in which onDemandCmd is a + // RTSP publisher that sends a TEARDOWN request and waits + // for the response (like FFmpeg), but it can't since + /// the path is already waiting for the command to close. if pa.onDemandCmd != nil { pa.onDemandCmd.Close() pa.onDemandCmd = nil pa.Log(logger.Info, "runOnDemand command stopped") } - - if pa.source != nil { - pa.source.(publisher).Close() - pa.doPublisherRemove() - } } }