Skip to content

Commit 54f6eac

Browse files
committed
green: Remove some unsafe code in BasicLoop
1 parent 05a453e commit 54f6eac

File tree

3 files changed

+20
-36
lines changed

3 files changed

+20
-36
lines changed

src/libgreen/basic.rs

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
//! This implementation is also used as the fallback implementation of an event
1616
//! loop if no other one is provided (and M:N scheduling is desired).
1717
18+
use alloc::arc::Arc;
19+
use std::sync::atomics;
1820
use std::mem;
1921
use std::rt::rtio::{EventLoop, IoFactory, RemoteCallback};
2022
use std::rt::rtio::{PausableIdleCallback, Callback};
@@ -27,10 +29,11 @@ pub fn event_loop() -> Box<EventLoop:Send> {
2729

2830
struct BasicLoop {
2931
work: Vec<proc():Send>, // pending work
30-
idle: Option<*mut BasicPausable>, // only one is allowed
3132
remotes: Vec<(uint, Box<Callback:Send>)>,
3233
next_remote: uint,
3334
messages: Exclusive<Vec<Message>>,
35+
idle: Option<Box<Callback:Send>>,
36+
idle_active: Option<Arc<atomics::AtomicBool>>,
3437
}
3538

3639
enum Message { RunRemote(uint), RemoveRemote(uint) }
@@ -40,6 +43,7 @@ impl BasicLoop {
4043
BasicLoop {
4144
work: vec![],
4245
idle: None,
46+
idle_active: None,
4347
next_remote: 0,
4448
remotes: vec![],
4549
messages: Exclusive::new(vec![]),
@@ -92,20 +96,18 @@ impl BasicLoop {
9296

9397
/// Run the idle callback if one is registered
9498
fn idle(&mut self) {
95-
unsafe {
96-
match self.idle {
97-
Some(idle) => {
98-
if (*idle).active {
99-
(*idle).work.call();
100-
}
99+
match self.idle {
100+
Some(ref mut idle) => {
101+
if self.idle_active.get_ref().load(atomics::SeqCst) {
102+
idle.call();
101103
}
102-
None => {}
103104
}
105+
None => {}
104106
}
105107
}
106108

107109
fn has_idle(&self) -> bool {
108-
unsafe { self.idle.is_some() && (**self.idle.get_ref()).active }
110+
self.idle.is_some() && self.idle_active.get_ref().load(atomics::SeqCst)
109111
}
110112
}
111113

@@ -141,13 +143,11 @@ impl EventLoop for BasicLoop {
141143
// FIXME: Seems like a really weird requirement to have an event loop provide.
142144
fn pausable_idle_callback(&mut self, cb: Box<Callback:Send>)
143145
-> Box<PausableIdleCallback:Send> {
144-
let callback = box BasicPausable::new(self, cb);
145146
rtassert!(self.idle.is_none());
146-
unsafe {
147-
let cb_ptr: &*mut BasicPausable = mem::transmute(&callback);
148-
self.idle = Some(*cb_ptr);
149-
}
150-
callback as Box<PausableIdleCallback:Send>
147+
self.idle = Some(cb);
148+
let a = Arc::new(atomics::AtomicBool::new(true));
149+
self.idle_active = Some(a.clone());
150+
box BasicPausable { active: a } as Box<PausableIdleCallback:Send>
151151
}
152152

153153
fn remote_callback(&mut self, f: Box<Callback:Send>)
@@ -196,35 +196,21 @@ impl Drop for BasicRemote {
196196
}
197197

198198
struct BasicPausable {
199-
eloop: *mut BasicLoop,
200-
work: Box<Callback:Send>,
201-
active: bool,
202-
}
203-
204-
impl BasicPausable {
205-
fn new(eloop: &mut BasicLoop, cb: Box<Callback:Send>) -> BasicPausable {
206-
BasicPausable {
207-
active: false,
208-
work: cb,
209-
eloop: eloop,
210-
}
211-
}
199+
active: Arc<atomics::AtomicBool>,
212200
}
213201

214202
impl PausableIdleCallback for BasicPausable {
215203
fn pause(&mut self) {
216-
self.active = false;
204+
self.active.store(false, atomics::SeqCst);
217205
}
218206
fn resume(&mut self) {
219-
self.active = true;
207+
self.active.store(true, atomics::SeqCst);
220208
}
221209
}
222210

223211
impl Drop for BasicPausable {
224212
fn drop(&mut self) {
225-
unsafe {
226-
(*self.eloop).idle = None;
227-
}
213+
self.active.store(false, atomics::SeqCst);
228214
}
229215
}
230216

src/libgreen/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,6 @@ impl SchedPool {
435435
pool.sleepers.clone(),
436436
pool.task_state.clone());
437437
pool.handles.push(sched.make_handle());
438-
let sched = sched;
439438
pool.threads.push(Thread::start(proc() { sched.bootstrap(); }));
440439
}
441440

@@ -497,7 +496,6 @@ impl SchedPool {
497496
self.task_state.clone());
498497
let ret = sched.make_handle();
499498
self.handles.push(sched.make_handle());
500-
let sched = sched;
501499
self.threads.push(Thread::start(proc() { sched.bootstrap() }));
502500

503501
return ret;

src/libgreen/sched.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,7 +1142,7 @@ mod test {
11421142

11431143
Thread::start(proc() {
11441144
let sleepers = SleeperList::new();
1145-
let mut pool = BufferPool::new();
1145+
let pool = BufferPool::new();
11461146
let (normal_worker, normal_stealer) = pool.deque();
11471147
let (special_worker, special_stealer) = pool.deque();
11481148
let queues = vec![normal_stealer, special_stealer];

0 commit comments

Comments
 (0)