Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 1 | /* |
| 2 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 3 | * Copyright 2015 gRPC authors. |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 4 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 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 |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 8 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 10 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 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. |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 16 | * |
| 17 | */ |
| 18 | |
murgatroid99 | 5407089 | 2016-08-08 17:01:18 -0700 | [diff] [blame] | 19 | #include "src/core/lib/iomgr/port.h" |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 20 | |
murgatroid99 | 623dd4f | 2016-08-08 17:31:27 -0700 | [diff] [blame] | 21 | #ifdef GRPC_WINSOCK_SOCKET |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 22 | |
Nicolas "Pixel" Noble | c4b18a5 | 2016-04-15 04:53:54 +0200 | [diff] [blame] | 23 | #include <limits.h> |
| 24 | |
Makarand Dharmapurikar | 0579cfc | 2016-06-20 15:45:24 -0700 | [diff] [blame] | 25 | #include "src/core/lib/iomgr/network_status_tracker.h" |
Yuchen Zeng | 12dfdc3 | 2016-04-26 22:05:41 -0700 | [diff] [blame] | 26 | #include "src/core/lib/iomgr/sockaddr_windows.h" |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 27 | |
Craig Tiller | 28b7242 | 2016-10-26 21:15:29 -0700 | [diff] [blame] | 28 | #include <grpc/slice_buffer.h> |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 29 | #include <grpc/support/alloc.h> |
| 30 | #include <grpc/support/log.h> |
Yuchen Zeng | 12dfdc3 | 2016-04-26 22:05:41 -0700 | [diff] [blame] | 31 | #include <grpc/support/log_windows.h> |
Masood Malekghassemi | 701af60 | 2015-06-03 15:01:17 -0700 | [diff] [blame] | 32 | #include <grpc/support/string_util.h> |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 33 | #include <grpc/support/useful.h> |
| 34 | |
Craig Tiller | 9533d04 | 2016-03-25 17:11:06 -0700 | [diff] [blame] | 35 | #include "src/core/lib/iomgr/iocp_windows.h" |
| 36 | #include "src/core/lib/iomgr/sockaddr.h" |
| 37 | #include "src/core/lib/iomgr/sockaddr_utils.h" |
| 38 | #include "src/core/lib/iomgr/socket_windows.h" |
| 39 | #include "src/core/lib/iomgr/tcp_client.h" |
Yash Tibrewal | 547653e | 2017-09-25 21:20:19 -0700 | [diff] [blame] | 40 | #include "src/core/lib/iomgr/tcp_windows.h" |
Craig Tiller | 9533d04 | 2016-03-25 17:11:06 -0700 | [diff] [blame] | 41 | #include "src/core/lib/iomgr/timer.h" |
Craig Tiller | fede4d4 | 2016-12-06 20:20:10 -0800 | [diff] [blame] | 42 | #include "src/core/lib/slice/slice_internal.h" |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 43 | |
Nicolas "Pixel" Noble | c4b18a5 | 2016-04-15 04:53:54 +0200 | [diff] [blame] | 44 | #if defined(__MSYS__) && defined(GPR_ARCH_64) |
| 45 | /* Nasty workaround for nasty bug when using the 64 bits msys compiler |
| 46 | in conjunction with Microsoft Windows headers. */ |
| 47 | #define GRPC_FIONBIO _IOW('f', 126, uint32_t) |
| 48 | #else |
| 49 | #define GRPC_FIONBIO FIONBIO |
| 50 | #endif |
| 51 | |
ncteisen | 06bce6e | 2017-07-10 07:58:49 -0700 | [diff] [blame] | 52 | grpc_tracer_flag grpc_tcp_trace = GRPC_TRACER_INITIALIZER(false, "tcp"); |
ncteisen | 0e3aee3 | 2017-06-08 16:32:24 -0700 | [diff] [blame] | 53 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 54 | static grpc_error* set_non_block(SOCKET sock) { |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 55 | int status; |
Nicolas "Pixel" Noble | c4b18a5 | 2016-04-15 04:53:54 +0200 | [diff] [blame] | 56 | uint32_t param = 1; |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 57 | DWORD ret; |
Nicolas "Pixel" Noble | 344f55b | 2016-04-15 07:52:25 +0200 | [diff] [blame] | 58 | status = WSAIoctl(sock, GRPC_FIONBIO, ¶m, sizeof(param), NULL, 0, &ret, |
| 59 | NULL, NULL); |
Craig Tiller | 3e149f3 | 2016-05-17 16:11:04 -0700 | [diff] [blame] | 60 | return status == 0 |
| 61 | ? GRPC_ERROR_NONE |
| 62 | : GRPC_WSA_ERROR(WSAGetLastError(), "WSAIoctl(GRPC_FIONBIO)"); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 63 | } |
| 64 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 65 | static grpc_error* set_dualstack(SOCKET sock) { |
Nicolas "Pixel" Noble | ee0c96c | 2015-02-04 23:35:41 +0100 | [diff] [blame] | 66 | int status; |
| 67 | unsigned long param = 0; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 68 | status = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)¶m, |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 69 | sizeof(param)); |
Craig Tiller | 3e149f3 | 2016-05-17 16:11:04 -0700 | [diff] [blame] | 70 | return status == 0 |
| 71 | ? GRPC_ERROR_NONE |
| 72 | : GRPC_WSA_ERROR(WSAGetLastError(), "setsockopt(IPV6_V6ONLY)"); |
Nicolas "Pixel" Noble | ee0c96c | 2015-02-04 23:35:41 +0100 | [diff] [blame] | 73 | } |
| 74 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 75 | grpc_error* grpc_tcp_prepare_socket(SOCKET sock) { |
| 76 | grpc_error* err; |
Craig Tiller | a41ac57 | 2016-05-17 16:08:17 -0700 | [diff] [blame] | 77 | err = set_non_block(sock); |
| 78 | if (err != GRPC_ERROR_NONE) return err; |
| 79 | err = set_dualstack(sock); |
| 80 | if (err != GRPC_ERROR_NONE) return err; |
| 81 | return GRPC_ERROR_NONE; |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 82 | } |
| 83 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 84 | typedef struct grpc_tcp { |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 85 | /* This is our C++ class derivation emulation. */ |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 86 | grpc_endpoint base; |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 87 | /* The one socket this endpoint is using. */ |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 88 | grpc_winsocket* socket; |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 89 | /* Refcounting how many operations are in progress. */ |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 90 | gpr_refcount refcount; |
| 91 | |
Craig Tiller | 82f9bd8 | 2015-09-23 09:31:51 -0700 | [diff] [blame] | 92 | grpc_closure on_read; |
| 93 | grpc_closure on_write; |
| 94 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 95 | grpc_closure* read_cb; |
| 96 | grpc_closure* write_cb; |
Craig Tiller | d41a4a7 | 2016-10-26 16:16:06 -0700 | [diff] [blame] | 97 | grpc_slice read_slice; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 98 | grpc_slice_buffer* write_slices; |
| 99 | grpc_slice_buffer* read_slices; |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 100 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 101 | grpc_resource_user* resource_user; |
Craig Tiller | 290e9a7 | 2016-10-28 08:17:00 -0700 | [diff] [blame] | 102 | |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 103 | /* The IO Completion Port runs from another thread. We need some mechanism |
| 104 | to protect ourselves when requesting a shutdown. */ |
| 105 | gpr_mu mu; |
| 106 | int shutting_down; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 107 | grpc_error* shutdown_error; |
Craig Tiller | 81bcc4c | 2015-07-20 14:04:18 -0700 | [diff] [blame] | 108 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 109 | char* peer_string; |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 110 | } grpc_tcp; |
| 111 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 112 | static void tcp_free(grpc_exec_ctx* exec_ctx, grpc_tcp* tcp) { |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 113 | grpc_winsocket_destroy(tcp->socket); |
| 114 | gpr_mu_destroy(&tcp->mu); |
| 115 | gpr_free(tcp->peer_string); |
Craig Tiller | c037fc1 | 2016-11-04 14:04:54 -0700 | [diff] [blame] | 116 | grpc_resource_user_unref(exec_ctx, tcp->resource_user); |
Craig Tiller | 6ba80f9 | 2017-01-27 11:58:32 -0800 | [diff] [blame] | 117 | if (tcp->shutting_down) GRPC_ERROR_UNREF(tcp->shutdown_error); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 118 | gpr_free(tcp); |
Craig Tiller | b029859 | 2015-08-27 07:38:01 -0700 | [diff] [blame] | 119 | } |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 120 | |
ncteisen | 0e3aee3 | 2017-06-08 16:32:24 -0700 | [diff] [blame] | 121 | #ifndef NDEBUG |
Craig Tiller | fe6350d | 2016-11-04 14:05:45 -0700 | [diff] [blame] | 122 | #define TCP_UNREF(exec_ctx, tcp, reason) \ |
| 123 | tcp_unref((exec_ctx), (tcp), (reason), __FILE__, __LINE__) |
Craig Tiller | b029859 | 2015-08-27 07:38:01 -0700 | [diff] [blame] | 124 | #define TCP_REF(tcp, reason) tcp_ref((tcp), (reason), __FILE__, __LINE__) |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 125 | static void tcp_unref(grpc_exec_ctx* exec_ctx, grpc_tcp* tcp, |
| 126 | const char* reason, const char* file, int line) { |
ncteisen | 0e3aee3 | 2017-06-08 16:32:24 -0700 | [diff] [blame] | 127 | if (GRPC_TRACER_ON(grpc_tcp_trace)) { |
| 128 | gpr_atm val = gpr_atm_no_barrier_load(&tcp->refcount.count); |
ncteisen | d39010e | 2017-06-08 17:08:07 -0700 | [diff] [blame] | 129 | gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, |
| 130 | "TCP unref %p : %s %" PRIdPTR " -> %" PRIdPTR, tcp, reason, val, |
| 131 | val - 1); |
ncteisen | 0e3aee3 | 2017-06-08 16:32:24 -0700 | [diff] [blame] | 132 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 133 | if (gpr_unref(&tcp->refcount)) { |
Craig Tiller | c037fc1 | 2016-11-04 14:04:54 -0700 | [diff] [blame] | 134 | tcp_free(exec_ctx, tcp); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 135 | } |
Craig Tiller | 0882a35 | 2015-08-26 13:21:14 -0700 | [diff] [blame] | 136 | } |
| 137 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 138 | static void tcp_ref(grpc_tcp* tcp, const char* reason, const char* file, |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 139 | int line) { |
ncteisen | 0e3aee3 | 2017-06-08 16:32:24 -0700 | [diff] [blame] | 140 | if (GRPC_TRACER_ON(grpc_tcp_trace)) { |
| 141 | gpr_atm val = gpr_atm_no_barrier_load(&tcp->refcount.count); |
ncteisen | d39010e | 2017-06-08 17:08:07 -0700 | [diff] [blame] | 142 | gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, |
| 143 | "TCP ref %p : %s %" PRIdPTR " -> %" PRIdPTR, tcp, reason, val, |
| 144 | val + 1); |
ncteisen | 0e3aee3 | 2017-06-08 16:32:24 -0700 | [diff] [blame] | 145 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 146 | gpr_ref(&tcp->refcount); |
Craig Tiller | b029859 | 2015-08-27 07:38:01 -0700 | [diff] [blame] | 147 | } |
| 148 | #else |
Craig Tiller | c037fc1 | 2016-11-04 14:04:54 -0700 | [diff] [blame] | 149 | #define TCP_UNREF(exec_ctx, tcp, reason) tcp_unref((exec_ctx), (tcp)) |
Craig Tiller | b029859 | 2015-08-27 07:38:01 -0700 | [diff] [blame] | 150 | #define TCP_REF(tcp, reason) tcp_ref((tcp)) |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 151 | static void tcp_unref(grpc_exec_ctx* exec_ctx, grpc_tcp* tcp) { |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 152 | if (gpr_unref(&tcp->refcount)) { |
Craig Tiller | c037fc1 | 2016-11-04 14:04:54 -0700 | [diff] [blame] | 153 | tcp_free(exec_ctx, tcp); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 154 | } |
Craig Tiller | b029859 | 2015-08-27 07:38:01 -0700 | [diff] [blame] | 155 | } |
| 156 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 157 | static void tcp_ref(grpc_tcp* tcp) { gpr_ref(&tcp->refcount); } |
Craig Tiller | b029859 | 2015-08-27 07:38:01 -0700 | [diff] [blame] | 158 | #endif |
| 159 | |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 160 | /* Asynchronous callback from the IOCP, or the background thread. */ |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 161 | static void on_read(grpc_exec_ctx* exec_ctx, void* tcpp, grpc_error* error) { |
| 162 | grpc_tcp* tcp = (grpc_tcp*)tcpp; |
| 163 | grpc_closure* cb = tcp->read_cb; |
| 164 | grpc_winsocket* socket = tcp->socket; |
Craig Tiller | d41a4a7 | 2016-10-26 16:16:06 -0700 | [diff] [blame] | 165 | grpc_slice sub; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 166 | grpc_winsocket_callback_info* info = &socket->read_info; |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 167 | |
Craig Tiller | a41ac57 | 2016-05-17 16:08:17 -0700 | [diff] [blame] | 168 | GRPC_ERROR_REF(error); |
| 169 | |
| 170 | if (error == GRPC_ERROR_NONE) { |
Jan Tattermusch | 6412479 | 2016-03-25 09:16:22 -0700 | [diff] [blame] | 171 | if (info->wsa_error != 0 && !tcp->shutting_down) { |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 172 | char* utf8_message = gpr_format_message(info->wsa_error); |
ncteisen | 4b36a3d | 2017-03-13 19:08:06 -0700 | [diff] [blame] | 173 | error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(utf8_message); |
Craig Tiller | a41ac57 | 2016-05-17 16:08:17 -0700 | [diff] [blame] | 174 | gpr_free(utf8_message); |
Craig Tiller | a59c16c | 2016-10-31 07:25:01 -0700 | [diff] [blame] | 175 | grpc_slice_unref_internal(exec_ctx, tcp->read_slice); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 176 | } else { |
Nicolas "Pixel" Noble | 3a26c5b | 2015-09-22 00:07:14 +0200 | [diff] [blame] | 177 | if (info->bytes_transfered != 0 && !tcp->shutting_down) { |
Craig Tiller | d41a4a7 | 2016-10-26 16:16:06 -0700 | [diff] [blame] | 178 | sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); |
| 179 | grpc_slice_buffer_add(tcp->read_slices, sub); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 180 | } else { |
Craig Tiller | a59c16c | 2016-10-31 07:25:01 -0700 | [diff] [blame] | 181 | grpc_slice_unref_internal(exec_ctx, tcp->read_slice); |
Craig Tiller | 393a4d9 | 2017-01-27 12:01:44 -0800 | [diff] [blame] | 182 | error = tcp->shutting_down |
ncteisen | 4b36a3d | 2017-03-13 19:08:06 -0700 | [diff] [blame] | 183 | ? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
| 184 | "TCP stream shutting down", &tcp->shutdown_error, 1) |
| 185 | : GRPC_ERROR_CREATE_FROM_STATIC_STRING("End of TCP stream"); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 186 | } |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 187 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 188 | } |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 189 | |
Craig Tiller | b029859 | 2015-08-27 07:38:01 -0700 | [diff] [blame] | 190 | tcp->read_cb = NULL; |
Craig Tiller | c037fc1 | 2016-11-04 14:04:54 -0700 | [diff] [blame] | 191 | TCP_UNREF(exec_ctx, tcp, "read"); |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 192 | GRPC_CLOSURE_SCHED(exec_ctx, cb, error); |
Craig Tiller | b029859 | 2015-08-27 07:38:01 -0700 | [diff] [blame] | 193 | } |
| 194 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 195 | static void win_read(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep, |
| 196 | grpc_slice_buffer* read_slices, grpc_closure* cb) { |
| 197 | grpc_tcp* tcp = (grpc_tcp*)ep; |
| 198 | grpc_winsocket* handle = tcp->socket; |
| 199 | grpc_winsocket_callback_info* info = &handle->read_info; |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 200 | int status; |
| 201 | DWORD bytes_read = 0; |
| 202 | DWORD flags = 0; |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 203 | WSABUF buffer; |
| 204 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 205 | if (tcp->shutting_down) { |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 206 | GRPC_CLOSURE_SCHED( |
ncteisen | 4b36a3d | 2017-03-13 19:08:06 -0700 | [diff] [blame] | 207 | exec_ctx, cb, |
| 208 | GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
| 209 | "TCP socket is shutting down", &tcp->shutdown_error, 1)); |
Craig Tiller | 82f9bd8 | 2015-09-23 09:31:51 -0700 | [diff] [blame] | 210 | return; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 211 | } |
Craig Tiller | b029859 | 2015-08-27 07:38:01 -0700 | [diff] [blame] | 212 | |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 213 | tcp->read_cb = cb; |
Craig Tiller | b029859 | 2015-08-27 07:38:01 -0700 | [diff] [blame] | 214 | tcp->read_slices = read_slices; |
Craig Tiller | a59c16c | 2016-10-31 07:25:01 -0700 | [diff] [blame] | 215 | grpc_slice_buffer_reset_and_unref_internal(exec_ctx, read_slices); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 216 | |
Craig Tiller | 423d6fd | 2017-04-12 13:15:45 -0700 | [diff] [blame] | 217 | tcp->read_slice = GRPC_SLICE_MALLOC(8192); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 218 | |
Craig Tiller | 618e67d | 2016-10-26 21:08:10 -0700 | [diff] [blame] | 219 | buffer.len = (ULONG)GRPC_SLICE_LENGTH( |
Craig Tiller | 620e965 | 2015-12-14 12:02:50 -0800 | [diff] [blame] | 220 | tcp->read_slice); // we know slice size fits in 32bit. |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 221 | buffer.buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slice); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 222 | |
Craig Tiller | 82f9bd8 | 2015-09-23 09:31:51 -0700 | [diff] [blame] | 223 | TCP_REF(tcp, "read"); |
| 224 | |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 225 | /* First let's try a synchronous, non-blocking read. */ |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 226 | status = |
| 227 | WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, NULL, NULL); |
| 228 | info->wsa_error = status == 0 ? 0 : WSAGetLastError(); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 229 | |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 230 | /* Did we get data immediately ? Yay. */ |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 231 | if (info->wsa_error != WSAEWOULDBLOCK) { |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 232 | info->bytes_transfered = bytes_read; |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 233 | GRPC_CLOSURE_SCHED(exec_ctx, &tcp->on_read, GRPC_ERROR_NONE); |
Craig Tiller | 82f9bd8 | 2015-09-23 09:31:51 -0700 | [diff] [blame] | 234 | return; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 235 | } |
Nicolas "Pixel" Noble | 7f2e98c | 2015-05-08 01:41:21 +0200 | [diff] [blame] | 236 | |
Craig Tiller | 45724b3 | 2015-09-22 10:42:19 -0700 | [diff] [blame] | 237 | /* Otherwise, let's retry, by queuing a read. */ |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 238 | memset(&tcp->socket->read_info.overlapped, 0, sizeof(OVERLAPPED)); |
| 239 | status = WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, |
| 240 | &info->overlapped, NULL); |
Craig Tiller | 45724b3 | 2015-09-22 10:42:19 -0700 | [diff] [blame] | 241 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 242 | if (status != 0) { |
| 243 | int wsa_error = WSAGetLastError(); |
| 244 | if (wsa_error != WSA_IO_PENDING) { |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 245 | info->wsa_error = wsa_error; |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 246 | GRPC_CLOSURE_SCHED(exec_ctx, &tcp->on_read, |
Craig Tiller | d465456 | 2017-01-03 08:45:56 -0800 | [diff] [blame] | 247 | GRPC_WSA_ERROR(info->wsa_error, "WSARecv")); |
Craig Tiller | 82f9bd8 | 2015-09-23 09:31:51 -0700 | [diff] [blame] | 248 | return; |
Craig Tiller | 45724b3 | 2015-09-22 10:42:19 -0700 | [diff] [blame] | 249 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 250 | } |
Craig Tiller | 45724b3 | 2015-09-22 10:42:19 -0700 | [diff] [blame] | 251 | |
Craig Tiller | 82f9bd8 | 2015-09-23 09:31:51 -0700 | [diff] [blame] | 252 | grpc_socket_notify_on_read(exec_ctx, tcp->socket, &tcp->on_read); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 253 | } |
| 254 | |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 255 | /* Asynchronous callback from the IOCP, or the background thread. */ |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 256 | static void on_write(grpc_exec_ctx* exec_ctx, void* tcpp, grpc_error* error) { |
| 257 | grpc_tcp* tcp = (grpc_tcp*)tcpp; |
| 258 | grpc_winsocket* handle = tcp->socket; |
| 259 | grpc_winsocket_callback_info* info = &handle->write_info; |
| 260 | grpc_closure* cb; |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 261 | |
Craig Tiller | a41ac57 | 2016-05-17 16:08:17 -0700 | [diff] [blame] | 262 | GRPC_ERROR_REF(error); |
| 263 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 264 | gpr_mu_lock(&tcp->mu); |
Nicolas Noble | e144536 | 2015-05-11 17:40:26 -0700 | [diff] [blame] | 265 | cb = tcp->write_cb; |
| 266 | tcp->write_cb = NULL; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 267 | gpr_mu_unlock(&tcp->mu); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 268 | |
Craig Tiller | a41ac57 | 2016-05-17 16:08:17 -0700 | [diff] [blame] | 269 | if (error == GRPC_ERROR_NONE) { |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 270 | if (info->wsa_error != 0) { |
Craig Tiller | a41ac57 | 2016-05-17 16:08:17 -0700 | [diff] [blame] | 271 | error = GRPC_WSA_ERROR(info->wsa_error, "WSASend"); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 272 | } else { |
| 273 | GPR_ASSERT(info->bytes_transfered == tcp->write_slices->length); |
Nicolas Noble | e144536 | 2015-05-11 17:40:26 -0700 | [diff] [blame] | 274 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 275 | } |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 276 | |
Craig Tiller | c037fc1 | 2016-11-04 14:04:54 -0700 | [diff] [blame] | 277 | TCP_UNREF(exec_ctx, tcp, "write"); |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 278 | GRPC_CLOSURE_SCHED(exec_ctx, cb, error); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 279 | } |
| 280 | |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 281 | /* Initiates a write. */ |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 282 | static void win_write(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep, |
| 283 | grpc_slice_buffer* slices, grpc_closure* cb) { |
| 284 | grpc_tcp* tcp = (grpc_tcp*)ep; |
| 285 | grpc_winsocket* socket = tcp->socket; |
| 286 | grpc_winsocket_callback_info* info = &socket->write_info; |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 287 | unsigned i; |
| 288 | DWORD bytes_sent; |
| 289 | int status; |
| 290 | WSABUF local_buffers[16]; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 291 | WSABUF* allocated = NULL; |
| 292 | WSABUF* buffers = local_buffers; |
Jan Tattermusch | f67f071 | 2015-12-07 18:09:49 -0800 | [diff] [blame] | 293 | size_t len; |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 294 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 295 | if (tcp->shutting_down) { |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 296 | GRPC_CLOSURE_SCHED( |
ncteisen | 4b36a3d | 2017-03-13 19:08:06 -0700 | [diff] [blame] | 297 | exec_ctx, cb, |
| 298 | GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
| 299 | "TCP socket is shutting down", &tcp->shutdown_error, 1)); |
Craig Tiller | 82f9bd8 | 2015-09-23 09:31:51 -0700 | [diff] [blame] | 300 | return; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 301 | } |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 302 | |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 303 | tcp->write_cb = cb; |
Craig Tiller | b029859 | 2015-08-27 07:38:01 -0700 | [diff] [blame] | 304 | tcp->write_slices = slices; |
Jan Tattermusch | f67f071 | 2015-12-07 18:09:49 -0800 | [diff] [blame] | 305 | GPR_ASSERT(tcp->write_slices->count <= UINT_MAX); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 306 | if (tcp->write_slices->count > GPR_ARRAY_SIZE(local_buffers)) { |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 307 | buffers = (WSABUF*)gpr_malloc(sizeof(WSABUF) * tcp->write_slices->count); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 308 | allocated = buffers; |
| 309 | } |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 310 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 311 | for (i = 0; i < tcp->write_slices->count; i++) { |
Craig Tiller | 618e67d | 2016-10-26 21:08:10 -0700 | [diff] [blame] | 312 | len = GRPC_SLICE_LENGTH(tcp->write_slices->slices[i]); |
Jan Tattermusch | f67f071 | 2015-12-07 18:09:49 -0800 | [diff] [blame] | 313 | GPR_ASSERT(len <= ULONG_MAX); |
Craig Tiller | 620e965 | 2015-12-14 12:02:50 -0800 | [diff] [blame] | 314 | buffers[i].len = (ULONG)len; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 315 | buffers[i].buf = (char*)GRPC_SLICE_START_PTR(tcp->write_slices->slices[i]); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 316 | } |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 317 | |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 318 | /* First, let's try a synchronous, non-blocking write. */ |
Jan Tattermusch | 4b3ecdf | 2015-12-04 09:33:05 -0800 | [diff] [blame] | 319 | status = WSASend(socket->socket, buffers, (DWORD)tcp->write_slices->count, |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 320 | &bytes_sent, 0, NULL, NULL); |
| 321 | info->wsa_error = status == 0 ? 0 : WSAGetLastError(); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 322 | |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 323 | /* We would kind of expect to get a WSAEWOULDBLOCK here, especially on a busy |
| 324 | connection that has its send queue filled up. But if we don't, then we can |
| 325 | avoid doing an async write operation at all. */ |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 326 | if (info->wsa_error != WSAEWOULDBLOCK) { |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 327 | grpc_error* error = status == 0 |
Craig Tiller | 3e149f3 | 2016-05-17 16:11:04 -0700 | [diff] [blame] | 328 | ? GRPC_ERROR_NONE |
| 329 | : GRPC_WSA_ERROR(info->wsa_error, "WSASend"); |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 330 | GRPC_CLOSURE_SCHED(exec_ctx, cb, error); |
Nicolas "Pixel" Noble | fa242cb | 2016-09-29 00:54:02 +0200 | [diff] [blame] | 331 | if (allocated) gpr_free(allocated); |
Craig Tiller | 82f9bd8 | 2015-09-23 09:31:51 -0700 | [diff] [blame] | 332 | return; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 333 | } |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 334 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 335 | TCP_REF(tcp, "write"); |
Craig Tiller | 9f80fcf | 2015-08-28 08:22:48 -0700 | [diff] [blame] | 336 | |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 337 | /* If we got a WSAEWOULDBLOCK earlier, then we need to re-do the same |
| 338 | operation, this time asynchronously. */ |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 339 | memset(&socket->write_info.overlapped, 0, sizeof(OVERLAPPED)); |
Jan Tattermusch | 4b3ecdf | 2015-12-04 09:33:05 -0800 | [diff] [blame] | 340 | status = WSASend(socket->socket, buffers, (DWORD)tcp->write_slices->count, |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 341 | &bytes_sent, 0, &socket->write_info.overlapped, NULL); |
| 342 | if (allocated) gpr_free(allocated); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 343 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 344 | if (status != 0) { |
| 345 | int wsa_error = WSAGetLastError(); |
| 346 | if (wsa_error != WSA_IO_PENDING) { |
Craig Tiller | c037fc1 | 2016-11-04 14:04:54 -0700 | [diff] [blame] | 347 | TCP_UNREF(exec_ctx, tcp, "write"); |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 348 | GRPC_CLOSURE_SCHED(exec_ctx, cb, GRPC_WSA_ERROR(wsa_error, "WSASend")); |
Craig Tiller | 82f9bd8 | 2015-09-23 09:31:51 -0700 | [diff] [blame] | 349 | return; |
Nicolas "Pixel" Noble | 7f2e98c | 2015-05-08 01:41:21 +0200 | [diff] [blame] | 350 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 351 | } |
Nicolas "Pixel" Noble | 7f2e98c | 2015-05-08 01:41:21 +0200 | [diff] [blame] | 352 | |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 353 | /* As all is now setup, we can now ask for the IOCP notification. It may |
| 354 | trigger the callback immediately however, but no matter. */ |
Craig Tiller | 82f9bd8 | 2015-09-23 09:31:51 -0700 | [diff] [blame] | 355 | grpc_socket_notify_on_write(exec_ctx, socket, &tcp->on_write); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 356 | } |
| 357 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 358 | static void win_add_to_pollset(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep, |
| 359 | grpc_pollset* ps) { |
| 360 | grpc_tcp* tcp; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 361 | (void)ps; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 362 | tcp = (grpc_tcp*)ep; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 363 | grpc_iocp_add_socket(tcp->socket); |
Nicolas "Pixel" Noble | f29e9db | 2015-07-29 06:00:22 +0200 | [diff] [blame] | 364 | } |
| 365 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 366 | static void win_add_to_pollset_set(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep, |
| 367 | grpc_pollset_set* pss) { |
| 368 | grpc_tcp* tcp; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 369 | (void)pss; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 370 | tcp = (grpc_tcp*)ep; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 371 | grpc_iocp_add_socket(tcp->socket); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 372 | } |
| 373 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 374 | static void win_delete_from_pollset_set(grpc_exec_ctx* exec_ctx, |
| 375 | grpc_endpoint* ep, |
| 376 | grpc_pollset_set* pss) {} |
Yuchen Zeng | 01432b7 | 2017-10-02 16:14:06 -0700 | [diff] [blame] | 377 | |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 378 | /* Initiates a shutdown of the TCP endpoint. This will queue abort callbacks |
| 379 | for the potential read and write operations. It is up to the caller to |
| 380 | guarantee this isn't called in parallel to a read or write request, so |
| 381 | we're not going to protect against these. However the IO Completion Port |
| 382 | callback will happen from another thread, so we need to protect against |
| 383 | concurrent access of the data structure in that regard. */ |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 384 | static void win_shutdown(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep, |
| 385 | grpc_error* why) { |
| 386 | grpc_tcp* tcp = (grpc_tcp*)ep; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 387 | gpr_mu_lock(&tcp->mu); |
Nicolas "Pixel" Noble | 0f981e9 | 2015-05-03 10:40:56 +0200 | [diff] [blame] | 388 | /* At that point, what may happen is that we're already inside the IOCP |
| 389 | callback. See the comments in on_read and on_write. */ |
Craig Tiller | 6ba80f9 | 2017-01-27 11:58:32 -0800 | [diff] [blame] | 390 | if (!tcp->shutting_down) { |
Craig Tiller | 393a4d9 | 2017-01-27 12:01:44 -0800 | [diff] [blame] | 391 | tcp->shutting_down = 1; |
| 392 | tcp->shutdown_error = why; |
| 393 | } else { |
| 394 | GRPC_ERROR_UNREF(why); |
Craig Tiller | 6ba80f9 | 2017-01-27 11:58:32 -0800 | [diff] [blame] | 395 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 396 | grpc_winsocket_shutdown(tcp->socket); |
| 397 | gpr_mu_unlock(&tcp->mu); |
Craig Tiller | c037fc1 | 2016-11-04 14:04:54 -0700 | [diff] [blame] | 398 | grpc_resource_user_shutdown(exec_ctx, tcp->resource_user); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 399 | } |
| 400 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 401 | static void win_destroy(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep) { |
Makarand Dharmapurikar | 6149443 | 2016-06-22 13:34:59 -0700 | [diff] [blame] | 402 | grpc_network_status_unregister_endpoint(ep); |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 403 | grpc_tcp* tcp = (grpc_tcp*)ep; |
Craig Tiller | c037fc1 | 2016-11-04 14:04:54 -0700 | [diff] [blame] | 404 | TCP_UNREF(exec_ctx, tcp, "destroy"); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 405 | } |
| 406 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 407 | static char* win_get_peer(grpc_endpoint* ep) { |
| 408 | grpc_tcp* tcp = (grpc_tcp*)ep; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 409 | return gpr_strdup(tcp->peer_string); |
Craig Tiller | 81bcc4c | 2015-07-20 14:04:18 -0700 | [diff] [blame] | 410 | } |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 411 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 412 | static grpc_resource_user* win_get_resource_user(grpc_endpoint* ep) { |
| 413 | grpc_tcp* tcp = (grpc_tcp*)ep; |
Craig Tiller | c037fc1 | 2016-11-04 14:04:54 -0700 | [diff] [blame] | 414 | return tcp->resource_user; |
Craig Tiller | 290e9a7 | 2016-10-28 08:17:00 -0700 | [diff] [blame] | 415 | } |
| 416 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 417 | static int win_get_fd(grpc_endpoint* ep) { return -1; } |
murgatroid99 | 2e01234 | 2016-11-10 18:24:08 -0800 | [diff] [blame] | 418 | |
Yuchen Zeng | 01432b7 | 2017-10-02 16:14:06 -0700 | [diff] [blame] | 419 | static grpc_endpoint_vtable vtable = {win_read, |
| 420 | win_write, |
| 421 | win_add_to_pollset, |
| 422 | win_add_to_pollset_set, |
| 423 | win_delete_from_pollset_set, |
| 424 | win_shutdown, |
| 425 | win_destroy, |
| 426 | win_get_resource_user, |
| 427 | win_get_peer, |
| 428 | win_get_fd}; |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 429 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 430 | grpc_endpoint* grpc_tcp_create(grpc_exec_ctx* exec_ctx, grpc_winsocket* socket, |
| 431 | grpc_channel_args* channel_args, |
| 432 | const char* peer_string) { |
| 433 | grpc_resource_quota* resource_quota = grpc_resource_quota_create(NULL); |
Craig Tiller | 4254d3b | 2017-04-05 14:03:49 -0700 | [diff] [blame] | 434 | if (channel_args != NULL) { |
| 435 | for (size_t i = 0; i < channel_args->num_args; i++) { |
| 436 | if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) { |
| 437 | grpc_resource_quota_unref_internal(exec_ctx, resource_quota); |
| 438 | resource_quota = grpc_resource_quota_ref_internal( |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 439 | (grpc_resource_quota*)channel_args->args[i].value.pointer.p); |
Craig Tiller | 4254d3b | 2017-04-05 14:03:49 -0700 | [diff] [blame] | 440 | } |
| 441 | } |
| 442 | } |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame^] | 443 | grpc_tcp* tcp = (grpc_tcp*)gpr_malloc(sizeof(grpc_tcp)); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 444 | memset(tcp, 0, sizeof(grpc_tcp)); |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 445 | tcp->base.vtable = &vtable; |
| 446 | tcp->socket = socket; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 447 | gpr_mu_init(&tcp->mu); |
Jan Tattermusch | 6f8507f | 2016-11-22 15:13:34 +0100 | [diff] [blame] | 448 | gpr_ref_init(&tcp->refcount, 1); |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 449 | GRPC_CLOSURE_INIT(&tcp->on_read, on_read, tcp, grpc_schedule_on_exec_ctx); |
| 450 | GRPC_CLOSURE_INIT(&tcp->on_write, on_write, tcp, grpc_schedule_on_exec_ctx); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 451 | tcp->peer_string = gpr_strdup(peer_string); |
Craig Tiller | c037fc1 | 2016-11-04 14:04:54 -0700 | [diff] [blame] | 452 | tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string); |
Makarand Dharmapurikar | 0579cfc | 2016-06-20 15:45:24 -0700 | [diff] [blame] | 453 | /* Tell network status tracking code about the new endpoint */ |
| 454 | grpc_network_status_register_endpoint(&tcp->base); |
Jan Tattermusch | 1b1e8d6 | 2017-10-24 11:15:17 +0200 | [diff] [blame] | 455 | grpc_resource_quota_unref_internal(exec_ctx, resource_quota); |
Makarand Dharmapurikar | 0579cfc | 2016-06-20 15:45:24 -0700 | [diff] [blame] | 456 | |
Nicolas "Pixel" Noble | 21f627a | 2015-02-04 01:31:14 +0100 | [diff] [blame] | 457 | return &tcp->base; |
| 458 | } |
| 459 | |
murgatroid99 | 623dd4f | 2016-08-08 17:31:27 -0700 | [diff] [blame] | 460 | #endif /* GRPC_WINSOCK_SOCKET */ |