Skip to content

Commit 257a73c

Browse files
committed
auto merge of #14301 : alexcrichton/rust/remove-unsafe-arc, r=brson
This type can be built with `Arc<Unsafe<T>>` now that liballoc exists.
2 parents 5f3f091 + fdf935a commit 257a73c

24 files changed

+280
-477
lines changed

src/libgreen/basic.rs

+19-33
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

+7-8
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,9 @@
214214
#[cfg(test)] extern crate rustuv;
215215
extern crate rand;
216216
extern crate libc;
217+
extern crate alloc;
217218

219+
use alloc::arc::Arc;
218220
use std::mem::replace;
219221
use std::os;
220222
use std::rt::rtio;
@@ -223,7 +225,6 @@ use std::rt;
223225
use std::sync::atomics::{SeqCst, AtomicUint, INIT_ATOMIC_UINT};
224226
use std::sync::deque;
225227
use std::task::TaskOpts;
226-
use std::sync::arc::UnsafeArc;
227228

228229
use sched::{Shutdown, Scheduler, SchedHandle, TaskFromFriend, NewNeighbor};
229230
use sleeper_list::SleeperList;
@@ -375,7 +376,7 @@ pub struct SchedPool {
375376
/// sending on a channel once the entire pool has been drained of all tasks.
376377
#[deriving(Clone)]
377378
struct TaskState {
378-
cnt: UnsafeArc<AtomicUint>,
379+
cnt: Arc<AtomicUint>,
379380
done: Sender<()>,
380381
}
381382

@@ -434,7 +435,6 @@ impl SchedPool {
434435
pool.sleepers.clone(),
435436
pool.task_state.clone());
436437
pool.handles.push(sched.make_handle());
437-
let sched = sched;
438438
pool.threads.push(Thread::start(proc() { sched.bootstrap(); }));
439439
}
440440

@@ -496,7 +496,6 @@ impl SchedPool {
496496
self.task_state.clone());
497497
let ret = sched.make_handle();
498498
self.handles.push(sched.make_handle());
499-
let sched = sched;
500499
self.threads.push(Thread::start(proc() { sched.bootstrap() }));
501500

502501
return ret;
@@ -537,21 +536,21 @@ impl TaskState {
537536
fn new() -> (Receiver<()>, TaskState) {
538537
let (tx, rx) = channel();
539538
(rx, TaskState {
540-
cnt: UnsafeArc::new(AtomicUint::new(0)),
539+
cnt: Arc::new(AtomicUint::new(0)),
541540
done: tx,
542541
})
543542
}
544543

545544
fn increment(&mut self) {
546-
unsafe { (*self.cnt.get()).fetch_add(1, SeqCst); }
545+
self.cnt.fetch_add(1, SeqCst);
547546
}
548547

549548
fn active(&self) -> bool {
550-
unsafe { (*self.cnt.get()).load(SeqCst) != 0 }
549+
self.cnt.load(SeqCst) != 0
551550
}
552551

553552
fn decrement(&mut self) {
554-
let prev = unsafe { (*self.cnt.get()).fetch_sub(1, SeqCst) };
553+
let prev = self.cnt.fetch_sub(1, SeqCst);
555554
if prev == 1 {
556555
self.done.send(());
557556
}

src/libgreen/message_queue.rs

+16-12
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use alloc::arc::Arc;
1112
use mpsc = std::sync::mpsc_queue;
12-
use std::sync::arc::UnsafeArc;
13+
use std::kinds::marker;
1314

1415
pub enum PopResult<T> {
1516
Inconsistent,
@@ -18,29 +19,32 @@ pub enum PopResult<T> {
1819
}
1920

2021
pub fn queue<T: Send>() -> (Consumer<T>, Producer<T>) {
21-
let (a, b) = UnsafeArc::new2(mpsc::Queue::new());
22-
(Consumer { inner: a }, Producer { inner: b })
22+
let a = Arc::new(mpsc::Queue::new());
23+
(Consumer { inner: a.clone(), noshare: marker::NoShare },
24+
Producer { inner: a, noshare: marker::NoShare })
2325
}
2426

2527
pub struct Producer<T> {
26-
inner: UnsafeArc<mpsc::Queue<T>>,
28+
inner: Arc<mpsc::Queue<T>>,
29+
noshare: marker::NoShare,
2730
}
2831

2932
pub struct Consumer<T> {
30-
inner: UnsafeArc<mpsc::Queue<T>>,
33+
inner: Arc<mpsc::Queue<T>>,
34+
noshare: marker::NoShare,
3135
}
3236

3337
impl<T: Send> Consumer<T> {
34-
pub fn pop(&mut self) -> PopResult<T> {
35-
match unsafe { (*self.inner.get()).pop() } {
38+
pub fn pop(&self) -> PopResult<T> {
39+
match self.inner.pop() {
3640
mpsc::Inconsistent => Inconsistent,
3741
mpsc::Empty => Empty,
3842
mpsc::Data(t) => Data(t),
3943
}
4044
}
4145

42-
pub fn casual_pop(&mut self) -> Option<T> {
43-
match unsafe { (*self.inner.get()).pop() } {
46+
pub fn casual_pop(&self) -> Option<T> {
47+
match self.inner.pop() {
4448
mpsc::Inconsistent => None,
4549
mpsc::Empty => None,
4650
mpsc::Data(t) => Some(t),
@@ -49,13 +53,13 @@ impl<T: Send> Consumer<T> {
4953
}
5054

5155
impl<T: Send> Producer<T> {
52-
pub fn push(&mut self, t: T) {
53-
unsafe { (*self.inner.get()).push(t); }
56+
pub fn push(&self, t: T) {
57+
self.inner.push(t);
5458
}
5559
}
5660

5761
impl<T: Send> Clone for Producer<T> {
5862
fn clone(&self) -> Producer<T> {
59-
Producer { inner: self.inner.clone() }
63+
Producer { inner: self.inner.clone(), noshare: marker::NoShare }
6064
}
6165
}

src/libgreen/sched.rs

+1-1
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];

src/libnative/io/file_unix.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@
1010

1111
//! Blocking posix-based file I/O
1212
13+
use alloc::arc::Arc;
1314
use libc::{c_int, c_void};
1415
use libc;
1516
use std::c_str::CString;
1617
use std::io::IoError;
1718
use std::io;
1819
use std::mem;
1920
use std::rt::rtio;
20-
use std::sync::arc::UnsafeArc;
2121

2222
use io::{IoResult, retry, keep_going};
2323

@@ -29,7 +29,7 @@ struct Inner {
2929
}
3030

3131
pub struct FileDesc {
32-
inner: UnsafeArc<Inner>
32+
inner: Arc<Inner>
3333
}
3434

3535
impl FileDesc {
@@ -42,7 +42,7 @@ impl FileDesc {
4242
/// Note that all I/O operations done on this object will be *blocking*, but
4343
/// they do not require the runtime to be active.
4444
pub fn new(fd: fd_t, close_on_drop: bool) -> FileDesc {
45-
FileDesc { inner: UnsafeArc::new(Inner {
45+
FileDesc { inner: Arc::new(Inner {
4646
fd: fd,
4747
close_on_drop: close_on_drop
4848
}) }
@@ -79,11 +79,7 @@ impl FileDesc {
7979
}
8080
}
8181

82-
pub fn fd(&self) -> fd_t {
83-
// This unsafety is fine because we're just reading off the file
84-
// descriptor, no one is modifying this.
85-
unsafe { (*self.inner.get()).fd }
86-
}
82+
pub fn fd(&self) -> fd_t { self.inner.fd }
8783
}
8884

8985
impl io::Reader for FileDesc {

src/libnative/io/file_win32.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@
1010

1111
//! Blocking win32-based file I/O
1212
13+
use alloc::arc::Arc;
14+
use libc::{c_int, c_void};
15+
use libc;
1316
use std::c_str::CString;
1417
use std::io::IoError;
1518
use std::io;
16-
use libc::{c_int, c_void};
17-
use libc;
1819
use std::mem;
1920
use std::os::win32::{as_utf16_p, fill_utf16_buf_and_decode};
2021
use std::ptr;
2122
use std::rt::rtio;
2223
use std::str;
23-
use std::sync::arc::UnsafeArc;
2424
use std::vec;
2525

2626
use io::IoResult;
@@ -33,7 +33,7 @@ struct Inner {
3333
}
3434

3535
pub struct FileDesc {
36-
inner: UnsafeArc<Inner>
36+
inner: Arc<Inner>
3737
}
3838

3939
impl FileDesc {
@@ -46,7 +46,7 @@ impl FileDesc {
4646
/// Note that all I/O operations done on this object will be *blocking*, but
4747
/// they do not require the runtime to be active.
4848
pub fn new(fd: fd_t, close_on_drop: bool) -> FileDesc {
49-
FileDesc { inner: UnsafeArc::new(Inner {
49+
FileDesc { inner: Arc::new(Inner {
5050
fd: fd,
5151
close_on_drop: close_on_drop
5252
}) }
@@ -85,11 +85,7 @@ impl FileDesc {
8585
Ok(())
8686
}
8787

88-
pub fn fd(&self) -> fd_t {
89-
// This unsafety is fine because we're just reading off the file
90-
// descriptor, no one is modifying this.
91-
unsafe { (*self.inner.get()).fd }
92-
}
88+
pub fn fd(&self) -> fd_t { self.inner.fd }
9389

9490
pub fn handle(&self) -> libc::HANDLE {
9591
unsafe { libc::get_osfhandle(self.fd()) as libc::HANDLE }

0 commit comments

Comments
 (0)