]>
Commit | Line | Data |
---|---|---|
85aaf69f | 1 | // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT |
1a4d82fc JJ |
2 | // file at the top-level directory of this distribution and at |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
1a4d82fc | 11 | // ignore-android needs extra network permissions |
9346a6ac | 12 | // ignore-bitrig system ulimit (Too many open files) |
c1a9b12d SL |
13 | // ignore-netbsd system ulimit (Too many open files) |
14 | // ignore-openbsd system ulimit (Too many open files) | |
7453a54e | 15 | // ignore-emscripten no threads or sockets support |
1a4d82fc | 16 | |
9346a6ac AL |
17 | use std::io::prelude::*; |
18 | use std::net::{TcpListener, TcpStream}; | |
19 | use std::process; | |
1a4d82fc | 20 | use std::sync::mpsc::channel; |
a7813a04 | 21 | use std::time::Duration; |
c34b1796 | 22 | use std::thread::{self, Builder}; |
1a4d82fc | 23 | |
5bcae85e SL |
24 | const TARGET_CNT: usize = 200; |
25 | ||
1a4d82fc JJ |
26 | fn main() { |
27 | // This test has a chance to time out, try to not let it time out | |
c34b1796 | 28 | thread::spawn(move|| -> () { |
a7813a04 | 29 | thread::sleep(Duration::from_secs(30)); |
9346a6ac | 30 | process::exit(1); |
1a4d82fc JJ |
31 | }); |
32 | ||
a7813a04 | 33 | let listener = TcpListener::bind("127.0.0.1:0").unwrap(); |
9346a6ac | 34 | let addr = listener.local_addr().unwrap(); |
c34b1796 | 35 | thread::spawn(move || -> () { |
1a4d82fc | 36 | loop { |
9346a6ac AL |
37 | let mut stream = match listener.accept() { |
38 | Ok(stream) => stream.0, | |
a7813a04 | 39 | Err(_) => continue, |
1a4d82fc | 40 | }; |
a7813a04 XL |
41 | let _ = stream.read(&mut [0]); |
42 | let _ = stream.write(&[2]); | |
1a4d82fc JJ |
43 | } |
44 | }); | |
1a4d82fc JJ |
45 | |
46 | let (tx, rx) = channel(); | |
5bcae85e | 47 | |
a7813a04 | 48 | let mut spawned_cnt = 0; |
5bcae85e | 49 | for _ in 0..TARGET_CNT { |
1a4d82fc | 50 | let tx = tx.clone(); |
a7813a04 | 51 | let res = Builder::new().stack_size(64 * 1024).spawn(move|| { |
1a4d82fc | 52 | match TcpStream::connect(addr) { |
9346a6ac | 53 | Ok(mut stream) => { |
a7813a04 XL |
54 | let _ = stream.write(&[1]); |
55 | let _ = stream.read(&mut [0]); | |
1a4d82fc | 56 | }, |
9346a6ac | 57 | Err(..) => {} |
1a4d82fc JJ |
58 | } |
59 | tx.send(()).unwrap(); | |
60 | }); | |
a7813a04 XL |
61 | if let Ok(_) = res { |
62 | spawned_cnt += 1; | |
63 | }; | |
1a4d82fc JJ |
64 | } |
65 | ||
66 | // Wait for all clients to exit, but don't wait for the server to exit. The | |
67 | // server just runs infinitely. | |
68 | drop(tx); | |
a7813a04 | 69 | for _ in 0..spawned_cnt { |
1a4d82fc JJ |
70 | rx.recv().unwrap(); |
71 | } | |
5bcae85e | 72 | assert_eq!(spawned_cnt, TARGET_CNT); |
9346a6ac | 73 | process::exit(0); |
1a4d82fc | 74 | } |