Skip to content

Commit a37e70c

Browse files
committed
Make CFRunLoopMode a safe wrapper with a lifetime.
Fixes servo#648
1 parent d4ce710 commit a37e70c

File tree

3 files changed

+40
-27
lines changed

3 files changed

+40
-27
lines changed

core-foundation/src/filedescriptor.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,8 @@ mod test {
100100
extern crate libc;
101101

102102
use super::*;
103-
use crate::runloop::CFRunLoop;
103+
use crate::runloop::{CFRunLoop, CFRunLoopMode};
104104
use core_foundation_sys::base::CFOptionFlags;
105-
use core_foundation_sys::runloop::kCFRunLoopDefaultMode;
106105
use libc::O_RDWR;
107106
use std::ffi::CString;
108107
use std::os::raw::c_void;
@@ -157,9 +156,7 @@ mod test {
157156
let run_loop = CFRunLoop::get_current();
158157
let source = CFRunLoopSource::from_file_descriptor(&cf_fd, 0);
159158
assert!(source.is_some());
160-
unsafe {
161-
run_loop.add_source(&source.unwrap(), kCFRunLoopDefaultMode);
162-
}
159+
run_loop.add_source(&source.unwrap(), CFRunLoopMode::default());
163160

164161
info.value = 0;
165162
cf_fd.enable_callbacks(kCFFileDescriptorReadCallBack);

core-foundation/src/runloop.rs

+36-20
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
#![allow(non_upper_case_globals)]
1111

12+
use std::marker::PhantomData;
13+
1214
use core_foundation_sys::base::CFIndex;
1315
use core_foundation_sys::base::{kCFAllocatorDefault, CFOptionFlags};
1416
pub use core_foundation_sys::runloop::*;
@@ -19,7 +21,23 @@ use crate::date::{CFAbsoluteTime, CFTimeInterval};
1921
use crate::filedescriptor::CFFileDescriptor;
2022
use crate::string::CFString;
2123

22-
pub type CFRunLoopMode = CFStringRef;
24+
pub struct CFRunLoopMode<'a>(CFStringRef, PhantomData<&'a CFString>);
25+
26+
impl<'a> CFRunLoopMode<'a> {
27+
pub fn new(s: &'a CFString) -> CFRunLoopMode<'a> {
28+
CFRunLoopMode(s.as_concrete_TypeRef(), PhantomData)
29+
}
30+
31+
#[doc(alias = "kCFRunLoopCommonModes")]
32+
pub fn common() -> CFRunLoopMode<'static> {
33+
unsafe { CFRunLoopMode(kCFRunLoopCommonModes, PhantomData) }
34+
}
35+
36+
#[doc(alias = "kCFRunLoopDefaultMode")]
37+
pub fn default() -> CFRunLoopMode<'static> {
38+
unsafe { CFRunLoopMode(kCFRunLoopDefaultMode, PhantomData) }
39+
}
40+
}
2341

2442
declare_TCFType!(CFRunLoop, CFRunLoopRef);
2543
impl_TCFType!(CFRunLoop, CFRunLoopRef, CFRunLoopGetTypeID);
@@ -59,15 +77,15 @@ impl CFRunLoop {
5977
}
6078

6179
pub fn run_in_mode(
62-
mode: CFStringRef,
80+
mode: CFRunLoopMode,
6381
duration: std::time::Duration,
6482
return_after_source_handled: bool,
6583
) -> CFRunLoopRunResult {
6684
let seconds = duration.as_secs_f64();
6785
let return_after_source_handled = if return_after_source_handled { 1 } else { 0 };
6886

6987
unsafe {
70-
match CFRunLoopRunInMode(mode, seconds, return_after_source_handled) {
88+
match CFRunLoopRunInMode(mode.0, seconds, return_after_source_handled) {
7189
2 => CFRunLoopRunResult::Stopped,
7290
3 => CFRunLoopRunResult::TimedOut,
7391
4 => CFRunLoopRunResult::HandledSource,
@@ -95,50 +113,50 @@ impl CFRunLoop {
95113
}
96114

97115
pub fn contains_timer(&self, timer: &CFRunLoopTimer, mode: CFRunLoopMode) -> bool {
98-
unsafe { CFRunLoopContainsTimer(self.0, timer.0, mode) != 0 }
116+
unsafe { CFRunLoopContainsTimer(self.0, timer.0, mode.0) != 0 }
99117
}
100118

101119
pub fn add_timer(&self, timer: &CFRunLoopTimer, mode: CFRunLoopMode) {
102120
unsafe {
103-
CFRunLoopAddTimer(self.0, timer.0, mode);
121+
CFRunLoopAddTimer(self.0, timer.0, mode.0);
104122
}
105123
}
106124

107125
pub fn remove_timer(&self, timer: &CFRunLoopTimer, mode: CFRunLoopMode) {
108126
unsafe {
109-
CFRunLoopRemoveTimer(self.0, timer.0, mode);
127+
CFRunLoopRemoveTimer(self.0, timer.0, mode.0);
110128
}
111129
}
112130

113131
pub fn contains_source(&self, source: &CFRunLoopSource, mode: CFRunLoopMode) -> bool {
114-
unsafe { CFRunLoopContainsSource(self.0, source.0, mode) != 0 }
132+
unsafe { CFRunLoopContainsSource(self.0, source.0, mode.0) != 0 }
115133
}
116134

117135
pub fn add_source(&self, source: &CFRunLoopSource, mode: CFRunLoopMode) {
118136
unsafe {
119-
CFRunLoopAddSource(self.0, source.0, mode);
137+
CFRunLoopAddSource(self.0, source.0, mode.0);
120138
}
121139
}
122140

123141
pub fn remove_source(&self, source: &CFRunLoopSource, mode: CFRunLoopMode) {
124142
unsafe {
125-
CFRunLoopRemoveSource(self.0, source.0, mode);
143+
CFRunLoopRemoveSource(self.0, source.0, mode.0);
126144
}
127145
}
128146

129147
pub fn contains_observer(&self, observer: &CFRunLoopObserver, mode: CFRunLoopMode) -> bool {
130-
unsafe { CFRunLoopContainsObserver(self.0, observer.0, mode) != 0 }
148+
unsafe { CFRunLoopContainsObserver(self.0, observer.0, mode.0) != 0 }
131149
}
132150

133151
pub fn add_observer(&self, observer: &CFRunLoopObserver, mode: CFRunLoopMode) {
134152
unsafe {
135-
CFRunLoopAddObserver(self.0, observer.0, mode);
153+
CFRunLoopAddObserver(self.0, observer.0, mode.0);
136154
}
137155
}
138156

139157
pub fn remove_observer(&self, observer: &CFRunLoopObserver, mode: CFRunLoopMode) {
140158
unsafe {
141-
CFRunLoopRemoveObserver(self.0, observer.0, mode);
159+
CFRunLoopRemoveObserver(self.0, observer.0, mode.0);
142160
}
143161
}
144162
}
@@ -222,9 +240,8 @@ mod test {
222240

223241
let run_loop_timer =
224242
CFRunLoopTimer::new(now + 0.20f64, 0f64, 0, 0, timer_popped, &mut context);
225-
unsafe {
226-
run_loop.add_timer(&run_loop_timer, kCFRunLoopDefaultMode);
227-
}
243+
run_loop.add_timer(&run_loop_timer, CFRunLoopMode::default());
244+
228245
CFRunLoop::run_current();
229246
let elapsed = elapsed_rx.try_recv().unwrap();
230247
println!("wait_200_milliseconds, elapsed: {}", elapsed);
@@ -277,7 +294,7 @@ mod test {
277294
};
278295

279296
let runloop = CFRunLoop::get_current();
280-
runloop.add_observer(&observer, unsafe { kCFRunLoopDefaultMode });
297+
runloop.add_observer(&observer, CFRunLoopMode::default());
281298

282299
let timer = CFRunLoopTimer::new(
283300
CFDate::now().abs_time() + 1f64,
@@ -287,11 +304,10 @@ mod test {
287304
observe_timer_popped,
288305
null_mut(),
289306
);
290-
runloop.add_timer(&timer, unsafe { kCFRunLoopDefaultMode });
307+
runloop.add_timer(&timer, CFRunLoopMode::default());
291308

292-
let result = unsafe {
293-
CFRunLoop::run_in_mode(kCFRunLoopDefaultMode, Duration::from_secs(10), false)
294-
};
309+
let result =
310+
CFRunLoop::run_in_mode(CFRunLoopMode::default(), Duration::from_secs(10), false);
295311

296312
assert_eq!(result, CFRunLoopRunResult::Stopped);
297313

core-graphics/src/event.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ unsafe extern "C" fn cg_event_tap_callback_internal(
441441

442442
/// ```no_run
443443
///extern crate core_foundation;
444-
///use core_foundation::runloop::{kCFRunLoopCommonModes, CFRunLoop};
444+
///use core_foundation::runloop::{CFRunLoop, CFRunLoopMode};
445445
///use core_graphics::event::{CGEventTap, CGEventTapLocation, CGEventTapPlacement, CGEventTapOptions, CGEventType};
446446
///let current = CFRunLoop::get_current();
447447
///match CGEventTap::new(
@@ -459,7 +459,7 @@ unsafe extern "C" fn cg_event_tap_callback_internal(
459459
/// .mach_port
460460
/// .create_runloop_source(0)
461461
/// .expect("Somethings is bad ");
462-
/// current.add_source(&loop_source, kCFRunLoopCommonModes);
462+
/// current.add_source(&loop_source, CFRunLoopMode::common());
463463
/// tap.enable();
464464
/// CFRunLoop::run_current();
465465
/// },

0 commit comments

Comments
 (0)