libuv-svace-build
144 строки · 3.8 Кб
1/* Copyright Joyent, Inc. and other Node 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
25#include <stdio.h>26#include <stdlib.h>27
28#define WRITE_REQ_DATA "Hello, world."29#define NUM_WRITE_REQS (1000 * 1000)30
31typedef struct {32uv_write_t req;33uv_buf_t buf;34} write_req;35
36
37static write_req* write_reqs;38static uv_tcp_t tcp_client;39static uv_connect_t connect_req;40static uv_shutdown_t shutdown_req;41
42static int shutdown_cb_called = 0;43static int connect_cb_called = 0;44static int write_cb_called = 0;45static int close_cb_called = 0;46
47static void connect_cb(uv_connect_t* req, int status);48static void write_cb(uv_write_t* req, int status);49static void shutdown_cb(uv_shutdown_t* req, int status);50static void close_cb(uv_handle_t* handle);51
52
53static void connect_cb(uv_connect_t* req, int status) {54write_req* w;55int i;56int r;57
58ASSERT_PTR_EQ(req->handle, (uv_stream_t*)&tcp_client);59
60for (i = 0; i < NUM_WRITE_REQS; i++) {61w = &write_reqs[i];62r = uv_write(&w->req, req->handle, &w->buf, 1, write_cb);63ASSERT_OK(r);64}65
66r = uv_shutdown(&shutdown_req, req->handle, shutdown_cb);67ASSERT_OK(r);68
69connect_cb_called++;70}
71
72
73static void write_cb(uv_write_t* req, int status) {74ASSERT_NOT_NULL(req);75ASSERT_OK(status);76write_cb_called++;77}
78
79
80static void shutdown_cb(uv_shutdown_t* req, int status) {81ASSERT_PTR_EQ(req->handle, (uv_stream_t*)&tcp_client);82ASSERT_OK(req->handle->write_queue_size);83
84uv_close((uv_handle_t*)req->handle, close_cb);85free(write_reqs);86
87shutdown_cb_called++;88}
89
90
91static void close_cb(uv_handle_t* handle) {92ASSERT_PTR_EQ(handle, (uv_handle_t*)&tcp_client);93close_cb_called++;94}
95
96
97BENCHMARK_IMPL(tcp_write_batch) {98struct sockaddr_in addr;99uv_loop_t* loop;100uint64_t start;101uint64_t stop;102int i;103int r;104
105write_reqs = malloc(sizeof(*write_reqs) * NUM_WRITE_REQS);106ASSERT_NOT_NULL(write_reqs);107
108/* Prepare the data to write out. */109for (i = 0; i < NUM_WRITE_REQS; i++) {110write_reqs[i].buf = uv_buf_init(WRITE_REQ_DATA,111sizeof(WRITE_REQ_DATA) - 1);112}113
114loop = uv_default_loop();115ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));116
117r = uv_tcp_init(loop, &tcp_client);118ASSERT_OK(r);119
120r = uv_tcp_connect(&connect_req,121&tcp_client,122(const struct sockaddr*) &addr,123connect_cb);124ASSERT_OK(r);125
126start = uv_hrtime();127
128r = uv_run(loop, UV_RUN_DEFAULT);129ASSERT_OK(r);130
131stop = uv_hrtime();132
133ASSERT_EQ(1, connect_cb_called);134ASSERT_EQ(write_cb_called, NUM_WRITE_REQS);135ASSERT_EQ(1, shutdown_cb_called);136ASSERT_EQ(1, close_cb_called);137
138printf("%ld write requests in %.2fs.\n",139(long)NUM_WRITE_REQS,140(stop - start) / 1e9);141
142MAKE_VALGRIND_HAPPY(loop);143return 0;144}
145