Skip listener-removed assertion if aggregate device is dead (#114)
This patch works around a crash we get in BMO 1658982 [1]. When creating the aggregate device, somehow we will get `kAudioHardwareBadObjectError` error during `set_sub_devices_sync` step. This error occurs when removing the device-changed listeners for the newly created aggregate device. This error implies the aggregate device is somehow dead. In this case, it's ok to not remove the listener manually since the listener should receive nothing from a dead device. We can just return error to indicate the aggregate device isn't initialized successfully. We should return the error if sub devices cannot be set. However, this patch only return the error when timeout of setting the sub devices. The reason to do so is to investigate when `kAudioHardwareBadObjectError` is thrown. [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1658982
This commit is contained in:
Родитель
b4f45e18a4
Коммит
faa9c58506
|
@ -292,15 +292,14 @@ impl AggregateDevice {
|
|||
return Err(status);
|
||||
}
|
||||
|
||||
let _teardown = finally(|| {
|
||||
let r = audio_object_remove_property_listener(
|
||||
let remove_listener = || -> OSStatus {
|
||||
audio_object_remove_property_listener(
|
||||
device_id,
|
||||
&address,
|
||||
devices_changed_callback,
|
||||
data_ptr as *mut c_void,
|
||||
);
|
||||
assert_eq!(r, NO_ERR);
|
||||
});
|
||||
)
|
||||
};
|
||||
|
||||
Self::set_sub_devices(device_id, input_id, output_id)?;
|
||||
|
||||
|
@ -318,6 +317,13 @@ impl AggregateDevice {
|
|||
);
|
||||
}
|
||||
if *dev != device_id {
|
||||
let r = remove_listener();
|
||||
// If the error is kAudioHardwareBadObjectError, it implies `device_id` is somehow
|
||||
// dead, so its listener should receive nothing. It's ok to leave here.
|
||||
assert!(r == NO_ERR || r == (kAudioHardwareBadObjectError as OSStatus));
|
||||
// TODO: Destroy the aggregate device immediately if error is not
|
||||
// kAudioHardwareBadObjectError. Otherwise the `devices_changed_callback` is able
|
||||
// to touch the `cloned_condvar_pair` after it's freed.
|
||||
return Err(APPLE_EVENT_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
@ -336,6 +342,8 @@ impl AggregateDevice {
|
|||
NO_ERR
|
||||
}
|
||||
|
||||
let r = remove_listener();
|
||||
assert_eq!(r, NO_ERR);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче