@@ -253,14 +253,26 @@ impl SCNetworkReachability {
253
253
copyDescription : Some ( NetworkReachabilityCallbackContext :: < F > :: copy_ctx_description) ,
254
254
} ;
255
255
256
- if unsafe {
256
+ let result = unsafe {
257
257
SCNetworkReachabilitySetCallback (
258
258
self . 0 ,
259
259
Some ( NetworkReachabilityCallbackContext :: < F > :: callback) ,
260
260
& mut callback_context,
261
261
)
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 {
264
276
Err ( SetCallbackError { } )
265
277
} else {
266
278
Ok ( ( ) )
@@ -309,17 +321,15 @@ impl<T: Fn(ReachabilityFlags) + Sync + Send> NetworkReachabilityCallbackContext<
309
321
310
322
extern "C" fn release_context ( ctx : * const c_void ) {
311
323
unsafe {
312
- let _ = Arc :: from_raw ( ctx as * mut Self ) ;
324
+ Arc :: decrement_strong_count ( ctx as * mut Self ) ;
313
325
}
314
326
}
315
327
316
328
extern "C" fn retain_context ( ctx_ptr : * const c_void ) -> * const c_void {
317
329
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 ) ;
322
331
}
332
+ ctx_ptr
323
333
}
324
334
}
325
335
0 commit comments