test-ping-pong.c
Go to the documentation of this file.
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 static int completed_pingers = 0;
29 
30 #if defined(__CYGWIN__) || defined(__MSYS__) || defined(__MVS__)
31 #define NUM_PINGS 100 /* fewer pings to avoid timeout */
32 #else
33 #define NUM_PINGS 1000
34 #endif
35 
36 /* 64 bytes is enough for a pinger */
37 #define BUFSIZE 10240
38 
39 static char PING[] = "PING\n";
41 
42 
43 typedef struct {
45  int pongs;
46  int state;
47  union {
48  uv_tcp_t tcp;
50  } stream;
52  char read_buffer[BUFSIZE];
53 } pinger_t;
54 
55 
56 static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
57  buf->base = malloc(size);
58  buf->len = size;
59 }
60 
61 
63  pinger_t* pinger = (pinger_t*)handle->data;
64 
65  ASSERT(NUM_PINGS == pinger->pongs);
66 
67  free(pinger);
68 
70 }
71 
72 
74  ASSERT(status == 0);
75  free(req);
76 }
77 
78 
79 static void pinger_write_ping(pinger_t* pinger) {
80  uv_write_t *req;
81  uv_buf_t bufs[sizeof PING - 1];
82  int i, nbufs;
83 
84  if (!pinger->vectored_writes) {
85  /* Write a single buffer. */
86  nbufs = 1;
87  bufs[0] = uv_buf_init(PING, sizeof PING - 1);
88  } else {
89  /* Write multiple buffers, each with one byte in them. */
90  nbufs = sizeof PING - 1;
91  for (i = 0; i < nbufs; i++) {
92  bufs[i] = uv_buf_init(&PING[i], 1);
93  }
94  }
95 
96  req = malloc(sizeof(*req));
97  if (uv_write(req,
98  (uv_stream_t*) &pinger->stream.tcp,
99  bufs,
100  nbufs,
102  FATAL("uv_write failed");
103  }
104 
105  puts("PING");
106 }
107 
108 
110  ssize_t nread,
111  const uv_buf_t* buf) {
112  ssize_t i;
113  pinger_t* pinger;
114 
115  pinger = (pinger_t*)stream->data;
116 
117  if (nread < 0) {
118  ASSERT(nread == UV_EOF);
119 
120  puts("got EOF");
121  free(buf->base);
122 
124 
125  return;
126  }
127 
128  /* Now we count the pings */
129  for (i = 0; i < nread; i++) {
130  ASSERT(buf->base[i] == PING[pinger->state]);
131  pinger->state = (pinger->state + 1) % (sizeof(PING) - 1);
132 
133  if (pinger->state != 0)
134  continue;
135 
136  printf("PONG %d\n", pinger->pongs);
137  pinger->pongs++;
138 
139  if (pinger->pongs < NUM_PINGS) {
140  pinger_write_ping(pinger);
141  } else {
143  break;
144  }
145  }
146 
147  free(buf->base);
148 }
149 
150 
152  pinger_t *pinger = (pinger_t*)req->handle->data;
153 
155 
156  ASSERT(status == 0);
157 
161 
162  pinger_write_ping(pinger);
163 
165 }
166 
167 
168 /* same ping-pong test, but using IPv6 connection */
169 static void tcp_pinger_v6_new(int vectored_writes) {
170  int r;
171  struct sockaddr_in6 server_addr;
172  pinger_t *pinger;
173 
174 
175  ASSERT(0 ==uv_ip6_addr("::1", TEST_PORT, &server_addr));
176  pinger = malloc(sizeof(*pinger));
177  ASSERT(pinger != NULL);
178  pinger->vectored_writes = vectored_writes;
179  pinger->state = 0;
180  pinger->pongs = 0;
181 
182  /* Try to connect to the server and do NUM_PINGS ping-pongs. */
183  r = uv_tcp_init(uv_default_loop(), &pinger->stream.tcp);
184  pinger->stream.tcp.data = pinger;
185  ASSERT(!r);
186 
187  /* We are never doing multiple reads/connects at a time anyway, so these
188  * handles can be pre-initialized. */
189  r = uv_tcp_connect(&pinger->connect_req,
190  &pinger->stream.tcp,
191  (const struct sockaddr*) &server_addr,
193  ASSERT(!r);
194 
195  /* Synchronous connect callbacks are not allowed. */
197 }
198 
199 
200 static void tcp_pinger_new(int vectored_writes) {
201  int r;
202  struct sockaddr_in server_addr;
203  pinger_t *pinger;
204 
205  ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
206  pinger = malloc(sizeof(*pinger));
207  ASSERT(pinger != NULL);
208  pinger->vectored_writes = vectored_writes;
209  pinger->state = 0;
210  pinger->pongs = 0;
211 
212  /* Try to connect to the server and do NUM_PINGS ping-pongs. */
213  r = uv_tcp_init(uv_default_loop(), &pinger->stream.tcp);
214  pinger->stream.tcp.data = pinger;
215  ASSERT(!r);
216 
217  /* We are never doing multiple reads/connects at a time anyway, so these
218  * handles can be pre-initialized. */
219  r = uv_tcp_connect(&pinger->connect_req,
220  &pinger->stream.tcp,
221  (const struct sockaddr*) &server_addr,
223  ASSERT(!r);
224 
225  /* Synchronous connect callbacks are not allowed. */
227 }
228 
229 
230 static void pipe_pinger_new(int vectored_writes) {
231  int r;
232  pinger_t *pinger;
233 
234  pinger = (pinger_t*)malloc(sizeof(*pinger));
235  ASSERT(pinger != NULL);
236  pinger->vectored_writes = vectored_writes;
237  pinger->state = 0;
238  pinger->pongs = 0;
239 
240  /* Try to connect to the server and do NUM_PINGS ping-pongs. */
241  r = uv_pipe_init(uv_default_loop(), &pinger->stream.pipe, 0);
242  pinger->stream.pipe.data = pinger;
243  ASSERT(!r);
244 
245  /* We are never doing multiple reads/connects at a time anyway, so these
246  * handles can be pre-initialized. */
249 
250  /* Synchronous connect callbacks are not allowed. */
252 }
253 
254 
255 static int run_ping_pong_test(void) {
258 
260  return 0;
261 }
262 
263 
264 TEST_IMPL(tcp_ping_pong) {
265  tcp_pinger_new(0);
266  return run_ping_pong_test();
267 }
268 
269 
270 TEST_IMPL(tcp_ping_pong_vec) {
271  tcp_pinger_new(1);
272  return run_ping_pong_test();
273 }
274 
275 
276 TEST_IMPL(tcp6_ping_pong) {
277  if (!can_ipv6())
278  RETURN_SKIP("IPv6 not supported");
280  return run_ping_pong_test();
281 }
282 
283 
284 TEST_IMPL(tcp6_ping_pong_vec) {
285  if (!can_ipv6())
286  RETURN_SKIP("IPv6 not supported");
288  return run_ping_pong_test();
289 }
290 
291 
292 TEST_IMPL(pipe_ping_pong) {
293  pipe_pinger_new(0);
294  return run_ping_pong_test();
295 }
296 
297 
298 TEST_IMPL(pipe_ping_pong_vec) {
299  pipe_pinger_new(1);
300  return run_ping_pong_test();
301 }
pinger_read_cb
static void pinger_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
Definition: test-ping-pong.c:109
uv_ip6_addr
UV_EXTERN int uv_ip6_addr(const char *ip, int port, struct sockaddr_in6 *addr)
Definition: uv-common.c:232
alloc_cb
static void alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf)
Definition: test-ping-pong.c:56
task.h
uv_pipe_connect
UV_EXTERN void uv_pipe_connect(uv_connect_t *req, uv_pipe_t *handle, const char *name, uv_connect_cb cb)
Definition: unix/pipe.c:173
uv_pipe_init
UV_EXTERN int uv_pipe_init(uv_loop_t *, uv_pipe_t *handle, int ipc)
Definition: unix/pipe.c:33
uv_connect_s
Definition: uv.h:580
BUFSIZE
#define BUFSIZE
Definition: test-ping-pong.c:37
NUM_PINGS
#define NUM_PINGS
Definition: test-ping-pong.c:33
pinger_t::pongs
int pongs
Definition: benchmark-ping-pongs.c:33
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
printf
_Use_decl_annotations_ int __cdecl printf(const char *_Format,...)
Definition: cs_driver.c:91
uv_connect_s::handle
uv_stream_t * handle
Definition: uv.h:583
ASSERT
#define ASSERT(expr)
Definition: task.h:102
tcp
static uv_tcp_t tcp
Definition: test-connection-fail.c:29
status
absl::Status status
Definition: rls.cc:251
pinger_on_connect
static void pinger_on_connect(uv_connect_t *req, int status)
Definition: test-ping-pong.c:151
pinger_write_ping
static void pinger_write_ping(pinger_t *pinger)
Definition: test-ping-pong.c:79
uv_run
UV_EXTERN int uv_run(uv_loop_t *, uv_run_mode mode)
Definition: unix/core.c:361
TEST_IMPL
TEST_IMPL(tcp_ping_pong)
Definition: test-ping-pong.c:264
uv_is_closing
UV_EXTERN int uv_is_closing(const uv_handle_t *handle)
Definition: unix/core.c:319
pinger_after_write
static void pinger_after_write(uv_write_t *req, int status)
Definition: test-ping-pong.c:73
TEST_PORT
#define TEST_PORT
Definition: task.h:53
uv_close
UV_EXTERN void uv_close(uv_handle_t *handle, uv_close_cb close_cb)
Definition: unix/core.c:112
uv_stream_s
Definition: uv.h:491
uv_tcp_connect
UV_EXTERN int uv_tcp_connect(uv_connect_t *req, uv_tcp_t *handle, const struct sockaddr *addr, uv_connect_cb cb)
Definition: uv-common.c:315
uv_ip4_addr
UV_EXTERN int uv_ip4_addr(const char *ip, int port, struct sockaddr_in *addr)
Definition: uv-common.c:221
uv_default_loop
UV_EXTERN uv_loop_t * uv_default_loop(void)
Definition: uv-common.c:733
ssize_t
intptr_t ssize_t
Definition: win.h:27
sockaddr_in6
Definition: ares_ipv6.h:25
uv_write
UV_EXTERN int uv_write(uv_write_t *req, uv_stream_t *handle, const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb)
Definition: unix/stream.c:1492
uv_is_readable
UV_EXTERN int uv_is_readable(const uv_stream_t *handle)
Definition: unix/stream.c:1606
req
static uv_connect_t req
Definition: test-connection-fail.c:30
UV_RUN_DEFAULT
@ UV_RUN_DEFAULT
Definition: uv.h:254
pinger_t::tcp
uv_tcp_t tcp
Definition: benchmark-ping-pongs.c:35
uv_read_start
UV_EXTERN int uv_read_start(uv_stream_t *, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
Definition: unix/stream.c:1555
pinger_on_close
static void pinger_on_close(uv_handle_t *handle)
Definition: test-ping-pong.c:62
uv_tcp_init
UV_EXTERN int uv_tcp_init(uv_loop_t *, uv_tcp_t *handle)
Definition: unix/tcp.c:143
pinger_t::pipe
uv_pipe_t pipe
Definition: test-ping-pong.c:49
pinger_t::stream
union pinger_t::@411 stream
uv_tcp_s
Definition: uv.h:544
pinger_t::connect_req
uv_connect_t connect_req
Definition: benchmark-ping-pongs.c:36
bufs
static uv_buf_t bufs[5]
Definition: benchmark-udp-pummel.c:51
uv.h
pinger_t::state
int state
Definition: benchmark-ping-pongs.c:34
MAKE_VALGRIND_HAPPY
#define MAKE_VALGRIND_HAPPY()
Definition: task.h:229
FATAL
#define FATAL(msg)
Definition: task.h:88
uv_buf_t
Definition: unix.h:121
pinger_t::vectored_writes
int vectored_writes
Definition: test-ping-pong.c:44
pinger_on_connect_count
static int pinger_on_connect_count
Definition: test-ping-pong.c:40
connect_req
static uv_connect_t connect_req
Definition: benchmark-tcp-write-batch.c:39
PING
static char PING[]
Definition: test-ping-pong.c:39
fix_build_deps.r
r
Definition: fix_build_deps.py:491
tcp_pinger_new
static void tcp_pinger_new(int vectored_writes)
Definition: test-ping-pong.c:200
tcp_pinger_v6_new
static void tcp_pinger_v6_new(int vectored_writes)
Definition: test-ping-pong.c:169
pinger_t
Definition: benchmark-ping-pongs.c:32
run_ping_pong_test
static int run_ping_pong_test(void)
Definition: test-ping-pong.c:255
uv_pipe_s
Definition: uv.h:757
uv_buf_init
UV_EXTERN uv_buf_t uv_buf_init(char *base, unsigned int len)
Definition: uv-common.c:157
can_ipv6
static UNUSED int can_ipv6(void)
Definition: task.h:315
uv_write_s
Definition: uv.h:522
RETURN_SKIP
#define RETURN_SKIP(explanation)
Definition: task.h:262
completed_pingers
static int completed_pingers
Definition: test-ping-pong.c:28
pipe_pinger_new
static void pipe_pinger_new(int vectored_writes)
Definition: test-ping-pong.c:230
handle
static csh handle
Definition: test_arm_regression.c:16
uv_handle_s
Definition: uv.h:441
TEST_PIPENAME
#define TEST_PIPENAME
Definition: task.h:61
uv_is_writable
UV_EXTERN int uv_is_writable(const uv_stream_t *handle)
Definition: unix/stream.c:1611
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
if
if(p->owned &&p->wrapped !=NULL)
Definition: call.c:42
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
state
static struct rpc_state state
Definition: bad_server_response_test.cc:87
stream
voidpf stream
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:26