Деян качи първо решение на 10.12.2025 03:18 (преди около 2 месеца)
Какво ще стане, ако от callback функция извикаме някой от on или off методите?
Ако event-ите са различени, всичко ще е наред, защото всеки има собствен Mutex.
Ако event-ите са еднакви, ще се получи deadlock, защото докато изпълняваме callbacks Mutex-а ще се заключи, но on или off също имат нужда от Mutex-a и ще чакат вечно.
Най-простото решение е при извикването на callbacks, те да се клонират и сложат във вектор. Така извикването им ще става извън Mutex-а ще се освободи, и така извикването им ще е извън критична зона.
Недостатъкът е, че за всеки emit ще се трябва да се заделя памет и копира, което потенциално има линейна сложност.
Тест, който показва проблема с deadlock-a
fn test_mine() { with_timeout(std::time::Duration::from_secs(3), || { let ed = EventDispatcher::<()>::new(); let callback: Callback<()> = { let ed = ed.clone(); Box::new(move || { ed.on("foo", Box::new(|| println!("hello"))); }) }; ed.on("foo", callback); ed.emit("foo", &mut ()); }); } }
Послепис - наясно съм със съществуването на std::sync::atomic::AtomicI32 и че в Arc<Mutex> Arc може да се внесе в самато структура
