diff --git a/src/unix/apple/disk.rs b/src/unix/apple/disk.rs index 048c85268..72a70ac12 100644 --- a/src/unix/apple/disk.rs +++ b/src/unix/apple/disk.rs @@ -91,7 +91,23 @@ impl crate::DisksInner { } pub(crate) fn refresh_list(&mut self) { + struct AutoreleasePool { + ctx: *mut c_void, + } + + impl Drop for AutoreleasePool { + fn drop(&mut self) { + // SAFETY: We have not manipulated `pool_ctx` since it was received from a corresponding + // pool push call. + unsafe { ffi::objc_autoreleasePoolPop(self.ctx) } + } + } + unsafe { + // SAFETY: Creating a new pool is safe in any context. They can be arbitrarily nested + // as long as pool objects are not used in deeper layers, but we only have one and don't + // allow it to leave this scope. + let _refresh_pool = AutoreleasePool { ctx: ffi::objc_autoreleasePoolPush() }; get_list(&mut self.disks); } } diff --git a/src/unix/apple/ffi.rs b/src/unix/apple/ffi.rs index fb6dc0460..75ae0e1ec 100644 --- a/src/unix/apple/ffi.rs +++ b/src/unix/apple/ffi.rs @@ -13,6 +13,7 @@ cfg_if! { array::CFArrayRef, dictionary::CFDictionaryRef, error::CFErrorRef, string::CFStringRef, url::CFURLRef, }; + use std::ffi::c_void; #[link(name = "CoreFoundation", kind = "framework")] extern "C" { @@ -32,6 +33,12 @@ cfg_if! { pub static kCFURLVolumeIsInternalKey: CFStringRef; pub static kCFURLVolumeIsBrowsableKey: CFStringRef; } + + #[link(name = "objc", kind = "dylib")] + extern "C" { + pub fn objc_autoreleasePoolPop(pool: *mut c_void); + pub fn objc_autoreleasePoolPush() -> *mut c_void; + } } }