mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-11-14 04:43:42 +01:00
fix(mac): take the rule-list locks in one order, so a rule check and a config load cannot deadlock
BEHAVIOUR (lock order only). window.rs (should_manage rule check) took the regex list, then ignore, then manage, then floating; static_config.rs (apply_globals) took ignore, regex, manage, floating. Two threads, one checking a window and one loading the config, could each hold what the other waits for. Same defect as the KDE fix ef1d3ef0; the order is now the KDE one minus the lists macOS lacks: floating, (session floating), ignore, manage, (workspace rules), regex. Both sites acquire in that order and the order is documented at the statics in lib.rs. The other holders (process_event.rs floating -> regex, process_command.rs floating -> session floating, window_manager.rs workspace rules -> regex) already follow it; every other site takes a single rule list. Verified: macOS fake-CC type-check (tools/fast-check) PASS. Not verified: cannot run on Linux; a deadlock is not reproducible by reading anyway. Gate needed: none runnable here; hand check on a Mac (docs/dev/macos-handcheck.md): reload the config while windows open/close.
This commit is contained in:
1 parent
633e7453cd
commit
01b9cbed91
3 files changed
+14
-5
No files matched your search
@@ -122,6 +122,10 @@ lazy_static! {
|
||||
Arc::new(Mutex::new(HashMap::new()));
|
||||
static ref WORKSPACE_MATCHING_RULES: Arc<Mutex<Vec<WorkspaceMatchingRule>>> =
|
||||
Arc::new(Mutex::new(Vec::new()));
|
||||
// LOCK ORDER for the rule lists (as in the KDE tree, minus the lists macOS does not have):
|
||||
// FLOATING_APPLICATIONS, SESSION_FLOATING_APPLICATIONS, IGNORE_IDENTIFIERS, MANAGE_IDENTIFIERS,
|
||||
// WORKSPACE_MATCHING_RULES, REGEX_IDENTIFIERS. Take the ones you need in that order and never
|
||||
// the other way round; a thread that does can deadlock with one that does not.
|
||||
static ref REGEX_IDENTIFIERS: Arc<Mutex<HashMap<String, Regex>>> =
|
||||
Arc::new(Mutex::new(HashMap::new()));
|
||||
static ref MANAGE_IDENTIFIERS: Arc<Mutex<Vec<MatchingRule>>> = Arc::new(Mutex::new(vec![]));
|
||||
|
||||
@@ -545,16 +545,18 @@ impl ApplyGlobals for StaticConfig {
|
||||
// transparency_manager::TRANSPARENCY_ALPHA
|
||||
// .store(self.transparency_alpha.unwrap_or(200), Ordering::SeqCst);
|
||||
|
||||
// the order every other place takes them in (floating, ignore, manage, regex; see lib.rs):
|
||||
// a thread that takes two in another order can wait for one that holds what it needs
|
||||
let mut floating_applications = FLOATING_APPLICATIONS.lock();
|
||||
let mut ignore_identifiers = IGNORE_IDENTIFIERS.lock();
|
||||
let mut regex_identifiers = REGEX_IDENTIFIERS.lock();
|
||||
let mut manage_identifiers = MANAGE_IDENTIFIERS.lock();
|
||||
let mut regex_identifiers = REGEX_IDENTIFIERS.lock();
|
||||
// let mut tray_and_multi_window_identifiers = TRAY_AND_MULTI_WINDOW_IDENTIFIERS.lock();
|
||||
// let mut object_name_change_identifiers = OBJECT_NAME_CHANGE_ON_LAUNCH.lock();
|
||||
// let mut object_name_change_title_ignore_list = OBJECT_NAME_CHANGE_TITLE_IGNORE_LIST.lock();
|
||||
// let mut layered_identifiers = LAYERED_WHITELIST.lock();
|
||||
// let mut transparency_blacklist = TRANSPARENCY_BLACKLIST.lock();
|
||||
// let mut slow_application_identifiers = SLOW_APPLICATION_IDENTIFIERS.lock();
|
||||
let mut floating_applications = FLOATING_APPLICATIONS.lock();
|
||||
// let mut no_titlebar_applications = NO_TITLEBAR.lock();
|
||||
let mut titleless_applications = TITLELESS_APPLICATIONS.lock();
|
||||
let mut tabbed_applications = TABBED_APPLICATIONS.lock();
|
||||
|
||||
@@ -1641,9 +1641,14 @@ fn window_is_eligible(
|
||||
}
|
||||
}
|
||||
|
||||
// Every place that holds two of the rule lists takes them in this order: floating, ignore,
|
||||
// manage, regex (see the statics in lib.rs). A thread that takes two in another order can wait
|
||||
// for one that holds what it needs, and both wait for ever.
|
||||
let floating_identifiers = FLOATING_APPLICATIONS.lock();
|
||||
let ignore_identifiers = IGNORE_IDENTIFIERS.lock();
|
||||
let manage_identifiers = MANAGE_IDENTIFIERS.lock();
|
||||
let regex_identifiers = REGEX_IDENTIFIERS.lock();
|
||||
|
||||
let ignore_identifiers = IGNORE_IDENTIFIERS.lock();
|
||||
let should_ignore = if let Some(rule) = should_act(
|
||||
title,
|
||||
exe_name,
|
||||
@@ -1658,7 +1663,6 @@ fn window_is_eligible(
|
||||
false
|
||||
};
|
||||
|
||||
let manage_identifiers = MANAGE_IDENTIFIERS.lock();
|
||||
let managed_override = if let Some(rule) = should_act(
|
||||
title,
|
||||
exe_name,
|
||||
@@ -1673,7 +1677,6 @@ fn window_is_eligible(
|
||||
false
|
||||
};
|
||||
|
||||
let floating_identifiers = FLOATING_APPLICATIONS.lock();
|
||||
if let Some(rule) = should_act(
|
||||
title,
|
||||
exe_name,
|
||||
|
||||
Reference in new issue
Block a user