Skip to content

Commit fe56d19

Browse files
committed
Merge branch 'mark-runloop-scheduling-as-unsafe'
2 parents 7633a12 + 5a08503 commit fe56d19

File tree

2 files changed

+61
-45
lines changed

2 files changed

+61
-45
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ Line wrap the file at 100 chars. Th
2424
## [Unreleased]
2525
### Changed
2626
- Bump minimum supported Rust version (MSRV) to 1.64.0.
27+
- Breaking: Mark `SCNetworkReachability::schedule_with_runloop` and `unschedule_from_runloop` as
28+
`unsafe`. They accept a raw pointer that it dereferences. Figuring out a safe API around this is
29+
left as an exercise for the future.
2730

2831
### Fixed
2932
- Fix memory leak in `SCNetworkReachability::set_callback`.

system-configuration/src/network_reachability.rs

+58-45
Original file line numberDiff line numberDiff line change
@@ -186,18 +186,21 @@ impl SCNetworkReachability {
186186
/// See [`SCNetworkReachabilityScheduleFromRunLoop`] for details.
187187
///
188188
/// [`SCNetworkReachabilityScheduleFromRunLoop`]: https://developer.apple.com/documentation/systemconfiguration/1514894-scnetworkreachabilityschedulewit?language=objc
189-
pub fn schedule_with_runloop(
189+
///
190+
/// # Safety
191+
///
192+
/// The `run_loop_mode` must not be NULL and must be a pointer to a valid run loop mode.
193+
/// Use `core_foundation::runloop::kCFRunLoopCommonModes` if you are unsure.
194+
pub unsafe fn schedule_with_runloop(
190195
&self,
191196
run_loop: &CFRunLoop,
192197
run_loop_mode: CFStringRef,
193198
) -> Result<(), SchedulingError> {
194-
if unsafe {
195-
SCNetworkReachabilityScheduleWithRunLoop(
196-
self.0,
197-
run_loop.to_void() as *mut _,
198-
run_loop_mode,
199-
)
200-
} == 0u8
199+
if SCNetworkReachabilityScheduleWithRunLoop(
200+
self.0,
201+
run_loop.to_void() as *mut _,
202+
run_loop_mode,
203+
) == 0u8
201204
{
202205
Err(SchedulingError(()))
203206
} else {
@@ -210,18 +213,21 @@ impl SCNetworkReachability {
210213
/// See [`SCNetworkReachabilityUnscheduleFromRunLoop`] for details.
211214
///
212215
/// [`SCNetworkReachabilityUnscheduleFromRunLoop`]: https://developer.apple.com/documentation/systemconfiguration/1514899-scnetworkreachabilityunschedulef?language=objc
213-
pub fn unschedule_from_runloop(
216+
///
217+
/// # Safety
218+
///
219+
/// The `run_loop_mode` must not be NULL and must be a pointer to a valid run loop mode.
220+
/// Use `core_foundation::runloop::kCFRunLoopCommonModes` if you are unsure.
221+
pub unsafe fn unschedule_from_runloop(
214222
&self,
215223
run_loop: &CFRunLoop,
216224
run_loop_mode: CFStringRef,
217225
) -> Result<(), UnschedulingError> {
218-
if unsafe {
219-
SCNetworkReachabilityUnscheduleFromRunLoop(
220-
self.0,
221-
run_loop.to_void() as *mut _,
222-
run_loop_mode,
223-
)
224-
} == 0u8
226+
if SCNetworkReachabilityUnscheduleFromRunLoop(
227+
self.0,
228+
run_loop.to_void() as *mut _,
229+
run_loop_mode,
230+
) == 0u8
225231
{
226232
Err(UnschedulingError(()))
227233
} else {
@@ -383,14 +389,15 @@ mod test {
383389
addr
384390
);
385391
reachability.set_callback(|_| {}).unwrap();
386-
reachability
387-
.schedule_with_runloop(&CFRunLoop::get_current(), unsafe { kCFRunLoopCommonModes })
388-
.unwrap();
389-
reachability
390-
.unschedule_from_runloop(&CFRunLoop::get_current(), unsafe {
391-
kCFRunLoopCommonModes
392-
})
393-
.unwrap();
392+
// SAFETY: We use the Apple provided run_loop_mode kCFRunLoopCommonModes
393+
unsafe {
394+
reachability
395+
.schedule_with_runloop(&CFRunLoop::get_current(), kCFRunLoopCommonModes)
396+
.unwrap();
397+
reachability
398+
.unschedule_from_runloop(&CFRunLoop::get_current(), kCFRunLoopCommonModes)
399+
.unwrap();
400+
}
394401
}
395402
}
396403

@@ -414,14 +421,15 @@ mod test {
414421
remote
415422
);
416423
reachability.set_callback(|_| {}).unwrap();
417-
reachability
418-
.schedule_with_runloop(&CFRunLoop::get_current(), unsafe { kCFRunLoopCommonModes })
419-
.unwrap();
420-
reachability
421-
.unschedule_from_runloop(&CFRunLoop::get_current(), unsafe {
422-
kCFRunLoopCommonModes
423-
})
424-
.unwrap();
424+
// SAFETY: We use the Apple provided run_loop_mode kCFRunLoopCommonModes
425+
unsafe {
426+
reachability
427+
.schedule_with_runloop(&CFRunLoop::get_current(), kCFRunLoopCommonModes)
428+
.unwrap();
429+
reachability
430+
.unschedule_from_runloop(&CFRunLoop::get_current(), kCFRunLoopCommonModes)
431+
.unwrap();
432+
}
425433
}
426434
}
427435

@@ -435,16 +443,18 @@ mod test {
435443
match SCNetworkReachability::from_host(&input) {
436444
Some(mut reachability) => {
437445
reachability.set_callback(|_| {}).unwrap();
438-
reachability
439-
.schedule_with_runloop(&CFRunLoop::get_current(), unsafe {
440-
kCFRunLoopCommonModes
441-
})
442-
.unwrap();
443-
reachability
444-
.unschedule_from_runloop(&CFRunLoop::get_current(), unsafe {
445-
kCFRunLoopCommonModes
446-
})
447-
.unwrap();
446+
// SAFETY: We use the Apple provided run_loop_mode kCFRunLoopCommonModes
447+
unsafe {
448+
reachability
449+
.schedule_with_runloop(&CFRunLoop::get_current(), kCFRunLoopCommonModes)
450+
.unwrap();
451+
reachability
452+
.unschedule_from_runloop(
453+
&CFRunLoop::get_current(),
454+
kCFRunLoopCommonModes,
455+
)
456+
.unwrap();
457+
}
448458
}
449459
None => {
450460
panic!(
@@ -471,9 +481,12 @@ mod test {
471481
let mut reachability =
472482
SCNetworkReachability::from("0.0.0.0:0".parse::<SocketAddr>().unwrap());
473483
reachability.set_callback(|_| {}).unwrap();
474-
reachability
475-
.schedule_with_runloop(&CFRunLoop::get_current(), unsafe { kCFRunLoopCommonModes })
476-
.unwrap();
484+
// SAFETY: We use the Apple provided run_loop_mode kCFRunLoopCommonModes
485+
unsafe {
486+
reachability
487+
.schedule_with_runloop(&CFRunLoop::get_current(), kCFRunLoopCommonModes)
488+
.unwrap();
489+
}
477490
reachability.set_callback(|_| {}).unwrap();
478491
let _ = tx.send(reachability);
479492
CFRunLoop::run_current();

0 commit comments

Comments
 (0)