Skip to content

Commit bb315f2

Browse files
committed
Implement RaceBox for StdinReader
1 parent 52072de commit bb315f2

File tree

4 files changed

+43
-16
lines changed

4 files changed

+43
-16
lines changed

src/libstd/io/buffered.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use result::Result::{Ok, Err};
2222
use slice::{SliceExt};
2323
use slice;
2424
use vec::Vec;
25+
use kinds::{Send,Sync};
2526

2627
/// Wraps a Reader and buffers input from it
2728
///
@@ -51,6 +52,11 @@ pub struct BufferedReader<R> {
5152
cap: uint,
5253
}
5354

55+
56+
unsafe impl<R: Send> Send for BufferedReader<R> {}
57+
unsafe impl<R: Send+Sync> Sync for BufferedReader<R> {}
58+
59+
5460
impl<R: Reader> BufferedReader<R> {
5561
/// Creates a new `BufferedReader` with the specified buffer capacity
5662
pub fn with_capacity(cap: uint, inner: R) -> BufferedReader<R> {

src/libstd/io/stdio.rs

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use failure::LOCAL_STDERR;
3434
use fmt;
3535
use io::{Reader, Writer, IoResult, IoError, OtherIoError, Buffer,
3636
standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
37-
use kinds::Send;
37+
use kinds::{Sync, Send};
3838
use libc;
3939
use mem;
4040
use option::Option;
@@ -98,26 +98,34 @@ thread_local! {
9898
}
9999
}
100100

101+
struct RaceBox(BufferedReader<StdReader>);
102+
103+
unsafe impl Send for RaceBox {}
104+
unsafe impl Sync for RaceBox {}
105+
101106
/// A synchronized wrapper around a buffered reader from stdin
102107
#[deriving(Clone)]
103108
pub struct StdinReader {
104-
inner: Arc<Mutex<BufferedReader<StdReader>>>,
109+
inner: Arc<Mutex<RaceBox>>,
105110
}
106111

112+
unsafe impl Send for StdinReader {}
113+
unsafe impl Sync for StdinReader {}
114+
107115
/// A guard for exclusive access to `StdinReader`'s internal `BufferedReader`.
108116
pub struct StdinReaderGuard<'a> {
109-
inner: MutexGuard<'a, BufferedReader<StdReader>>,
117+
inner: MutexGuard<'a, RaceBox>,
110118
}
111119

112120
impl<'a> Deref<BufferedReader<StdReader>> for StdinReaderGuard<'a> {
113121
fn deref(&self) -> &BufferedReader<StdReader> {
114-
&*self.inner
122+
&self.inner.0
115123
}
116124
}
117125

118126
impl<'a> DerefMut<BufferedReader<StdReader>> for StdinReaderGuard<'a> {
119127
fn deref_mut(&mut self) -> &mut BufferedReader<StdReader> {
120-
&mut *self.inner
128+
&mut self.inner.0
121129
}
122130
}
123131

@@ -147,53 +155,53 @@ impl StdinReader {
147155
/// The read is performed atomically - concurrent read calls in other
148156
/// threads will not interleave with this one.
149157
pub fn read_line(&mut self) -> IoResult<String> {
150-
self.inner.lock().read_line()
158+
self.inner.lock().0.read_line()
151159
}
152160

153161
/// Like `Buffer::read_until`.
154162
///
155163
/// The read is performed atomically - concurrent read calls in other
156164
/// threads will not interleave with this one.
157165
pub fn read_until(&mut self, byte: u8) -> IoResult<Vec<u8>> {
158-
self.inner.lock().read_until(byte)
166+
self.inner.lock().0.read_until(byte)
159167
}
160168

161169
/// Like `Buffer::read_char`.
162170
///
163171
/// The read is performed atomically - concurrent read calls in other
164172
/// threads will not interleave with this one.
165173
pub fn read_char(&mut self) -> IoResult<char> {
166-
self.inner.lock().read_char()
174+
self.inner.lock().0.read_char()
167175
}
168176
}
169177

170178
impl Reader for StdinReader {
171179
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
172-
self.inner.lock().read(buf)
180+
self.inner.lock().0.read(buf)
173181
}
174182

175183
// We have to manually delegate all of these because the default impls call
176184
// read more than once and we don't want those calls to interleave (or
177185
// incur the costs of repeated locking).
178186

179187
fn read_at_least(&mut self, min: uint, buf: &mut [u8]) -> IoResult<uint> {
180-
self.inner.lock().read_at_least(min, buf)
188+
self.inner.lock().0.read_at_least(min, buf)
181189
}
182190

183191
fn push_at_least(&mut self, min: uint, len: uint, buf: &mut Vec<u8>) -> IoResult<uint> {
184-
self.inner.lock().push_at_least(min, len, buf)
192+
self.inner.lock().0.push_at_least(min, len, buf)
185193
}
186194

187195
fn read_to_end(&mut self) -> IoResult<Vec<u8>> {
188-
self.inner.lock().read_to_end()
196+
self.inner.lock().0.read_to_end()
189197
}
190198

191199
fn read_le_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
192-
self.inner.lock().read_le_uint_n(nbytes)
200+
self.inner.lock().0.read_le_uint_n(nbytes)
193201
}
194202

195203
fn read_be_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
196-
self.inner.lock().read_be_uint_n(nbytes)
204+
self.inner.lock().0.read_be_uint_n(nbytes)
197205
}
198206
}
199207

@@ -221,7 +229,7 @@ pub fn stdin() -> StdinReader {
221229
BufferedReader::new(stdin_raw())
222230
};
223231
let stdin = StdinReader {
224-
inner: Arc::new(Mutex::new(stdin))
232+
inner: Arc::new(Mutex::new(RaceBox(stdin)))
225233
};
226234
STDIN = mem::transmute(box stdin);
227235

@@ -426,6 +434,9 @@ pub struct StdWriter {
426434
inner: StdSource
427435
}
428436

437+
unsafe impl Send for StdWriter {}
438+
unsafe impl Sync for StdWriter {}
439+
429440
impl StdWriter {
430441
/// Gets the size of this output window, if possible. This is typically used
431442
/// when the writer is attached to something like a terminal, this is used

src/libstd/sys/common/helper_thread.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ unsafe impl<M:Send> Send for Helper<M> { }
6363

6464
unsafe impl<M:Send> Sync for Helper<M> { }
6565

66+
struct RaceBox(helper_signal::signal);
67+
68+
unsafe impl Send for RaceBox {}
69+
unsafe impl Sync for RaceBox {}
70+
6671
impl<M: Send> Helper<M> {
6772
/// Lazily boots a helper thread, becoming a no-op if the helper has already
6873
/// been spawned.
@@ -85,9 +90,11 @@ impl<M: Send> Helper<M> {
8590
let (receive, send) = helper_signal::new();
8691
*self.signal.get() = send as uint;
8792

93+
let receive = RaceBox(receive);
94+
8895
let t = f();
8996
Thread::spawn(move |:| {
90-
helper(receive, rx, t);
97+
helper(receive.0, rx, t);
9198
let _g = self.lock.lock();
9299
*self.shutdown.get() = true;
93100
self.cond.notify_one()

src/libstd/sys/windows/timer.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ pub enum Req {
4848
RemoveTimer(libc::HANDLE, Sender<()>),
4949
}
5050

51+
unsafe impl Send for Req {}
52+
53+
5154
fn helper(input: libc::HANDLE, messages: Receiver<Req>, _: ()) {
5255
let mut objs = vec![input];
5356
let mut chans = vec![];

0 commit comments

Comments
 (0)