diff options
Diffstat (limited to 'vendor/sysinfo/src/apple/utils.rs')
-rw-r--r-- | vendor/sysinfo/src/apple/utils.rs | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/vendor/sysinfo/src/apple/utils.rs b/vendor/sysinfo/src/apple/utils.rs index 019295b95..408c02c31 100644 --- a/vendor/sysinfo/src/apple/utils.rs +++ b/vendor/sysinfo/src/apple/utils.rs @@ -1,6 +1,39 @@ // Take a look at the license at the top of the repository in the LICENSE file. +use core_foundation_sys::base::CFRelease; use libc::c_char; +use std::ptr::NonNull; + +// A helper using to auto release the resource got from CoreFoundation. +// More information about the ownership policy for CoreFoundation pelease refer the link below: +// https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-CJBEJBHH +#[repr(transparent)] +pub(crate) struct CFReleaser<T>(NonNull<T>); + +impl<T> CFReleaser<T> { + pub(crate) fn new(ptr: *const T) -> Option<Self> { + // This cast is OK because `NonNull` is a transparent wrapper + // over a `*const T`. Additionally, mutability doesn't matter with + // pointers here. + NonNull::new(ptr as *mut T).map(Self) + } + + pub(crate) fn inner(&self) -> *const T { + self.0.as_ptr().cast() + } +} + +impl<T> Drop for CFReleaser<T> { + fn drop(&mut self) { + unsafe { CFRelease(self.0.as_ptr().cast()) } + } +} + +// Safety: These are safe to implement because we only wrap non-mutable +// CoreFoundation types, which are generally threadsafe unless noted +// otherwise. +unsafe impl<T> Send for CFReleaser<T> {} +unsafe impl<T> Sync for CFReleaser<T> {} pub(crate) fn cstr_to_rust(c: *const c_char) -> Option<String> { cstr_to_rust_with_size(c, None) @@ -28,7 +61,6 @@ pub(crate) fn cstr_to_rust_with_size(c: *const c_char, size: Option<usize>) -> O } } -#[cfg(target_os = "macos")] pub(crate) fn vec_to_rust(buf: Vec<i8>) -> Option<String> { String::from_utf8( buf.into_iter() |