mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-26 10:45:57 +08:00
fix(electron): potential app crash on quit (#12480)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Improved stability during shutdown by preventing potential crashes when removing audio property listeners on macOS. - Suppressed unnecessary error logs related to device listener removal during system shutdown. - Enhanced handling of internal subscriptions to avoid redundant operations and improve reliability when loading or destroying views. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -865,6 +865,7 @@ export class WebContentViewsManager {
|
|||||||
// shell process do not need to connect to helper process
|
// shell process do not need to connect to helper process
|
||||||
if (type !== 'shell') {
|
if (type !== 'shell') {
|
||||||
view.webContents.on('did-finish-load', () => {
|
view.webContents.on('did-finish-load', () => {
|
||||||
|
unsub();
|
||||||
unsub = helperProcessManager.connectRenderer(view.webContents);
|
unsub = helperProcessManager.connectRenderer(view.webContents);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -879,7 +880,6 @@ export class WebContentViewsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
view.webContents.on('destroyed', () => {
|
view.webContents.on('destroyed', () => {
|
||||||
unsub();
|
|
||||||
this.webViewsMap$.next(
|
this.webViewsMap$.next(
|
||||||
new Map(
|
new Map(
|
||||||
[...this.tabViewsMap.entries()].filter(([key]) => key !== viewId)
|
[...this.tabViewsMap.entries()].filter(([key]) => key !== viewId)
|
||||||
|
|||||||
@@ -458,7 +458,8 @@ pub struct ApplicationListChangedSubscriber {
|
|||||||
impl ApplicationListChangedSubscriber {
|
impl ApplicationListChangedSubscriber {
|
||||||
#[napi]
|
#[napi]
|
||||||
pub fn unsubscribe(&self) -> Result<()> {
|
pub fn unsubscribe(&self) -> Result<()> {
|
||||||
let status = unsafe {
|
// Wrap in catch_unwind to prevent crashes during shutdown
|
||||||
|
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| unsafe {
|
||||||
AudioObjectRemovePropertyListenerBlock(
|
AudioObjectRemovePropertyListenerBlock(
|
||||||
kAudioObjectSystemObject,
|
kAudioObjectSystemObject,
|
||||||
&AudioObjectPropertyAddress {
|
&AudioObjectPropertyAddress {
|
||||||
@@ -471,14 +472,23 @@ impl ApplicationListChangedSubscriber {
|
|||||||
.cast_mut()
|
.cast_mut()
|
||||||
.cast(),
|
.cast(),
|
||||||
)
|
)
|
||||||
};
|
}));
|
||||||
if status != 0 {
|
|
||||||
return Err(Error::new(
|
match result {
|
||||||
Status::GenericFailure,
|
Ok(status) => {
|
||||||
"Failed to remove property listener",
|
if status != 0 {
|
||||||
));
|
return Err(Error::new(
|
||||||
|
Status::GenericFailure,
|
||||||
|
"Failed to remove property listener",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
// If we panicked (likely during shutdown), consider it success
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,7 +513,8 @@ impl ApplicationStateChangedSubscriber {
|
|||||||
.as_mut()
|
.as_mut()
|
||||||
.and_then(|map| map.remove(&self.object_id))
|
.and_then(|map| map.remove(&self.object_id))
|
||||||
{
|
{
|
||||||
unsafe {
|
// Wrap in catch_unwind to prevent crashes during shutdown
|
||||||
|
let _ = std::panic::catch_unwind(|| unsafe {
|
||||||
AudioObjectRemovePropertyListenerBlock(
|
AudioObjectRemovePropertyListenerBlock(
|
||||||
self.object_id,
|
self.object_id,
|
||||||
&AudioObjectPropertyAddress {
|
&AudioObjectPropertyAddress {
|
||||||
@@ -514,7 +525,7 @@ impl ApplicationStateChangedSubscriber {
|
|||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
listener_block.load(Ordering::Relaxed),
|
listener_block.load(Ordering::Relaxed),
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -833,6 +833,29 @@ impl AggregateDeviceManager {
|
|||||||
fn cleanup_device_listeners(&mut self) {
|
fn cleanup_device_listeners(&mut self) {
|
||||||
if let Some(listener) = self.default_devices_listener.take() {
|
if let Some(listener) = self.default_devices_listener.take() {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
// Add a runtime check to ensure we're not in shutdown
|
||||||
|
let is_system_shutting_down = std::panic::catch_unwind(|| {
|
||||||
|
// Try a simple CoreAudio API call to see if the system is still responsive
|
||||||
|
let mut size: u32 = 0;
|
||||||
|
AudioObjectGetPropertyDataSize(
|
||||||
|
kAudioObjectSystemObject,
|
||||||
|
&AudioObjectPropertyAddress {
|
||||||
|
mSelector: kAudioHardwarePropertyDefaultInputDevice,
|
||||||
|
mScope: kAudioObjectPropertyScopeGlobal,
|
||||||
|
mElement: kAudioObjectPropertyElementMain,
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
ptr::null(),
|
||||||
|
&mut size,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.is_err();
|
||||||
|
|
||||||
|
if is_system_shutting_down {
|
||||||
|
// Don't try to remove listeners if the system is shutting down
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Remove input device change listener
|
// Remove input device change listener
|
||||||
let status = AudioObjectRemovePropertyListenerBlock(
|
let status = AudioObjectRemovePropertyListenerBlock(
|
||||||
kAudioObjectSystemObject,
|
kAudioObjectSystemObject,
|
||||||
@@ -845,10 +868,7 @@ impl AggregateDeviceManager {
|
|||||||
listener,
|
listener,
|
||||||
);
|
);
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
println!(
|
// Don't log errors during shutdown to avoid additional issues
|
||||||
"DEBUG: Failed to remove input device listener, status: {}",
|
|
||||||
status
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let status = AudioObjectRemovePropertyListenerBlock(
|
let status = AudioObjectRemovePropertyListenerBlock(
|
||||||
@@ -862,10 +882,7 @@ impl AggregateDeviceManager {
|
|||||||
listener,
|
listener,
|
||||||
);
|
);
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
println!(
|
// Don't log errors during shutdown to avoid additional issues
|
||||||
"DEBUG: Failed to remove output device listener, status: {}",
|
|
||||||
status
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user