@@ -34,7 +34,7 @@ use failure::LOCAL_STDERR;
3434use fmt;
3535use io:: { Reader , Writer , IoResult , IoError , OtherIoError , Buffer ,
3636 standard_error, EndOfFile , LineBufferedWriter , BufferedReader } ;
37- use kinds:: Send ;
37+ use kinds:: { Sync , Send } ;
3838use libc;
3939use mem;
4040use 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 ) ]
103108pub 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`.
108116pub struct StdinReaderGuard < ' a > {
109- inner : MutexGuard < ' a , BufferedReader < StdReader > > ,
117+ inner : MutexGuard < ' a , RaceBox > ,
110118}
111119
112120impl < ' a > Deref < BufferedReader < StdReader > > for StdinReaderGuard < ' a > {
113121 fn deref ( & self ) -> & BufferedReader < StdReader > {
114- & * self . inner
122+ & self . inner . 0
115123 }
116124}
117125
118126impl < ' 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
170178impl 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+
429440impl 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
0 commit comments