Skip to content

Commit

Permalink
Fix texture loader deadlock
Browse files Browse the repository at this point in the history
  • Loading branch information
Zerthox committed Jul 15, 2024
1 parent 6e4f14a commit 26eefd6
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "reffect"
version = "0.1.2"
version = "0.1.3"
authors = ["Zerthox"]
edition = "2021"
description = "Customizable effect displays"
Expand Down
21 changes: 16 additions & 5 deletions src/texture_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,14 @@ impl TextureManager {
}
}

fn loader_thread(source: IconSource) {
// FIXME: exit with pending loads causes deadlock between loader & renderer threads
fn loader_thread(source: IconSource) -> bool {
let mut textures = Self::lock();

// check for stop
if textures.loader.is_none() {
return true;
}

if !textures.exists(&source) {
match &source {
IconSource::Unknown | IconSource::Empty => {}
Expand All @@ -52,6 +57,7 @@ impl TextureManager {
}
}
}
false
}

fn exists(&self, source: &IconSource) -> bool {
Expand Down Expand Up @@ -80,7 +86,9 @@ impl TextureManager {
}

pub fn unload() {
if let Some(loader) = Self::lock().loader.take() {
let mut lock = Self::lock();
if let Some(loader) = lock.loader.take() {
drop(lock); // drop to avoid deadlock with loader thread
loader.exit_and_wait();
}
}
Expand Down Expand Up @@ -164,15 +172,18 @@ struct TextureLoader {
}

impl TextureLoader {
fn spawn(callback: impl Fn(IconSource) + Send + 'static) -> Option<Self> {
fn spawn(callback: impl Fn(IconSource) -> bool + Send + 'static) -> Option<Self> {
let (sender, receiver) = mpsc::channel();

let result = thread::Builder::new()
.name("reffect-texture-loader".into())
.spawn(move || {
log::debug!("Texture loader spawn");
while let Ok(source) = receiver.recv() {
callback(source);
let stop = callback(source);
if stop {
break;
}
}
log::debug!("Texture loader exit");
});
Expand Down

0 comments on commit 26eefd6

Please sign in to comment.