Skip to content

Commit c0fb9cb

Browse files
committed
---
yaml --- r: 151429 b: refs/heads/try2 c: e27f27c h: refs/heads/master i: 151427: 8bfe044 v: v3
1 parent 0d27484 commit c0fb9cb

File tree

8 files changed

+432
-55
lines changed

8 files changed

+432
-55
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: 26632d541c3f548b064ffea57f0cb2057b48f947
8+
refs/heads/try2: e27f27c8588f5cfa0cd9dfbbdf7609ea2d6818ec
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libgraphviz/lib.rs

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,11 @@ type Nd = int;
5454
type Ed = (int,int);
5555
struct Edges(Vec<Ed>);
5656
57-
pub fn render_to<W:Writer>(output: &mut W) {
57+
pub fn main() {
58+
use std::io::File;
5859
let edges = Edges(vec!((0,1), (0,2), (1,3), (2,3), (3,4), (4,4)));
59-
dot::render(&edges, output).unwrap()
60+
let mut f = File::create(&Path::new("example1.dot"));
61+
dot::render(&edges, &mut f).unwrap()
6062
}
6163
6264
impl<'a> dot::Labeller<'a, Nd, Ed> for Edges {
@@ -89,17 +91,6 @@ impl<'a> dot::GraphWalk<'a, Nd, Ed> for Edges {
8991
9092
fn target(&self, e: &Ed) -> Nd { let &(_,t) = e; t }
9193
}
92-
93-
# pub fn main() { use std::io::MemWriter; render_to(&mut MemWriter::new()) }
94-
```
95-
96-
```no_run
97-
# pub fn render_to<W:Writer>(output: &mut W) { unimplemented!() }
98-
pub fn main() {
99-
use std::io::File;
100-
let mut f = File::create(&Path::new("example1.dot"));
101-
render_to(&mut f)
102-
}
10394
```
10495
10596
Output from first example (in `example1.dot`):
@@ -149,17 +140,19 @@ entity `&sube`).
149140
```rust
150141
use dot = graphviz;
151142
use std::str;
143+
use std::io::File;
152144
153145
type Nd = uint;
154146
type Ed<'a> = &'a (uint, uint);
155147
struct Graph { nodes: Vec<&'static str>, edges: Vec<(uint,uint)> }
156148
157-
pub fn render_to<W:Writer>(output: &mut W) {
149+
pub fn main() {
158150
let nodes = vec!("{x,y}","{x}","{y}","{}");
159151
let edges = vec!((0,1), (0,2), (1,3), (2,3));
160152
let graph = Graph { nodes: nodes, edges: edges };
161153
162-
dot::render(&graph, output).unwrap()
154+
let mut f = File::create(&Path::new("example2.dot"));
155+
dot::render(&graph, &mut f).unwrap()
163156
}
164157
165158
impl<'a> dot::Labeller<'a, Nd, Ed<'a>> for Graph {
@@ -181,17 +174,6 @@ impl<'a> dot::GraphWalk<'a, Nd, Ed<'a>> for Graph {
181174
fn source(&self, e: &Ed) -> Nd { let & &(s,_) = e; s }
182175
fn target(&self, e: &Ed) -> Nd { let & &(_,t) = e; t }
183176
}
184-
185-
# pub fn main() { use std::io::MemWriter; render_to(&mut MemWriter::new()) }
186-
```
187-
188-
```no_run
189-
# pub fn render_to<W:Writer>(output: &mut W) { unimplemented!() }
190-
pub fn main() {
191-
use std::io::File;
192-
let mut f = File::create(&Path::new("example2.dot"));
193-
render_to(&mut f)
194-
}
195177
```
196178
197179
The third example is similar to the second, except now each node and
@@ -205,17 +187,19 @@ Hasse-diagram for the subsets of the set `{x, y}`.
205187
```rust
206188
use dot = graphviz;
207189
use std::str;
190+
use std::io::File;
208191
209192
type Nd<'a> = (uint, &'a str);
210193
type Ed<'a> = (Nd<'a>, Nd<'a>);
211194
struct Graph { nodes: Vec<&'static str>, edges: Vec<(uint,uint)> }
212195
213-
pub fn render_to<W:Writer>(output: &mut W) {
196+
pub fn main() {
214197
let nodes = vec!("{x,y}","{x}","{y}","{}");
215198
let edges = vec!((0,1), (0,2), (1,3), (2,3));
216199
let graph = Graph { nodes: nodes, edges: edges };
217200
218-
dot::render(&graph, output).unwrap()
201+
let mut f = File::create(&Path::new("example3.dot"));
202+
dot::render(&graph, &mut f).unwrap()
219203
}
220204
221205
impl<'a> dot::Labeller<'a, Nd<'a>, Ed<'a>> for Graph {
@@ -245,17 +229,6 @@ impl<'a> dot::GraphWalk<'a, Nd<'a>, Ed<'a>> for Graph {
245229
fn source(&self, e: &Ed<'a>) -> Nd<'a> { let &(s,_) = e; s }
246230
fn target(&self, e: &Ed<'a>) -> Nd<'a> { let &(_,t) = e; t }
247231
}
248-
249-
# pub fn main() { use std::io::MemWriter; render_to(&mut MemWriter::new()) }
250-
```
251-
252-
```no_run
253-
# pub fn render_to<W:Writer>(output: &mut W) { unimplemented!() }
254-
pub fn main() {
255-
use std::io::File;
256-
let mut f = File::create(&Path::new("example3.dot"));
257-
render_to(&mut f)
258-
}
259232
```
260233
261234
# References

branches/try2/src/libstd/io/mod.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,17 @@ pub enum IoErrorKind {
434434
InvalidInput,
435435
/// The I/O operation's timeout expired, causing it to be canceled.
436436
TimedOut,
437+
/// This write operation failed to write all of its data.
438+
///
439+
/// Normally the write() method on a Writer guarantees that all of its data
440+
/// has been written, but some operations may be terminated after only
441+
/// partially writing some data. An example of this is a timed out write
442+
/// which successfully wrote a known number of bytes, but bailed out after
443+
/// doing so.
444+
///
445+
/// The payload contained as part of this variant is the number of bytes
446+
/// which are known to have been successfully written.
447+
ShortWrite(uint),
437448
}
438449

439450
/// A trait for objects which are byte-oriented streams. Readers are defined by
@@ -1429,7 +1440,8 @@ pub fn standard_error(kind: IoErrorKind) -> IoError {
14291440
PathDoesntExist => "no such file",
14301441
MismatchedFileTypeForOperation => "mismatched file type",
14311442
ResourceUnavailable => "resource unavailable",
1432-
TimedOut => "operation timed out"
1443+
TimedOut => "operation timed out",
1444+
ShortWrite(..) => "short write",
14331445
};
14341446
IoError {
14351447
kind: kind,

branches/try2/src/libstd/io/net/tcp.rs

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,69 @@ impl TcpStream {
151151
/// Note that this method affects all cloned handles associated with this
152152
/// stream, not just this one handle.
153153
pub fn close_write(&mut self) -> IoResult<()> { self.obj.close_write() }
154+
155+
/// Sets a timeout, in milliseconds, for blocking operations on this stream.
156+
///
157+
/// This function will set a timeout for all blocking operations (including
158+
/// reads and writes) on this stream. The timeout specified is a relative
159+
/// time, in milliseconds, into the future after which point operations will
160+
/// time out. This means that the timeout must be reset periodically to keep
161+
/// it from expiring. Specifying a value of `None` will clear the timeout
162+
/// for this stream.
163+
///
164+
/// The timeout on this stream is local to this stream only. Setting a
165+
/// timeout does not affect any other cloned instances of this stream, nor
166+
/// does the timeout propagated to cloned handles of this stream. Setting
167+
/// this timeout will override any specific read or write timeouts
168+
/// previously set for this stream.
169+
///
170+
/// For clarification on the semantics of interrupting a read and a write,
171+
/// take a look at `set_read_timeout` and `set_write_timeout`.
172+
pub fn set_timeout(&mut self, timeout_ms: Option<u64>) {
173+
self.obj.set_timeout(timeout_ms)
174+
}
175+
176+
/// Sets the timeout for read operations on this stream.
177+
///
178+
/// See documentation in `set_timeout` for the semantics of this read time.
179+
/// This will overwrite any previous read timeout set through either this
180+
/// function or `set_timeout`.
181+
///
182+
/// # Errors
183+
///
184+
/// When this timeout expires, if there is no pending read operation, no
185+
/// action is taken. Otherwise, the read operation will be scheduled to
186+
/// promptly return. If a timeout error is returned, then no data was read
187+
/// during the timeout period.
188+
pub fn set_read_timeout(&mut self, timeout_ms: Option<u64>) {
189+
self.obj.set_read_timeout(timeout_ms)
190+
}
191+
192+
/// Sets the timeout for write operations on this stream.
193+
///
194+
/// See documentation in `set_timeout` for the semantics of this write time.
195+
/// This will overwrite any previous write timeout set through either this
196+
/// function or `set_timeout`.
197+
///
198+
/// # Errors
199+
///
200+
/// When this timeout expires, if there is no pending write operation, no
201+
/// action is taken. Otherwise, the pending write operation will be
202+
/// scheduled to promptly return. The actual state of the underlying stream
203+
/// is not specified.
204+
///
205+
/// The write operation may return an error of type `ShortWrite` which
206+
/// indicates that the object is known to have written an exact number of
207+
/// bytes successfully during the timeout period, and the remaining bytes
208+
/// were never written.
209+
///
210+
/// If the write operation returns `TimedOut`, then it the timeout primitive
211+
/// does not know how many bytes were written as part of the timeout
212+
/// operation. It may be the case that bytes continue to be written in an
213+
/// asynchronous fashion after the call to write returns.
214+
pub fn set_write_timeout(&mut self, timeout_ms: Option<u64>) {
215+
self.obj.set_write_timeout(timeout_ms)
216+
}
154217
}
155218

156219
impl Clone for TcpStream {
@@ -892,6 +955,7 @@ mod test {
892955
Err(ref e) if e.kind == TimedOut => {}
893956
Err(e) => fail!("error: {}", e),
894957
}
958+
::task::deschedule();
895959
if i == 1000 { fail!("should have a pending connection") }
896960
}
897961
drop(l);
@@ -964,4 +1028,118 @@ mod test {
9641028
// this test will never finish if the child doesn't wake up
9651029
rx.recv();
9661030
})
1031+
1032+
iotest!(fn readwrite_timeouts() {
1033+
let addr = next_test_ip6();
1034+
let mut a = TcpListener::bind(addr).listen().unwrap();
1035+
let (tx, rx) = channel::<()>();
1036+
spawn(proc() {
1037+
let mut s = TcpStream::connect(addr).unwrap();
1038+
rx.recv();
1039+
assert!(s.write([0]).is_ok());
1040+
let _ = rx.recv_opt();
1041+
});
1042+
1043+
let mut s = a.accept().unwrap();
1044+
s.set_timeout(Some(20));
1045+
assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
1046+
assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
1047+
1048+
s.set_timeout(Some(20));
1049+
for i in range(0, 1001) {
1050+
match s.write([0, .. 128 * 1024]) {
1051+
Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
1052+
Err(IoError { kind: TimedOut, .. }) => break,
1053+
Err(e) => fail!("{}", e),
1054+
}
1055+
if i == 1000 { fail!("should have filled up?!"); }
1056+
}
1057+
assert_eq!(s.write([0]).err().unwrap().kind, TimedOut);
1058+
1059+
tx.send(());
1060+
s.set_timeout(None);
1061+
assert_eq!(s.read([0, 0]), Ok(1));
1062+
})
1063+
1064+
iotest!(fn read_timeouts() {
1065+
let addr = next_test_ip6();
1066+
let mut a = TcpListener::bind(addr).listen().unwrap();
1067+
let (tx, rx) = channel::<()>();
1068+
spawn(proc() {
1069+
let mut s = TcpStream::connect(addr).unwrap();
1070+
rx.recv();
1071+
let mut amt = 0;
1072+
while amt < 100 * 128 * 1024 {
1073+
match s.read([0, ..128 * 1024]) {
1074+
Ok(n) => { amt += n; }
1075+
Err(e) => fail!("{}", e),
1076+
}
1077+
}
1078+
let _ = rx.recv_opt();
1079+
});
1080+
1081+
let mut s = a.accept().unwrap();
1082+
s.set_read_timeout(Some(20));
1083+
assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
1084+
assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
1085+
1086+
tx.send(());
1087+
for _ in range(0, 100) {
1088+
assert!(s.write([0, ..128 * 1024]).is_ok());
1089+
}
1090+
})
1091+
1092+
iotest!(fn write_timeouts() {
1093+
let addr = next_test_ip6();
1094+
let mut a = TcpListener::bind(addr).listen().unwrap();
1095+
let (tx, rx) = channel::<()>();
1096+
spawn(proc() {
1097+
let mut s = TcpStream::connect(addr).unwrap();
1098+
rx.recv();
1099+
assert!(s.write([0]).is_ok());
1100+
let _ = rx.recv_opt();
1101+
});
1102+
1103+
let mut s = a.accept().unwrap();
1104+
s.set_write_timeout(Some(20));
1105+
for i in range(0, 1001) {
1106+
match s.write([0, .. 128 * 1024]) {
1107+
Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
1108+
Err(IoError { kind: TimedOut, .. }) => break,
1109+
Err(e) => fail!("{}", e),
1110+
}
1111+
if i == 1000 { fail!("should have filled up?!"); }
1112+
}
1113+
assert_eq!(s.write([0]).err().unwrap().kind, TimedOut);
1114+
1115+
tx.send(());
1116+
assert!(s.read([0]).is_ok());
1117+
})
1118+
1119+
iotest!(fn timeout_concurrent_read() {
1120+
let addr = next_test_ip6();
1121+
let mut a = TcpListener::bind(addr).listen().unwrap();
1122+
let (tx, rx) = channel::<()>();
1123+
spawn(proc() {
1124+
let mut s = TcpStream::connect(addr).unwrap();
1125+
rx.recv();
1126+
assert_eq!(s.write([0]), Ok(()));
1127+
let _ = rx.recv_opt();
1128+
});
1129+
1130+
let mut s = a.accept().unwrap();
1131+
let s2 = s.clone();
1132+
let (tx2, rx2) = channel();
1133+
spawn(proc() {
1134+
let mut s2 = s2;
1135+
assert_eq!(s2.read([0]), Ok(1));
1136+
tx2.send(());
1137+
});
1138+
1139+
s.set_read_timeout(Some(20));
1140+
assert_eq!(s.read([0]).err().unwrap().kind, TimedOut);
1141+
tx.send(());
1142+
1143+
rx2.recv();
1144+
})
9671145
}

0 commit comments

Comments
 (0)