fix: unsubscribe deadlock (#101)

This commit is contained in:
Théo Monnom
2023-06-30 11:08:05 +02:00
committed by GitHub
parent c7c82cc693
commit 046ae8c22b
3 changed files with 69 additions and 16 deletions
+60 -13
View File
@@ -11,7 +11,7 @@ use livekit::webrtc::audio_stream::native::NativeAudioStream;
use livekit::SimulateScenario;
use parking_lot::deadlock;
use parking_lot::Mutex;
use std::collections::{HashMap, VecDeque};
use std::collections::HashMap;
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
@@ -61,6 +61,8 @@ struct App {
connection_failure: Option<String>,
room_state: ConnectionState,
auto_subscribe: bool,
// Log events
events: Vec<String>,
}
@@ -100,7 +102,8 @@ pub fn run(rt: tokio::runtime::Runtime) {
lk_url: DEFAULT_URL.to_owned(),
lk_token: DEFAULT_TOKEN.to_owned(),
connection_failure: None,
room_state: ConnectionState::Connected,
room_state: ConnectionState::Unknown,
auto_subscribe: true,
events: Vec::new(),
};
@@ -342,6 +345,9 @@ impl App {
}
fn ui(&mut self, ui: &mut egui::Ui) {
let connecting = self.state.connecting.load(Ordering::SeqCst);
let connected = self.state.session.lock().is_some();
egui::TopBottomPanel::top("top_panel").show(ui.ctx(), |ui| {
egui::menu::bar(ui, |ui| {
ui.menu_button(
@@ -397,11 +403,13 @@ impl App {
});
});
egui::SidePanel::right("room_panel")
egui::SidePanel::left("left_panel")
.resizable(true)
.default_width(256.0)
.show(ui.ctx(), |ui| {
ui.heading("Livekit - Connect to a room");
ui.separator();
ui.add_space(8.0);
ui.monospace("Livekit - Connect to a room");
ui.add_space(8.0);
ui.horizontal(|ui| {
ui.label("URL: ");
@@ -414,10 +422,7 @@ impl App {
});
ui.horizontal(|ui| {
let connecting = self.state.connecting.load(Ordering::SeqCst);
let session = self.state.session.lock();
ui.add_enabled_ui(!connecting && session.is_none(), |ui| {
ui.add_enabled_ui(!connected && !connecting, |ui| {
if ui.button("Connect").clicked() {
self.connection_failure = None;
let _ = self.cmd_tx.send(AsyncCmd::RoomConnect {
@@ -431,13 +436,19 @@ impl App {
ui.spinner();
}
if session.is_some() {
if connected {
if ui.button("Disconnect").clicked() {
let _ = self.cmd_tx.send(AsyncCmd::RoomDisconnect);
}
}
});
ui.horizontal(|ui| {
ui.add_enabled_ui(!connected && !connecting, |ui| {
ui.checkbox(&mut self.auto_subscribe, "Auto Subscribe");
});
});
if let Some(err) = &self.connection_failure {
ui.colored_label(egui::Color32::RED, err);
}
@@ -461,11 +472,47 @@ impl App {
}
});
egui::TopBottomPanel::bottom("bottom_panel")
.default_height(128.0)
egui::SidePanel::right("right_panel")
.resizable(true)
.default_width(256.0)
.show(ui.ctx(), |ui| {
ui.label("Events");
ui.monospace("Tracks");
egui::ScrollArea::vertical().show(ui, |ui| {
// Show all tracks
if let Some(session) = self.state.session.lock().as_ref() {
for (_, participant) in session.room.participants() {
for (_, track) in participant.tracks() {
let TrackPublication::Remote(track) = track else {
unreachable!();
};
ui.group(|ui| {
ui.label(format!("{} {}", track.sid().0, track.name()));
ui.horizontal(|ui| {
ui.label(format!("{:?}", track.source()));
if track.is_subscribed() {
ui.colored_label(egui::Color32::GREEN, "Subscribed");
} else {
ui.colored_label(egui::Color32::RED, "Unsubscribed");
}
if track.is_muted() {
ui.colored_label(egui::Color32::DARK_GRAY, "Muted");
}
});
});
}
}
}
});
});
egui::TopBottomPanel::bottom("bottom_panel")
.resizable(true)
.min_height(32.0)
.show(ui.ctx(), |ui| {
ui.monospace("Events");
egui::ScrollArea::vertical().show(ui, |ui| {
for event in &self.events {
ui.label(event);
@@ -182,7 +182,8 @@ impl RemoteParticipant {
}
// remove tracks that are no longer valid
for (sid, _) in self.inner.tracks.read().iter() {
let tracks = self.inner.tracks.read().clone();
for (sid, _) in &tracks {
if valid_tracks.contains(sid) {
continue;
}
+7 -2
View File
@@ -51,7 +51,7 @@ impl RemoteTrackPublication {
remote: Arc::new(RemoteInner {
info: RwLock::new(RemoteInfo {
subscribed: false,
allowed: false,
allowed: true,
}),
events: Default::default(),
}),
@@ -122,7 +122,12 @@ impl RemoteTrackPublication {
}
pub(crate) fn update_info(&self, info: proto::TrackInfo) {
super::update_info(&self.inner, &TrackPublication::Remote(self.clone()), info);
super::update_info(
&self.inner,
&TrackPublication::Remote(self.clone()),
info.clone(),
);
self.inner.info.write().muted = info.muted;
}
pub(crate) fn on_muted(&self, f: impl Fn(TrackPublication, Track) + Send + 'static) {