Block native teardown until viewer and shared mixer cleanup is confirmed
This commit is contained in:
1 parent
16c7d817cc
commit
495d399691
3 files changed
+22
No files matched your search
@@ -74,6 +74,7 @@ object NativeLib {
|
||||
RadioCallController.reset()
|
||||
StreamController.reset(); CallController.reset(); ChatApplication.instance.avatars.stop(); ChatApplication.instance.memberFiles.cancel()
|
||||
CallService.requireReleased() // Не останавливать native при неподтверждённой очистке его media-владельца.
|
||||
StreamPlayerEngine.stopForCore()
|
||||
check(!CallController.blocksMedia()) {
|
||||
LogManager.addLog("ERROR", "Call", "Core teardown blocked: call media preparation still running")
|
||||
"Call media preparation still running"
|
||||
|
||||
@@ -49,6 +49,14 @@ internal object StreamAudioMixer {
|
||||
LogManager.addLog("INFO", "stream", "shared audio output released for call")
|
||||
}
|
||||
|
||||
/** Проверка core teardown без join: живой worker удерживает Android output для retry. */
|
||||
fun requireReleased() = synchronized(lock) {
|
||||
check(inputs.isEmpty() && worker?.isAlive != true) {
|
||||
LogManager.addLog("ERROR", "stream", "core teardown blocked by mixer inputs=${inputs.size} worker=${worker?.state}")
|
||||
"Stream mixer cleanup pending"
|
||||
}
|
||||
}
|
||||
|
||||
private fun run() {
|
||||
var audio: StreamAudioOutput? = null
|
||||
var generated = 0L
|
||||
|
||||
@@ -24,6 +24,19 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
|
||||
private val mutableViewing = MutableStateFlow(false)
|
||||
val viewing: StateFlow<Boolean> = mutableViewing
|
||||
|
||||
/** Main: запросить stop всех viewers; незавершённый cleanup запрещает native stop и допускает повтор. */
|
||||
fun stopForCore() {
|
||||
check(Looper.myLooper() == Looper.getMainLooper()) { "Viewer core teardown requires main" }
|
||||
players.toList().forEach { it.stop() }
|
||||
players.removeAll { player -> synchronized(player.releaseLock) { player.released } && player.worker?.isAlive != true }
|
||||
mutableViewing.value = players.isNotEmpty()
|
||||
check(players.isEmpty()) {
|
||||
LogManager.addLog("ERROR", "stream", "core teardown blocked by viewers count=${players.size}; cleanup retained")
|
||||
"Stream viewers cleanup pending"
|
||||
}
|
||||
StreamAudioMixer.requireReleased()
|
||||
}
|
||||
|
||||
/** Закрыть просмотр и дождаться освобождения AudioTrack/decoder вне main thread. */
|
||||
suspend fun stopForCall() {
|
||||
val stopped = players.toList()
|
||||
|
||||
Reference in new issue
Block a user