mirror of
https://github.com/danbulant/cushy
synced 2026-06-18 14:01:10 +00:00
Allowing change callbacks to recurse still
The last fix had a panic where a guard should have been allowed to be created. Change callbacks detect when they are about to be fired from themselves, and prevent the deadlock.
This commit is contained in:
parent
e54bbd743d
commit
2045d5fb4a
1 changed files with 13 additions and 10 deletions
23
src/value.rs
23
src/value.rs
|
|
@ -1227,7 +1227,7 @@ impl<T> Dynamic<T> {
|
|||
}
|
||||
|
||||
fn lock_inner<const READONLY: bool>(&self) -> DynamicGuard<'_, T, READONLY> {
|
||||
let guard = self.0.state().expect("deadlocked");
|
||||
let mut guard = self.0.state().expect("deadlocked");
|
||||
// Before allowing a lock, we need to ensure that the current change
|
||||
// callbacks aren't executing. Otherwise, during drop of this guard, if
|
||||
// we notify of changes from a second thread than one set is already
|
||||
|
|
@ -1235,16 +1235,19 @@ impl<T> Dynamic<T> {
|
|||
// other and deadlocking. By ensuring a single guard and change
|
||||
// callbacks cycle can exist at any one time, we prevent this deadlock.
|
||||
if !READONLY && guard.callbacks.currently_executing.lock().thread.is_some() {
|
||||
let current_thread_id = std::thread::current().id();
|
||||
let callbacks = guard.callbacks.clone();
|
||||
let mut executing = callbacks.currently_executing.lock();
|
||||
loop {
|
||||
match &executing.thread {
|
||||
Some(th) if th == ¤t_thread_id => panic!("deadlocked"),
|
||||
Some(_) => callbacks.sync.wait(&mut executing),
|
||||
None => break,
|
||||
};
|
||||
}
|
||||
guard.unlocked(|| {
|
||||
let current_thread_id = std::thread::current().id();
|
||||
let mut executing = callbacks.currently_executing.lock();
|
||||
|
||||
loop {
|
||||
match &executing.thread {
|
||||
Some(th) if th == ¤t_thread_id => break,
|
||||
None => break,
|
||||
Some(_) => callbacks.sync.wait(&mut executing),
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
DynamicGuard {
|
||||
guard: DynamicOrOwnedGuard::Dynamic(guard),
|
||||
|
|
|
|||
Loading…
Reference in a new issue