libuv-svace-build
183 строки · 5.0 Кб
1/* Copyright libuv project and contributors. All rights reserved.
2*
3* Permission is hereby granted, free of charge, to any person obtaining a copy
4* of this software and associated documentation files (the "Software"), to
5* deal in the Software without restriction, including without limitation the
6* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7* sell copies of the Software, and to permit persons to whom the Software is
8* furnished to do so, subject to the following conditions:
9*
10* The above copyright notice and this permission notice shall be included in
11* all copies or substantial portions of the Software.
12*
13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19* IN THE SOFTWARE.
20*/
21
22#include "uv.h"23#include "task.h"24
25static uv_tcp_t client;26static uv_tcp_t connection;27static uv_connect_t connect_req;28static uv_timer_t timer;29
30static int read_cb_called;31static int on_close_called;32
33static void on_connection(uv_stream_t* server, int status);34
35static void on_client_connect(uv_connect_t* req, int status);36static void on_client_alloc(uv_handle_t* handle,37size_t suggested_size,38uv_buf_t* buf);39static void on_client_read(uv_stream_t* stream,40ssize_t nread,41const uv_buf_t* buf);42static void on_client_timeout(uv_timer_t* handle);43
44static void on_close(uv_handle_t* handle);45
46
47static void on_client_connect(uv_connect_t* conn_req, int status) {48int r;49
50r = uv_read_start((uv_stream_t*) &client, on_client_alloc, on_client_read);51ASSERT_OK(r);52
53r = uv_timer_start(&timer, on_client_timeout, 1000, 0);54ASSERT_OK(r);55}
56
57
58static void on_client_alloc(uv_handle_t* handle,59size_t suggested_size,60uv_buf_t* buf) {61static char slab[8];62buf->base = slab;63buf->len = sizeof(slab);64}
65
66
67static void on_client_read(uv_stream_t* stream, ssize_t nread,68const uv_buf_t* buf) {69ASSERT_LT(nread, 0);70read_cb_called++;71}
72
73
74static void on_client_timeout(uv_timer_t* handle) {75ASSERT_PTR_EQ(handle, &timer);76ASSERT_OK(read_cb_called);77uv_read_stop((uv_stream_t*) &client);78uv_close((uv_handle_t*) &client, on_close);79uv_close((uv_handle_t*) &timer, on_close);80}
81
82
83static void on_connection_alloc(uv_handle_t* handle,84size_t suggested_size,85uv_buf_t* buf) {86static char slab[8];87buf->base = slab;88buf->len = sizeof(slab);89}
90
91
92static void on_connection_read(uv_stream_t* stream,93ssize_t nread,94const uv_buf_t* buf) {95ASSERT_EQ(nread, UV_EOF);96read_cb_called++;97uv_close((uv_handle_t*) stream, on_close);98}
99
100
101static void on_connection(uv_stream_t* server, int status) {102int r;103
104ASSERT_OK(status);105ASSERT_OK(uv_accept(server, (uv_stream_t*) &connection));106
107r = uv_read_start((uv_stream_t*) &connection,108on_connection_alloc,109on_connection_read);110ASSERT_OK(r);111}
112
113
114static void on_close(uv_handle_t* handle) {115ASSERT_NE(handle == (uv_handle_t*) &client ||116handle == (uv_handle_t*) &connection ||117handle == (uv_handle_t*) &timer, 0);118on_close_called++;119}
120
121
122static void start_server(uv_loop_t* loop, uv_tcp_t* handle) {123struct sockaddr_in addr;124int r;125
126ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));127
128r = uv_tcp_init(loop, handle);129ASSERT_OK(r);130
131r = uv_tcp_bind(handle, (const struct sockaddr*) &addr, 0);132ASSERT_OK(r);133
134r = uv_listen((uv_stream_t*) handle, 128, on_connection);135ASSERT_OK(r);136
137uv_unref((uv_handle_t*) handle);138}
139
140
141/* Check that pending write requests have their callbacks
142* invoked when the handle is closed.
143*/
144TEST_IMPL(tcp_close_after_read_timeout) {145struct sockaddr_in addr;146uv_tcp_t tcp_server;147uv_loop_t* loop;148int r;149
150ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));151
152loop = uv_default_loop();153
154/* We can't use the echo server, it doesn't handle ECONNRESET. */155start_server(loop, &tcp_server);156
157r = uv_tcp_init(loop, &client);158ASSERT_OK(r);159
160r = uv_tcp_connect(&connect_req,161&client,162(const struct sockaddr*) &addr,163on_client_connect);164ASSERT_OK(r);165
166r = uv_tcp_init(loop, &connection);167ASSERT_OK(r);168
169r = uv_timer_init(loop, &timer);170ASSERT_OK(r);171
172ASSERT_OK(read_cb_called);173ASSERT_OK(on_close_called);174
175r = uv_run(loop, UV_RUN_DEFAULT);176ASSERT_OK(r);177
178ASSERT_EQ(1, read_cb_called);179ASSERT_EQ(3, on_close_called);180
181MAKE_VALGRIND_HAPPY(loop);182return 0;183}
184