blob: 28ddf58cc84535de8e718bf1d358293ca3753982 [file] [log] [blame]
Craig Tiller9fb89ea2016-03-11 20:12:45 -08001/*
2*
Craig Tillera45782f2016-03-11 20:15:51 -08003* Copyright 2016, Google Inc.
Craig Tiller9fb89ea2016-03-11 20:12:45 -08004* All rights reserved.
5*
6* Redistribution and use in source and binary forms, with or without
7* modification, are permitted provided that the following conditions are
8* met:
9*
10* * Redistributions of source code must retain the above copyright
11* notice, this list of conditions and the following disclaimer.
12* * Redistributions in binary form must reproduce the above
13* copyright notice, this list of conditions and the following disclaimer
14* in the documentation and/or other materials provided with the
15* distribution.
16* * Neither the name of Google Inc. nor the names of its
17* contributors may be used to endorse or promote products derived from
18* this software without specific prior written permission.
19*
20* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*
32*/
33
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +020034#include <memory.h>
Craig Tiller57e27432016-03-11 16:53:58 -080035#include <stdio.h>
36
37#include <grpc/grpc.h>
38#include <grpc/support/alloc.h>
Craig Tiller0ce7bec2016-03-11 17:02:07 -080039#include <grpc/support/log.h>
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +020040#include <grpc/support/string_util.h>
Craig Tiller57e27432016-03-11 16:53:58 -080041#include <grpc/support/thd.h>
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +020042
43#include "src/core/lib/iomgr/exec_ctx.h"
44#include "src/core/lib/iomgr/iomgr.h"
45#include "src/core/lib/iomgr/sockaddr_utils.h"
46#include "src/core/lib/iomgr/tcp_server.h"
47
48#include "test/core/util/port.h"
Craig Tiller0ce7bec2016-03-11 17:02:07 -080049#include "test/core/util/test_config.h"
Craig Tiller57e27432016-03-11 16:53:58 -080050
51#define NUM_THREADS 100
Masood Malekghassemi6643ce72016-03-14 14:21:08 -070052#define NUM_OUTER_LOOPS 10
53#define NUM_INNER_LOOPS 10
54#define DELAY_MILLIS 10
55#define POLL_MILLIS 3000
Craig Tiller57e27432016-03-11 16:53:58 -080056
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +020057static void *tag(int n) { return (void *)(uintptr_t)n; }
58static int detag(void *p) { return (int)(uintptr_t)p; }
59
60void create_loop_destroy(void *addr) {
Masood Malekghassemi6643ce72016-03-14 14:21:08 -070061 for (int i = 0; i < NUM_OUTER_LOOPS; ++i) {
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +020062 grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
Nicolas "Pixel" Noble90f03b52016-04-14 06:17:58 +020063 grpc_channel *chan = grpc_insecure_channel_create((char *)addr, NULL, NULL);
Craig Tiller57e27432016-03-11 16:53:58 -080064
Masood Malekghassemi6643ce72016-03-14 14:21:08 -070065 for (int j = 0; j < NUM_INNER_LOOPS; ++j) {
66 gpr_timespec later_time = GRPC_TIMEOUT_MILLIS_TO_DEADLINE(DELAY_MILLIS);
Craig Tiller57e27432016-03-11 16:53:58 -080067 grpc_connectivity_state state =
68 grpc_channel_check_connectivity_state(chan, 1);
69 grpc_channel_watch_connectivity_state(chan, state, later_time, cq, NULL);
Masood Malekghassemi6643ce72016-03-14 14:21:08 -070070 gpr_timespec poll_time = GRPC_TIMEOUT_MILLIS_TO_DEADLINE(POLL_MILLIS);
71 GPR_ASSERT(grpc_completion_queue_next(cq, poll_time, NULL).type ==
72 GRPC_OP_COMPLETE);
Craig Tiller57e27432016-03-11 16:53:58 -080073 }
Masood Malekghassemi6643ce72016-03-14 14:21:08 -070074 grpc_channel_destroy(chan);
75 grpc_completion_queue_destroy(cq);
Craig Tiller57e27432016-03-11 16:53:58 -080076 }
77}
78
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +020079struct server_thread_args {
80 char *addr;
81 grpc_server *server;
82 grpc_completion_queue *cq;
83 grpc_pollset *pollset;
84 gpr_mu *mu;
85 gpr_event ready;
86 gpr_atm stop;
87};
88
89void server_thread(void *vargs) {
Nicolas "Pixel" Noble90f03b52016-04-14 06:17:58 +020090 struct server_thread_args *args = (struct server_thread_args *)vargs;
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +020091 grpc_event ev;
92 gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
93 ev = grpc_completion_queue_next(args->cq, deadline, NULL);
94 GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
95 GPR_ASSERT(detag(ev.tag) == 0xd1e);
96}
97
98static void on_connect(grpc_exec_ctx *exec_ctx, void *vargs, grpc_endpoint *tcp,
99 grpc_tcp_server_acceptor *acceptor) {
Nicolas "Pixel" Noble90f03b52016-04-14 06:17:58 +0200100 struct server_thread_args *args = (struct server_thread_args *)vargs;
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +0200101 (void)acceptor;
102 grpc_endpoint_shutdown(exec_ctx, tcp);
103 grpc_endpoint_destroy(exec_ctx, tcp);
104 grpc_pollset_kick(args->pollset, NULL);
105}
106
107void bad_server_thread(void *vargs) {
Nicolas "Pixel" Noble90f03b52016-04-14 06:17:58 +0200108 struct server_thread_args *args = (struct server_thread_args *)vargs;
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +0200109
110 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
111 struct sockaddr_storage addr;
112 socklen_t addr_len = sizeof(addr);
113 int port;
114 grpc_tcp_server *s = grpc_tcp_server_create(NULL);
115 memset(&addr, 0, sizeof(addr));
116 addr.ss_family = AF_INET;
117 port = grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, addr_len);
118 GPR_ASSERT(port > 0);
119 gpr_asprintf(&args->addr, "localhost:%d", port);
120
121 grpc_tcp_server_start(&exec_ctx, s, &args->pollset, 1, on_connect, args);
122 gpr_event_set(&args->ready, (void *)1);
123
124 gpr_mu_lock(args->mu);
125 while (gpr_atm_acq_load(&args->stop) == 0) {
126 gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
Nicolas "Pixel" Noble90f03b52016-04-14 06:17:58 +0200127 gpr_timespec deadline =
128 gpr_time_add(now, gpr_time_from_millis(100, GPR_TIMESPAN));
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +0200129
130 grpc_pollset_worker *worker = NULL;
131 grpc_pollset_work(&exec_ctx, args->pollset, &worker, now, deadline);
132 gpr_mu_unlock(args->mu);
133 grpc_exec_ctx_finish(&exec_ctx);
134 gpr_mu_lock(args->mu);
135 }
136 gpr_mu_unlock(args->mu);
137
138 grpc_tcp_server_unref(&exec_ctx, s);
139
140 grpc_exec_ctx_finish(&exec_ctx);
141
142 gpr_free(args->addr);
143}
144
Craig Tiller653ea752016-04-25 07:40:23 -0700145static void done_pollset_shutdown(grpc_exec_ctx *exec_ctx, void *pollset,
146 bool success) {
147 grpc_pollset_destroy(pollset);
148 gpr_free(pollset);
149}
150
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +0200151int main(int argc, char **argv) {
152 struct server_thread_args args;
153 memset(&args, 0, sizeof(args));
154
Craig Tiller0ce7bec2016-03-11 17:02:07 -0800155 grpc_test_init(argc, argv);
Craig Tiller57e27432016-03-11 16:53:58 -0800156 grpc_init();
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +0200157
Craig Tiller57e27432016-03-11 16:53:58 -0800158 gpr_thd_id threads[NUM_THREADS];
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +0200159 gpr_thd_id server;
160
161 char *localhost = gpr_strdup("localhost:54321");
162 gpr_thd_options options = gpr_thd_options_default();
163 gpr_thd_options_set_joinable(&options);
164
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +0200165 /* First round, no server */
166 gpr_log(GPR_DEBUG, "Wave 1");
Masood Malekghassemi6643ce72016-03-14 14:21:08 -0700167 for (size_t i = 0; i < NUM_THREADS; ++i) {
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +0200168 gpr_thd_new(&threads[i], create_loop_destroy, localhost, &options);
Craig Tiller57e27432016-03-11 16:53:58 -0800169 }
Masood Malekghassemi6643ce72016-03-14 14:21:08 -0700170 for (size_t i = 0; i < NUM_THREADS; ++i) {
Craig Tiller57e27432016-03-11 16:53:58 -0800171 gpr_thd_join(threads[i]);
172 }
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +0200173 gpr_free(localhost);
174
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +0200175 /* Second round, actual grpc server */
176 gpr_log(GPR_DEBUG, "Wave 2");
177 int port = grpc_pick_unused_port_or_die();
178 gpr_asprintf(&args.addr, "localhost:%d", port);
179 args.server = grpc_server_create(NULL, NULL);
180 grpc_server_add_insecure_http2_port(args.server, args.addr);
181 args.cq = grpc_completion_queue_create(NULL);
182 grpc_server_register_completion_queue(args.server, args.cq, NULL);
183 grpc_server_start(args.server);
184 gpr_thd_new(&server, server_thread, &args, &options);
185
186 for (size_t i = 0; i < NUM_THREADS; ++i) {
187 gpr_thd_new(&threads[i], create_loop_destroy, args.addr, &options);
188 }
189 for (size_t i = 0; i < NUM_THREADS; ++i) {
190 gpr_thd_join(threads[i]);
191 }
192 grpc_server_shutdown_and_notify(args.server, args.cq, tag(0xd1e));
193
194 gpr_thd_join(server);
195 grpc_server_destroy(args.server);
196 grpc_completion_queue_destroy(args.cq);
197 gpr_free(args.addr);
198
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +0200199 /* Third round, bogus tcp server */
200 gpr_log(GPR_DEBUG, "Wave 3");
201 args.pollset = gpr_malloc(grpc_pollset_size());
202 grpc_pollset_init(args.pollset, &args.mu);
Craig Tiller418b9f92016-04-15 09:06:55 -0700203 gpr_event_init(&args.ready);
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +0200204 gpr_thd_new(&server, bad_server_thread, &args, &options);
205 gpr_event_wait(&args.ready, gpr_inf_future(GPR_CLOCK_MONOTONIC));
206
207 for (size_t i = 0; i < NUM_THREADS; ++i) {
208 gpr_thd_new(&threads[i], create_loop_destroy, args.addr, &options);
209 }
210 for (size_t i = 0; i < NUM_THREADS; ++i) {
211 gpr_thd_join(threads[i]);
212 }
213
214 gpr_atm_rel_store(&args.stop, 1);
215 gpr_thd_join(server);
Craig Tiller653ea752016-04-25 07:40:23 -0700216 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
217 grpc_pollset_shutdown(
218 &exec_ctx, args.pollset,
219 grpc_closure_create(done_pollset_shutdown, args.pollset));
220 grpc_exec_ctx_finish(&exec_ctx);
Nicolas "Pixel" Noble04f812b2016-04-13 20:27:51 +0200221
Craig Tiller57e27432016-03-11 16:53:58 -0800222 grpc_shutdown();
223 return 0;
224}