Add mutex to data access

This commit is contained in:
hodasemi 2018-09-14 14:08:44 +02:00
parent 21cc37e80c
commit dce4df7893
3 changed files with 80 additions and 55 deletions

6
Cargo.lock generated
View file

@ -339,12 +339,12 @@ dependencies = [
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.35 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openssl-sys"
version = "0.9.35"
version = "0.9.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
@ -802,7 +802,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
"checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985"
"checksum openssl-sys 0.9.35 (registry+https://github.com/rust-lang/crates.io-index)" = "912f301a749394e1025d9dcddef6106ddee9252620e6d0a0e5f8d0681de9b129"
"checksum openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)" = "409d77eeb492a1aebd6eb322b2ee72ff7c7496b4434d98b3bf8be038755de65e"
"checksum opus 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e9059a7daf1e6665eb88c4a95ca9ff393a6d276fd66e9d85191280d7e5ec18b"
"checksum opus-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fad8b294f482f7972fa466b1c64d5a564e4ee6975599d80483ee4fa83f25b6ec"
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"

View file

@ -1,7 +1,5 @@
use parking_lot;
use youtube::convert_file_name;
use serenity;
use serenity::client::CACHE;
use serenity::model::id::{ChannelId, GuildId};
@ -29,9 +27,9 @@ pub struct Song {
}
pub struct MediaData {
playlist: RefCell<Vec<Song>>,
playlist: Mutex<RefCell<Vec<Song>>>,
current_song: Mutex<RefCell<Option<LockedAudio>>>,
watcher_thread: RefCell<Option<JoinHandle<()>>>,
watcher_thread: Mutex<RefCell<Option<JoinHandle<()>>>>,
}
fn guild_id(channel_id: ChannelId) -> Option<GuildId> {
@ -59,8 +57,13 @@ impl MediaData {
self.current_song.lock().unwrap()
}
fn playlist_mut(&self) -> MutexGuard<RefCell<Vec<Song>>> {
self.playlist.lock().unwrap()
}
fn reset_thread(&self) {
*self.watcher_thread.borrow_mut() = None;
let thread_mutex = self.watcher_thread.lock().unwrap();
*thread_mutex.borrow_mut() = None;
}
fn start_thread(
@ -73,7 +76,8 @@ impl MediaData {
let media_clone = media.clone();
let manager_clone = manager_lock.clone();
let mut watcher_mut = media.watcher_thread.borrow_mut();
let thread_mutex = media.watcher_thread.lock().unwrap();
let mut watcher_mut = thread_mutex.borrow_mut();
if watcher_mut.is_none() {
*watcher_mut = Some(thread::spawn(move || loop {
@ -86,9 +90,11 @@ impl MediaData {
let audio = song_lock.lock();
if audio.finished {
let playlist = media_clone.playlist_mut();
if !Self::next_song(
song,
media_clone.playlist.borrow_mut().deref_mut(),
playlist.borrow_mut().deref_mut(),
channel_id,
&manager_clone,
) {
@ -107,40 +113,42 @@ impl MediaData {
continue;
}
let mut playlist = media_clone.playlist.borrow_mut();
{
let playlist_mutex = media_clone.playlist_mut();
let mut playlist = playlist_mutex.borrow_mut();
if !playlist.is_empty() {
let mut manager = manager_clone.lock();
if !playlist.is_empty() {
let mut manager = manager_clone.lock();
if let Some(handler) =
handler(check_option!(guild_id(channel_id)), &mut manager)
{
let first = playlist.remove(0);
if let Some(handler) =
handler(check_option!(guild_id(channel_id)), &mut manager)
{
let first = playlist.remove(0);
*borrow = Some(handler.play_returning(first.source));
*borrow = Some(handler.play_returning(first.source));
super::check_msg(channel_id.say(format!(
"Playing song: {}",
super::youtube::convert_file_name(first.name)
)));
super::check_msg(
channel_id.say(format!("Playing song: {}", first.name)),
);
} else {
return;
}
} else {
manager_clone
.lock()
.remove(check_option!(guild_id(channel_id)));
media_clone.reset_thread();
println!("left channel");
return;
}
} else {
manager_clone
.lock()
.remove(check_option!(guild_id(channel_id)));
media_clone.reset_thread();
println!("left channel");
return;
}
}
let five_sec = time::Duration::from_secs(5);
thread::sleep(five_sec);
let two_sec = time::Duration::from_secs(2);
thread::sleep(two_sec);
}));
}
}
@ -168,10 +176,7 @@ impl MediaData {
*song = handler.play_returning(first.source);
super::check_msg(channel_id.say(format!(
"Playing song: {}",
super::youtube::convert_file_name(first.name)
)));
super::check_msg(channel_id.say(format!("Playing song: {}", first.name)));
return true;
}
@ -184,9 +189,9 @@ impl MediaData {
impl Default for MediaData {
fn default() -> MediaData {
MediaData {
playlist: RefCell::new(Vec::new()),
playlist: Mutex::new(RefCell::new(Vec::new())),
current_song: Mutex::new(RefCell::new(None)),
watcher_thread: RefCell::new(None),
watcher_thread: Mutex::new(RefCell::new(None)),
}
}
}
@ -284,15 +289,22 @@ impl serenity::framework::standard::Command for Play {
Err(why) => {
println!("Err starting source: {:?}", why);
super::check_msg(msg.channel_id.say("Error sourcing ffmpeg"));
super::check_msg(
msg.channel_id
.say(format!("Error using youtube-dl: {}", why)),
);
return Ok(());
}
};
self.media.playlist.borrow_mut().append(&mut source);
{
let playlist_mutex = self.media.playlist_mut();
playlist_mutex.borrow_mut().append(&mut source);
}
let mut manager_lock = ctx.data
let mut manager_lock = ctx
.data
.lock()
.get::<super::VoiceManager>()
.cloned()
@ -357,16 +369,19 @@ impl serenity::framework::standard::Command for List {
) -> ::std::result::Result<(), serenity::framework::standard::CommandError> {
let mut output = String::new();
let playlist = self.media.playlist.borrow();
{
let playlist_mutex = self.media.playlist_mut();
let playlist = playlist_mutex.borrow();
output += &format!(
"{} {} queued\n",
playlist.len(),
if playlist.len() == 1 { "song" } else { "songs" }
);
output += &format!(
"{} {} queued\n",
playlist.len(),
if playlist.len() == 1 { "song" } else { "songs" }
);
for (i, song) in playlist.iter().enumerate() {
output += &format!("\t{}.\t{}\n", i + 1, convert_file_name(song.name.clone()));
for (i, song) in playlist.iter().enumerate() {
output += &format!("\t{}.\t{}\n", i + 1, song.name.clone());
}
}
super::check_msg(msg.channel_id.say(output));
@ -429,7 +444,10 @@ impl serenity::framework::standard::Command for Stop {
msg: &serenity::model::channel::Message,
_: serenity::framework::standard::Args,
) -> ::std::result::Result<(), serenity::framework::standard::CommandError> {
self.media.playlist.borrow_mut().clear();
{
let playlist = self.media.playlist_mut();
playlist.borrow_mut().clear();
}
{
let song = self.media.song_mut();
@ -437,7 +455,8 @@ impl serenity::framework::standard::Command for Stop {
}
{
let mut manager_lock = ctx.data
let mut manager_lock = ctx
.data
.lock()
.get::<super::VoiceManager>()
.cloned()

View file

@ -53,7 +53,13 @@ fn convert_output(out: &Output) -> Result<Vec<String>, String> {
}
}
Ok(files)
let mut mp3s = Vec::new();
for file in files {
mp3s.push(str::replace(file.as_str(), ".webm", ".mp3").to_string());
}
Ok(mp3s)
}
Err(_) => Err("error converting output".to_string()),
@ -61,7 +67,7 @@ fn convert_output(out: &Output) -> Result<Vec<String>, String> {
}
pub fn youtube_dl(uri: &str) -> Result<Vec<Song>, String> {
let args = ["-f", "webm[abr>0]/bestaudio/best", uri];
let args = ["-x", "--audio-format", "mp3", "--audio-quality", "5", uri];
let out = match Command::new("youtube-dl")
.args(&args)