1 /* 2 * 3 * Copyright 2015 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #include "src/core/lib/iomgr/sockaddr.h" 20 #include "src/core/lib/iomgr/socket_utils.h" 21 22 #include "test/core/util/test_tcp_server.h" 23 24 #include <grpc/grpc.h> 25 #include <grpc/support/alloc.h> 26 #include <grpc/support/log.h> 27 #include <grpc/support/sync.h> 28 #include <grpc/support/time.h> 29 #include <string.h> 30 31 #include "src/core/lib/gpr/host_port.h" 32 #include "src/core/lib/iomgr/endpoint.h" 33 #include "src/core/lib/iomgr/resolve_address.h" 34 #include "src/core/lib/iomgr/tcp_server.h" 35 #include "test/core/util/port.h" 36 #include "test/core/util/test_config.h" 37 38 static void on_server_destroyed(void* data, grpc_error* error) { 39 test_tcp_server* server = static_cast<test_tcp_server*>(data); 40 server->shutdown = 1; 41 } 42 43 void test_tcp_server_init(test_tcp_server* server, 44 grpc_tcp_server_cb on_connect, void* user_data) { 45 grpc_init(); 46 server->tcp_server = nullptr; 47 GRPC_CLOSURE_INIT(&server->shutdown_complete, on_server_destroyed, server, 48 grpc_schedule_on_exec_ctx); 49 server->shutdown = 0; 50 server->pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); 51 grpc_pollset_init(server->pollset, &server->mu); 52 server->on_connect = on_connect; 53 server->cb_data = user_data; 54 } 55 56 void test_tcp_server_start(test_tcp_server* server, int port) { 57 grpc_resolved_address resolved_addr; 58 grpc_sockaddr_in* addr = 59 reinterpret_cast<grpc_sockaddr_in*>(resolved_addr.addr); 60 int port_added; 61 grpc_core::ExecCtx exec_ctx; 62 63 addr->sin_family = GRPC_AF_INET; 64 addr->sin_port = grpc_htons(static_cast<uint16_t>(port)); 65 memset(&addr->sin_addr, 0, sizeof(addr->sin_addr)); 66 67 grpc_error* error = grpc_tcp_server_create(&server->shutdown_complete, 68 nullptr, &server->tcp_server); 69 GPR_ASSERT(error == GRPC_ERROR_NONE); 70 error = 71 grpc_tcp_server_add_port(server->tcp_server, &resolved_addr, &port_added); 72 GPR_ASSERT(error == GRPC_ERROR_NONE); 73 GPR_ASSERT(port_added == port); 74 75 grpc_tcp_server_start(server->tcp_server, &server->pollset, 1, 76 server->on_connect, server->cb_data); 77 gpr_log(GPR_INFO, "test tcp server listening on 0.0.0.0:%d", port); 78 } 79 80 void test_tcp_server_poll(test_tcp_server* server, int seconds) { 81 grpc_pollset_worker* worker = nullptr; 82 grpc_core::ExecCtx exec_ctx; 83 grpc_millis deadline = grpc_timespec_to_millis_round_up( 84 grpc_timeout_seconds_to_deadline(seconds)); 85 gpr_mu_lock(server->mu); 86 GRPC_LOG_IF_ERROR("pollset_work", 87 grpc_pollset_work(server->pollset, &worker, deadline)); 88 gpr_mu_unlock(server->mu); 89 } 90 91 static void do_nothing(void* arg, grpc_error* error) {} 92 static void finish_pollset(void* arg, grpc_error* error) { 93 grpc_pollset_destroy(static_cast<grpc_pollset*>(arg)); 94 } 95 96 void test_tcp_server_destroy(test_tcp_server* server) { 97 grpc_core::ExecCtx exec_ctx; 98 gpr_timespec shutdown_deadline; 99 grpc_closure do_nothing_cb; 100 grpc_tcp_server_unref(server->tcp_server); 101 GRPC_CLOSURE_INIT(&do_nothing_cb, do_nothing, nullptr, 102 grpc_schedule_on_exec_ctx); 103 shutdown_deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), 104 gpr_time_from_seconds(5, GPR_TIMESPAN)); 105 while (!server->shutdown && 106 gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), shutdown_deadline) < 0) { 107 test_tcp_server_poll(server, 1); 108 } 109 grpc_pollset_shutdown(server->pollset, 110 GRPC_CLOSURE_CREATE(finish_pollset, server->pollset, 111 grpc_schedule_on_exec_ctx)); 112 grpc_core::ExecCtx::Get()->Flush(); 113 gpr_free(server->pollset); 114 grpc_shutdown(); 115 } 116