libuv-svace-build
143 строки · 4.4 Кб
1/* Copyright libuv project 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 <stdio.h>23#include <stdlib.h>24#include <string.h>25
26#include "task.h"27#include "uv.h"28
29static uv_tcp_t server;30static uv_tcp_t client;31static uv_tcp_t incoming;32static int connect_cb_called;33static int close_cb_called;34static int connection_cb_called;35static int write_cb_called;36static uv_write_t small_write;37static uv_write_t big_write;38
39/* 10 MB, which is large than the send buffer size and the recv buffer */
40static char data[1024 * 1024 * 10];41
42static void close_cb(uv_handle_t* handle) {43close_cb_called++;44}
45
46static void write_cb(uv_write_t* w, int status) {47/* the small write should finish immediately after the big write */48ASSERT_OK(uv_stream_get_write_queue_size((uv_stream_t*) &client));49
50write_cb_called++;51
52if (write_cb_called == 2) {53/* we are done */54uv_close((uv_handle_t*) &client, close_cb);55uv_close((uv_handle_t*) &incoming, close_cb);56uv_close((uv_handle_t*) &server, close_cb);57}58}
59
60static void connect_cb(uv_connect_t* _, int status) {61int r;62uv_buf_t buf;63size_t write_queue_size0, write_queue_size1;64
65ASSERT_OK(status);66connect_cb_called++;67
68/* fire a big write */69buf = uv_buf_init(data, sizeof(data));70r = uv_write(&small_write, (uv_stream_t*) &client, &buf, 1, write_cb);71ASSERT_OK(r);72
73/* check that the write process gets stuck */74write_queue_size0 = uv_stream_get_write_queue_size((uv_stream_t*) &client);75ASSERT_GT(write_queue_size0, 0);76
77/* fire a small write, which should be queued */78buf = uv_buf_init("A", 1);79r = uv_write(&big_write, (uv_stream_t*) &client, &buf, 1, write_cb);80ASSERT_OK(r);81
82write_queue_size1 = uv_stream_get_write_queue_size((uv_stream_t*) &client);83ASSERT_EQ(write_queue_size1, write_queue_size0 + 1);84}
85
86static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {87static char base[1024];88
89buf->base = base;90buf->len = sizeof(base);91}
92
93static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {}94
95static void connection_cb(uv_stream_t* tcp, int status) {96ASSERT_OK(status);97connection_cb_called++;98
99ASSERT_OK(uv_tcp_init(tcp->loop, &incoming));100ASSERT_OK(uv_accept(tcp, (uv_stream_t*) &incoming));101ASSERT_OK(uv_read_start((uv_stream_t*) &incoming, alloc_cb, read_cb));102}
103
104static void start_server(void) {105struct sockaddr_in addr;106
107ASSERT_OK(uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));108
109ASSERT_OK(uv_tcp_init(uv_default_loop(), &server));110ASSERT_OK(uv_tcp_bind(&server, (struct sockaddr*) &addr, 0));111ASSERT_OK(uv_listen((uv_stream_t*) &server, 128, connection_cb));112}
113
114TEST_IMPL(tcp_write_in_a_row) {115#if defined(_WIN32)116RETURN_SKIP("tcp_write_in_a_row does not work on Windows");117#elif defined(__PASE__)118RETURN_SKIP("tcp_write_in_a_row does not work on IBM i PASE");119#else120uv_connect_t connect_req;121struct sockaddr_in addr;122
123start_server();124
125ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));126
127ASSERT_OK(uv_tcp_init(uv_default_loop(), &client));128ASSERT_OK(uv_tcp_connect(&connect_req,129&client,130(struct sockaddr*) &addr,131connect_cb));132
133ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));134
135ASSERT_EQ(1, connect_cb_called);136ASSERT_EQ(3, close_cb_called);137ASSERT_EQ(1, connection_cb_called);138ASSERT_EQ(2, write_cb_called);139
140MAKE_VALGRIND_HAPPY(uv_default_loop());141return 0;142#endif143}
144