Skip to content

Commit c8711c5

Browse files
committed
Merge branch 'fix_mem_leak_set_callback'
2 parents 38b65aa + 88d5500 commit c8711c5

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ Line wrap the file at 100 chars. Th
2525
### Changed
2626
- Bump minimum supported Rust version (MSRV) to 1.64.0.
2727

28+
### Fixed
29+
- Fix memory leak in `SCNetworkReachability::set_callback`.
30+
2831

2932
## [0.5.1] - 2023-05-15
3033
### Added

system-configuration/src/network_reachability.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,26 @@ impl SCNetworkReachability {
253253
copyDescription: Some(NetworkReachabilityCallbackContext::<F>::copy_ctx_description),
254254
};
255255

256-
if unsafe {
256+
let result = unsafe {
257257
SCNetworkReachabilitySetCallback(
258258
self.0,
259259
Some(NetworkReachabilityCallbackContext::<F>::callback),
260260
&mut callback_context,
261261
)
262-
} == 0u8
263-
{
262+
};
263+
264+
// The call to SCNetworkReachabilitySetCallback will call the
265+
// `retain` callback which will increment the reference count on
266+
// `callback`. Therefore, although the count is decremented below,
267+
// the reference count will still be >0.
268+
//
269+
// When `SCNetworkReachability` is dropped, `release` is called
270+
// which will drop the reference count on `callback` to 0.
271+
//
272+
// Assumes the pointer pointed to by the `info` member of `callback_context` is still valid.
273+
unsafe { Arc::decrement_strong_count(callback_context.info) };
274+
275+
if result == 0u8 {
264276
Err(SetCallbackError {})
265277
} else {
266278
Ok(())
@@ -309,17 +321,15 @@ impl<T: Fn(ReachabilityFlags) + Sync + Send> NetworkReachabilityCallbackContext<
309321

310322
extern "C" fn release_context(ctx: *const c_void) {
311323
unsafe {
312-
let _ = Arc::from_raw(ctx as *mut Self);
324+
Arc::decrement_strong_count(ctx as *mut Self);
313325
}
314326
}
315327

316328
extern "C" fn retain_context(ctx_ptr: *const c_void) -> *const c_void {
317329
unsafe {
318-
let ctx_ref: Arc<Self> = Arc::from_raw(ctx_ptr as *const Self);
319-
let new_ctx = ctx_ref.clone();
320-
std::mem::forget(ctx_ref);
321-
Arc::into_raw(new_ctx) as *const c_void
330+
Arc::increment_strong_count(ctx_ptr as *mut Self);
322331
}
332+
ctx_ptr
323333
}
324334
}
325335

0 commit comments

Comments
 (0)