Skip to content

Commit bbac0c2

Browse files
olsonjefferybrson
authored andcommitted
---
yaml --- r: 12967 b: refs/heads/master c: 7e114b2 h: refs/heads/master i: 12965: ecd42e3 12963: b0cdb7a 12959: 1ccee08 v: v3
1 parent d8cf6bc commit bbac0c2

File tree

2 files changed

+127
-19
lines changed

2 files changed

+127
-19
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 5590dfc85775259a3ba313c75d88db0b7e2bd708
2+
refs/heads/master: 7e114b200abccb7dcbc03c47585828716dfc0f4a
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/libstd/net_tcp.rs

Lines changed: 126 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,38 @@ High-level interface to libuv's TCP functionality
44

55
import ip = net_ip;
66

7-
export tcp_connect_result;
8-
export connect;
7+
export tcp_connect_result, tcp_write_result;
8+
export connect, write;
99

10-
enum tcp_socket {
11-
valid_tcp_socket(@tcp_socket_data)
10+
resource tcp_socket(socket_data: @tcp_socket_data) unsafe {
11+
let closed_po = comm::port::<()>();
12+
let closed_ch = comm::chan(closed_po);
13+
let close_data = {
14+
closed_ch: closed_ch
15+
};
16+
let close_data_ptr = ptr::addr_of(close_data);
17+
let stream_handle_ptr = ptr::addr_of((*socket_data).stream_handle);
18+
uv::hl::interact((*socket_data).hl_loop) {|loop_ptr|
19+
log(debug, #fmt("interact dtor for tcp_socket stream %? loop %?",
20+
stream_handle_ptr, loop_ptr));
21+
uv::ll::set_data_for_uv_handle(stream_handle_ptr,
22+
close_data_ptr);
23+
uv::ll::close(stream_handle_ptr, tcp_socket_dtor_close_cb);
24+
};
25+
comm::recv(closed_po);
26+
log(debug, "exiting dtor for tcp_socket");
1227
}
1328

1429
enum tcp_connect_result {
1530
tcp_connected(tcp_socket),
1631
tcp_connect_error(uv::ll::uv_err_data)
1732
}
1833

34+
enum tcp_write_result {
35+
tcp_write_success,
36+
tcp_write_error(uv::ll::uv_err_data)
37+
}
38+
1939
#[doc="
2040
Initiate a client connection over TCP/IP
2141
@@ -37,19 +57,19 @@ fn connect(input_ip: ip::ip_addr, port: uint) -> tcp_connect_result unsafe {
3757
closed_signal_ch: comm::chan(closed_signal_po)
3858
};
3959
let conn_data_ptr = ptr::addr_of(conn_data);
60+
let hl_loop = uv::global_loop::get();
4061
let socket_data = @{
4162
reader_port: comm::port::<[u8]>(),
4263
stream_handle : uv::ll::tcp_t(),
4364
connect_req : uv::ll::connect_t(),
44-
write_req : uv::ll::write_t()
65+
write_req : uv::ll::write_t(),
66+
hl_loop: hl_loop
4567
};
4668
log(debug, #fmt("tcp_connect result_ch %?", conn_data.result_ch));
4769
// get an unsafe representation of our stream_handle_ptr that
4870
// we can send into the interact cb to be handled in libuv..
4971
let socket_data_ptr: *tcp_socket_data =
5072
ptr::addr_of(*socket_data);
51-
// in we go!
52-
let hl_loop = uv::global_loop::get();
5373
log(debug, #fmt("stream_handl_ptr outside interact %?",
5474
ptr::addr_of((*socket_data_ptr).stream_handle)));
5575
uv::hl::interact(hl_loop) {|loop_ptr|
@@ -113,7 +133,7 @@ fn connect(input_ip: ip::ip_addr, port: uint) -> tcp_connect_result unsafe {
113133
alt comm::recv(result_po) {
114134
conn_success {
115135
log(debug, "tcp::connect - received success on result_po");
116-
tcp_connected(valid_tcp_socket(socket_data))
136+
tcp_connected(tcp_socket(socket_data))
117137
}
118138
conn_failure(err_data) {
119139
comm::recv(closed_signal_po);
@@ -122,7 +142,87 @@ fn connect(input_ip: ip::ip_addr, port: uint) -> tcp_connect_result unsafe {
122142
}
123143
}
124144
}
145+
146+
#[doc="
147+
Write binary data to a tcp stream
148+
"]
149+
fn write(sock: tcp_socket, raw_write_data: [[u8]]) -> tcp_write_result
150+
unsafe {
151+
let socket_data_ptr = ptr::addr_of(**sock);
152+
let write_req_ptr = ptr::addr_of((*socket_data_ptr).write_req);
153+
let stream_handle_ptr =
154+
ptr::addr_of((*socket_data_ptr).stream_handle);
155+
let write_buf_vec = iter::map_to_vec(raw_write_data) {|raw_bytes|
156+
uv::ll::buf_init(vec::unsafe::to_ptr(raw_bytes),
157+
vec::len(raw_bytes))
158+
};
159+
let write_buf_vec_ptr = ptr::addr_of(write_buf_vec);
160+
let result_po = comm::port::<tcp_write_result>();
161+
let write_data = {
162+
result_ch: comm::chan(result_po)
163+
};
164+
let write_data_ptr = ptr::addr_of(write_data);
165+
uv::hl::interact((*socket_data_ptr).hl_loop) {|loop_ptr|
166+
log(debug, #fmt("in interact cb for tcp::write %?", loop_ptr));
167+
alt uv::ll::write(write_req_ptr,
168+
stream_handle_ptr,
169+
write_buf_vec_ptr,
170+
tcp_write_complete_cb) {
171+
0i32 {
172+
log(debug, "uv_write() invoked successfully");
173+
uv::ll::set_data_for_req(write_req_ptr, write_data_ptr);
174+
}
175+
_ {
176+
log(debug, "error invoking uv_write()");
177+
let err_data = uv::ll::get_last_err_data(loop_ptr);
178+
comm::send((*write_data_ptr).result_ch,
179+
tcp_write_error(err_data));
180+
}
181+
}
182+
};
183+
comm::recv(result_po)
184+
}
185+
186+
187+
125188
// INTERNAL API
189+
190+
type tcp_socket_close_data = {
191+
closed_ch: comm::chan<()>
192+
};
193+
194+
crust fn tcp_socket_dtor_close_cb(handle: *uv::ll::uv_tcp_t) unsafe {
195+
let data = uv::ll::get_data_for_uv_handle(handle)
196+
as *tcp_socket_close_data;
197+
let closed_ch = (*data).closed_ch;
198+
comm::send(closed_ch, ());
199+
log(debug, "tcp_socket_dtor_close_cb exiting..");
200+
}
201+
202+
crust fn tcp_write_complete_cb(write_req: *uv::ll::uv_write_t,
203+
status: libc::c_int) unsafe {
204+
let write_data_ptr = uv::ll::get_data_for_req(write_req)
205+
as *write_req_data;
206+
alt status {
207+
0i32 {
208+
log(debug, "successful write complete");
209+
comm::send((*write_data_ptr).result_ch, tcp_write_success);
210+
}
211+
_ {
212+
let stream_handle_ptr = uv::ll::get_stream_handle_from_write_req(
213+
write_req);
214+
let loop_ptr = uv::ll::get_loop_for_uv_handle(stream_handle_ptr);
215+
let err_data = uv::ll::get_last_err_data(loop_ptr);
216+
log(debug, "failure to write");
217+
comm::send((*write_data_ptr).result_ch, tcp_write_error(err_data));
218+
}
219+
}
220+
}
221+
222+
type write_req_data = {
223+
result_ch: comm::chan<tcp_write_result>
224+
};
225+
126226
type connect_req_data = {
127227
result_ch: comm::chan<conn_attempt>,
128228
closed_signal_ch: comm::chan<()>
@@ -177,7 +277,8 @@ type tcp_socket_data = {
177277
reader_port: comm::port<[u8]>,
178278
stream_handle: uv::ll::uv_tcp_t,
179279
connect_req: uv::ll::uv_connect_t,
180-
write_req: uv::ll::uv_write_t
280+
write_req: uv::ll::uv_write_t,
281+
hl_loop: uv::hl::high_level_loop
181282
};
182283

183284
// convert rust ip_addr to libuv's native representation
@@ -190,10 +291,10 @@ fn ipv4_ip_addr_to_sockaddr_in(input: ip::ip_addr,
190291
mod test {
191292
#[test]
192293
fn test_gl_tcp_ipv4_request() {
193-
let ip_str = "127.0.0.1";
294+
let ip_str = "173.194.79.99";
194295
let port = 80u;
195296
let expected_read_msg = "foo";
196-
let actual_write_msg = "bar";
297+
let actual_write_msg = "GET / HTTP/1.1\r\n\r\n";
197298
let host_ip = ip::v4::parse_addr(ip_str);
198299

199300
let data_po = comm::port::<[u8]>();
@@ -202,12 +303,16 @@ mod test {
202303
alt connect(host_ip, port) {
203304
tcp_connected(sock) {
204305
log(debug, "successful tcp connect");
205-
/*
206-
let write_data = str::as_buf(actual_write_msg);
207-
alt write(sock, [write_data]) {
306+
let mut write_data: [[u8]] = [];
307+
let write_data = [str::as_bytes(actual_write_msg) {|str_bytes|
308+
str_bytes
309+
}];
310+
alt write(sock, write_data) {
208311
tcp_write_success {
312+
log(debug, "tcp::write successful");
313+
/*
209314
let mut total_read_data: [u8] = [];
210-
let reader_po = read_start(sock);nyw
315+
let reader_po = read_start(sock);
211316
loop {
212317
alt comm::recv(reader_po) {
213318
new_read_data(data) {
@@ -228,12 +333,15 @@ mod test {
228333
}
229334
}
230335
comm::send(data_ch, total_read_data);
336+
*/
231337
}
232-
tcp_write_error {
233-
fail "error during write attempt.. FIXME need err info";
338+
tcp_write_error(err_data) {
339+
log(debug, "tcp_write_error received..");
340+
log(debug, #fmt("tcp write error: %? %?", err_data.err_name,
341+
err_data.err_msg));
342+
assert false;
234343
}
235344
}
236-
*/
237345
}
238346
tcp_connect_error(err_data) {
239347
log(debug, "tcp_connect_error received..");

0 commit comments

Comments
 (0)