tcp_windows.cc
Go to the documentation of this file.
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 
20 
22 
23 #ifdef GRPC_WINSOCK_SOCKET
24 
25 #include <limits.h>
26 
27 #include <grpc/slice_buffer.h>
28 #include <grpc/support/alloc.h>
29 #include <grpc/support/log.h>
32 
45 
46 #if defined(__MSYS__) && defined(GPR_ARCH_64)
47 /* Nasty workaround for nasty bug when using the 64 bits msys compiler
48  in conjunction with Microsoft Windows headers. */
49 #define GRPC_FIONBIO _IOW('f', 126, uint32_t)
50 #else
51 #define GRPC_FIONBIO FIONBIO
52 #endif
53 
55 
56 grpc_error_handle grpc_tcp_set_non_block(SOCKET sock) {
57  int status;
58  uint32_t param = 1;
59  DWORD ret;
60  status = WSAIoctl(sock, GRPC_FIONBIO, &param, sizeof(param), NULL, 0, &ret,
61  NULL, NULL);
62  return status == 0
64  : GRPC_WSA_ERROR(WSAGetLastError(), "WSAIoctl(GRPC_FIONBIO)");
65 }
66 
67 static grpc_error_handle set_dualstack(SOCKET sock) {
68  int status;
69  unsigned long param = 0;
70  status = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&param,
71  sizeof(param));
72  return status == 0
74  : GRPC_WSA_ERROR(WSAGetLastError(), "setsockopt(IPV6_V6ONLY)");
75 }
76 
77 static grpc_error_handle enable_socket_low_latency(SOCKET sock) {
78  int status;
79  BOOL param = TRUE;
80  status = ::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
81  reinterpret_cast<char*>(&param), sizeof(param));
82  if (status == SOCKET_ERROR) {
83  status = WSAGetLastError();
84  }
85  return status == 0 ? GRPC_ERROR_NONE
86  : GRPC_WSA_ERROR(status, "setsockopt(TCP_NODELAY)");
87 }
88 
89 grpc_error_handle grpc_tcp_prepare_socket(SOCKET sock) {
91  err = grpc_tcp_set_non_block(sock);
92  if (!GRPC_ERROR_IS_NONE(err)) return err;
93  err = set_dualstack(sock);
94  if (!GRPC_ERROR_IS_NONE(err)) return err;
95  err = enable_socket_low_latency(sock);
96  if (!GRPC_ERROR_IS_NONE(err)) return err;
97  return GRPC_ERROR_NONE;
98 }
99 
100 typedef struct grpc_tcp {
101  /* This is our C++ class derivation emulation. */
103  /* The one socket this endpoint is using. */
104  grpc_winsocket* socket;
105  /* Refcounting how many operations are in progress. */
107 
110 
113 
114  /* garbage after the last read */
115  grpc_slice_buffer last_read_buffer;
116 
117  grpc_slice_buffer* write_slices;
118  grpc_slice_buffer* read_slices;
119 
120  /* The IO Completion Port runs from another thread. We need some mechanism
121  to protect ourselves when requesting a shutdown. */
122  gpr_mu mu;
123  int shutting_down;
124  grpc_error_handle shutdown_error;
125 
126  std::string peer_string;
127  std::string local_address;
128 } grpc_tcp;
129 
130 static void tcp_free(grpc_tcp* tcp) {
131  grpc_winsocket_destroy(tcp->socket);
132  gpr_mu_destroy(&tcp->mu);
133  grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer);
134  if (tcp->shutting_down) GRPC_ERROR_UNREF(tcp->shutdown_error);
135  delete tcp;
136 }
137 
138 #ifndef NDEBUG
139 #define TCP_UNREF(tcp, reason) tcp_unref((tcp), (reason), __FILE__, __LINE__)
140 #define TCP_REF(tcp, reason) tcp_ref((tcp), (reason), __FILE__, __LINE__)
141 static void tcp_unref(grpc_tcp* tcp, const char* reason, const char* file,
142  int line) {
143  if (grpc_tcp_trace.enabled()) {
144  gpr_atm val = gpr_atm_no_barrier_load(&tcp->refcount.count);
146  "TCP unref %p : %s %" PRIdPTR " -> %" PRIdPTR, tcp, reason, val,
147  val - 1);
148  }
149  if (gpr_unref(&tcp->refcount)) {
150  tcp_free(tcp);
151  }
152 }
153 
154 static void tcp_ref(grpc_tcp* tcp, const char* reason, const char* file,
155  int line) {
156  if (grpc_tcp_trace.enabled()) {
157  gpr_atm val = gpr_atm_no_barrier_load(&tcp->refcount.count);
159  "TCP ref %p : %s %" PRIdPTR " -> %" PRIdPTR, tcp, reason, val,
160  val + 1);
161  }
162  gpr_ref(&tcp->refcount);
163 }
164 #else
165 #define TCP_UNREF(tcp, reason) tcp_unref((tcp))
166 #define TCP_REF(tcp, reason) tcp_ref((tcp))
167 static void tcp_unref(grpc_tcp* tcp) {
168  if (gpr_unref(&tcp->refcount)) {
169  tcp_free(tcp);
170  }
171 }
172 
173 static void tcp_ref(grpc_tcp* tcp) { gpr_ref(&tcp->refcount); }
174 #endif
175 
176 /* Asynchronous callback from the IOCP, or the background thread. */
177 static void on_read(void* tcpp, grpc_error_handle error) {
178  grpc_tcp* tcp = (grpc_tcp*)tcpp;
179  grpc_closure* cb = tcp->read_cb;
180  grpc_winsocket* socket = tcp->socket;
181  grpc_winsocket_callback_info* info = &socket->read_info;
182 
183  if (grpc_tcp_trace.enabled()) {
184  gpr_log(GPR_INFO, "TCP:%p on_read", tcp);
185  }
186 
187  (void)GRPC_ERROR_REF(error);
188 
189  if (GRPC_ERROR_IS_NONE(error)) {
190  if (info->wsa_error != 0 && !tcp->shutting_down) {
191  char* utf8_message = gpr_format_message(info->wsa_error);
193  gpr_free(utf8_message);
195  } else {
196  if (info->bytes_transferred != 0 && !tcp->shutting_down) {
197  GPR_ASSERT((size_t)info->bytes_transferred <= tcp->read_slices->length);
198  if (static_cast<size_t>(info->bytes_transferred) !=
199  tcp->read_slices->length) {
201  tcp->read_slices,
202  tcp->read_slices->length -
203  static_cast<size_t>(info->bytes_transferred),
204  &tcp->last_read_buffer);
205  }
206  GPR_ASSERT((size_t)info->bytes_transferred == tcp->read_slices->length);
207 
208  if (grpc_tcp_trace.enabled()) {
209  size_t i;
210  for (i = 0; i < tcp->read_slices->count; i++) {
211  char* dump = grpc_dump_slice(tcp->read_slices->slices[i],
213  gpr_log(GPR_INFO, "READ %p (peer=%s): %s", tcp,
214  tcp->peer_string.c_str(), dump);
215  gpr_free(dump);
216  }
217  }
218  } else {
219  if (grpc_tcp_trace.enabled()) {
220  gpr_log(GPR_INFO, "TCP:%p unref read_slice", tcp);
221  }
224  tcp->shutting_down
226  "TCP stream shutting down", &tcp->shutdown_error, 1)
227  : GRPC_ERROR_CREATE_FROM_STATIC_STRING("End of TCP stream"),
229  }
230  }
231  }
232 
233  tcp->read_cb = NULL;
234  TCP_UNREF(tcp, "read");
236 }
237 
238 #define DEFAULT_TARGET_READ_SIZE 8192
239 #define MAX_WSABUF_COUNT 16
240 static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices,
241  grpc_closure* cb, bool urgent, int /*min_progress_size*/) {
242  grpc_tcp* tcp = (grpc_tcp*)ep;
243  grpc_winsocket* handle = tcp->socket;
244  grpc_winsocket_callback_info* info = &handle->read_info;
245  int status;
246  DWORD bytes_read = 0;
247  DWORD flags = 0;
248  WSABUF buffers[MAX_WSABUF_COUNT];
249  size_t i;
250 
251  if (grpc_tcp_trace.enabled()) {
252  gpr_log(GPR_INFO, "TCP:%p win_read", tcp);
253  }
254 
255  if (tcp->shutting_down) {
260  "TCP socket is shutting down", &tcp->shutdown_error, 1),
262  return;
263  }
264 
265  tcp->read_cb = cb;
266  tcp->read_slices = read_slices;
268  grpc_slice_buffer_swap(read_slices, &tcp->last_read_buffer);
269 
270  if (tcp->read_slices->length < DEFAULT_TARGET_READ_SIZE / 2 &&
271  tcp->read_slices->count < MAX_WSABUF_COUNT) {
272  // TODO(jtattermusch): slice should be allocated using resource quota
273  grpc_slice_buffer_add(tcp->read_slices,
274  GRPC_SLICE_MALLOC(DEFAULT_TARGET_READ_SIZE));
275  }
276 
277  GPR_ASSERT(tcp->read_slices->count <= MAX_WSABUF_COUNT);
278  for (i = 0; i < tcp->read_slices->count; i++) {
279  buffers[i].len = (ULONG)GRPC_SLICE_LENGTH(
280  tcp->read_slices->slices[i]); // we know slice size fits in 32bit.
281  buffers[i].buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slices->slices[i]);
282  }
283 
284  TCP_REF(tcp, "read");
285 
286  /* First let's try a synchronous, non-blocking read. */
287  status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count,
288  &bytes_read, &flags, NULL, NULL);
289  info->wsa_error = status == 0 ? 0 : WSAGetLastError();
290 
291  /* Did we get data immediately ? Yay. */
292  if (info->wsa_error != WSAEWOULDBLOCK) {
293  info->bytes_transferred = bytes_read;
295  return;
296  }
297 
298  /* Otherwise, let's retry, by queuing a read. */
299  memset(&tcp->socket->read_info.overlapped, 0, sizeof(OVERLAPPED));
300  status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count,
301  &bytes_read, &flags, &info->overlapped, NULL);
302 
303  if (status != 0) {
304  int wsa_error = WSAGetLastError();
305  if (wsa_error != WSA_IO_PENDING) {
306  info->wsa_error = wsa_error;
308  GRPC_WSA_ERROR(info->wsa_error, "WSARecv"));
309  return;
310  }
311  }
312 
313  grpc_socket_notify_on_read(tcp->socket, &tcp->on_read);
314 }
315 
316 /* Asynchronous callback from the IOCP, or the background thread. */
317 static void on_write(void* tcpp, grpc_error_handle error) {
318  grpc_tcp* tcp = (grpc_tcp*)tcpp;
319  grpc_winsocket* handle = tcp->socket;
320  grpc_winsocket_callback_info* info = &handle->write_info;
321  grpc_closure* cb;
322 
323  if (grpc_tcp_trace.enabled()) {
324  gpr_log(GPR_INFO, "TCP:%p on_write", tcp);
325  }
326 
327  (void)GRPC_ERROR_REF(error);
328 
329  gpr_mu_lock(&tcp->mu);
330  cb = tcp->write_cb;
331  tcp->write_cb = NULL;
332  gpr_mu_unlock(&tcp->mu);
333 
334  if (GRPC_ERROR_IS_NONE(error)) {
335  if (info->wsa_error != 0) {
336  error = GRPC_WSA_ERROR(info->wsa_error, "WSASend");
337  } else {
338  GPR_ASSERT(info->bytes_transferred == tcp->write_slices->length);
339  }
340  }
341 
342  TCP_UNREF(tcp, "write");
344 }
345 
346 /* Initiates a write. */
347 static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices,
348  grpc_closure* cb, void* arg, int /*max_frame_size*/) {
349  grpc_tcp* tcp = (grpc_tcp*)ep;
350  grpc_winsocket* socket = tcp->socket;
351  grpc_winsocket_callback_info* info = &socket->write_info;
352  unsigned i;
353  DWORD bytes_sent;
354  int status;
355  WSABUF local_buffers[MAX_WSABUF_COUNT];
356  WSABUF* allocated = NULL;
357  WSABUF* buffers = local_buffers;
358  size_t len;
359 
360  if (grpc_tcp_trace.enabled()) {
361  size_t i;
362  for (i = 0; i < slices->count; i++) {
363  char* data =
365  gpr_log(GPR_INFO, "WRITE %p (peer=%s): %s", tcp, tcp->peer_string.c_str(),
366  data);
367  gpr_free(data);
368  }
369  }
370 
371  if (tcp->shutting_down) {
376  "TCP socket is shutting down", &tcp->shutdown_error, 1),
378  return;
379  }
380 
381  tcp->write_cb = cb;
382  tcp->write_slices = slices;
383  GPR_ASSERT(tcp->write_slices->count <= UINT_MAX);
384  if (tcp->write_slices->count > GPR_ARRAY_SIZE(local_buffers)) {
385  buffers = (WSABUF*)gpr_malloc(sizeof(WSABUF) * tcp->write_slices->count);
386  allocated = buffers;
387  }
388 
389  for (i = 0; i < tcp->write_slices->count; i++) {
390  len = GRPC_SLICE_LENGTH(tcp->write_slices->slices[i]);
391  GPR_ASSERT(len <= ULONG_MAX);
392  buffers[i].len = (ULONG)len;
393  buffers[i].buf = (char*)GRPC_SLICE_START_PTR(tcp->write_slices->slices[i]);
394  }
395 
396  /* First, let's try a synchronous, non-blocking write. */
397  status = WSASend(socket->socket, buffers, (DWORD)tcp->write_slices->count,
398  &bytes_sent, 0, NULL, NULL);
399  info->wsa_error = status == 0 ? 0 : WSAGetLastError();
400 
401  /* We would kind of expect to get a WSAEWOULDBLOCK here, especially on a busy
402  connection that has its send queue filled up. But if we don't, then we can
403  avoid doing an async write operation at all. */
404  if (info->wsa_error != WSAEWOULDBLOCK) {
407  : GRPC_WSA_ERROR(info->wsa_error, "WSASend");
409  if (allocated) gpr_free(allocated);
410  return;
411  }
412 
413  TCP_REF(tcp, "write");
414 
415  /* If we got a WSAEWOULDBLOCK earlier, then we need to re-do the same
416  operation, this time asynchronously. */
417  memset(&socket->write_info.overlapped, 0, sizeof(OVERLAPPED));
418  status = WSASend(socket->socket, buffers, (DWORD)tcp->write_slices->count,
419  &bytes_sent, 0, &socket->write_info.overlapped, NULL);
420  if (allocated) gpr_free(allocated);
421 
422  if (status != 0) {
423  int wsa_error = WSAGetLastError();
424  if (wsa_error != WSA_IO_PENDING) {
425  TCP_UNREF(tcp, "write");
427  GRPC_WSA_ERROR(wsa_error, "WSASend"));
428  return;
429  }
430  }
431 
432  /* As all is now setup, we can now ask for the IOCP notification. It may
433  trigger the callback immediately however, but no matter. */
434  grpc_socket_notify_on_write(socket, &tcp->on_write);
435 }
436 
437 static void win_add_to_pollset(grpc_endpoint* ep, grpc_pollset* ps) {
438  grpc_tcp* tcp;
439  (void)ps;
440  tcp = (grpc_tcp*)ep;
441  grpc_iocp_add_socket(tcp->socket);
442 }
443 
444 static void win_add_to_pollset_set(grpc_endpoint* ep, grpc_pollset_set* pss) {
445  grpc_tcp* tcp;
446  (void)pss;
447  tcp = (grpc_tcp*)ep;
448  grpc_iocp_add_socket(tcp->socket);
449 }
450 
451 static void win_delete_from_pollset_set(grpc_endpoint* ep,
452  grpc_pollset_set* pss) {}
453 
454 /* Initiates a shutdown of the TCP endpoint. This will queue abort callbacks
455  for the potential read and write operations. It is up to the caller to
456  guarantee this isn't called in parallel to a read or write request, so
457  we're not going to protect against these. However the IO Completion Port
458  callback will happen from another thread, so we need to protect against
459  concurrent access of the data structure in that regard. */
460 static void win_shutdown(grpc_endpoint* ep, grpc_error_handle why) {
461  grpc_tcp* tcp = (grpc_tcp*)ep;
462  gpr_mu_lock(&tcp->mu);
463  /* At that point, what may happen is that we're already inside the IOCP
464  callback. See the comments in on_read and on_write. */
465  if (!tcp->shutting_down) {
466  tcp->shutting_down = 1;
467  tcp->shutdown_error = why;
468  } else {
469  GRPC_ERROR_UNREF(why);
470  }
471  grpc_winsocket_shutdown(tcp->socket);
472  gpr_mu_unlock(&tcp->mu);
473 }
474 
475 static void win_destroy(grpc_endpoint* ep) {
476  grpc_tcp* tcp = (grpc_tcp*)ep;
478  TCP_UNREF(tcp, "destroy");
479 }
480 
481 static absl::string_view win_get_peer(grpc_endpoint* ep) {
482  grpc_tcp* tcp = (grpc_tcp*)ep;
483  return tcp->peer_string;
484 }
485 
486 static absl::string_view win_get_local_address(grpc_endpoint* ep) {
487  grpc_tcp* tcp = (grpc_tcp*)ep;
488  return tcp->local_address;
489 }
490 
491 static int win_get_fd(grpc_endpoint* ep) { return -1; }
492 
493 static bool win_can_track_err(grpc_endpoint* ep) { return false; }
494 
495 static grpc_endpoint_vtable vtable = {win_read,
496  win_write,
497  win_add_to_pollset,
498  win_add_to_pollset_set,
499  win_delete_from_pollset_set,
500  win_shutdown,
501  win_destroy,
502  win_get_peer,
503  win_get_local_address,
504  win_get_fd,
505  win_can_track_err};
506 
507 grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket,
508  grpc_channel_args* channel_args,
509  absl::string_view peer_string) {
510  // TODO(jtattermusch): C++ize grpc_tcp and its dependencies (i.e. add
511  // constructors) to ensure proper initialization
512  grpc_tcp* tcp = new grpc_tcp{};
513  tcp->base.vtable = &vtable;
514  tcp->socket = socket;
515  gpr_mu_init(&tcp->mu);
516  gpr_ref_init(&tcp->refcount, 1);
517  GRPC_CLOSURE_INIT(&tcp->on_read, on_read, tcp, grpc_schedule_on_exec_ctx);
518  GRPC_CLOSURE_INIT(&tcp->on_write, on_write, tcp, grpc_schedule_on_exec_ctx);
519  grpc_resolved_address resolved_local_addr;
520  resolved_local_addr.len = sizeof(resolved_local_addr.addr);
522  if (getsockname(tcp->socket->socket,
523  reinterpret_cast<sockaddr*>(resolved_local_addr.addr),
524  &resolved_local_addr.len) < 0 ||
525  !(addr_uri = grpc_sockaddr_to_uri(&resolved_local_addr)).ok()) {
526  tcp->local_address = "";
527  } else {
528  tcp->local_address = grpc_sockaddr_to_uri(&resolved_local_addr).value();
529  }
530  tcp->peer_string = std::string(peer_string);
531  grpc_slice_buffer_init(&tcp->last_read_buffer);
532  return &tcp->base;
533 }
534 
535 #endif /* GRPC_WINSOCK_SOCKET */
GRPC_CLOSURE_INIT
#define GRPC_CLOSURE_INIT(closure, cb, cb_arg, scheduler)
Definition: closure.h:115
TRUE
const BOOL TRUE
Definition: undname.c:48
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
grpc_endpoint_vtable
Definition: endpoint.h:39
gpr_mu_unlock
GPRAPI void gpr_mu_unlock(gpr_mu *mu)
vtable
static const grpc_transport_vtable vtable
Definition: binder_transport.cc:680
gpr_atm_no_barrier_load
#define gpr_atm_no_barrier_load(p)
Definition: impl/codegen/atm_gcc_atomic.h:53
GRPC_ERROR_NONE
#define GRPC_ERROR_NONE
Definition: error.h:234
log.h
GRPC_ERROR_CREATE_FROM_COPIED_STRING
#define GRPC_ERROR_CREATE_FROM_COPIED_STRING(desc)
Definition: error.h:294
sockaddr_utils.h
GRPC_STATUS_UNAVAILABLE
@ GRPC_STATUS_UNAVAILABLE
Definition: include/grpc/impl/codegen/status.h:143
read_cb
static void read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
Definition: benchmark-pound.c:138
memset
return memset(p, 0, total)
grpc_dump_slice
char * grpc_dump_slice(const grpc_slice &s, uint32_t flags)
Definition: slice_string_helpers.cc:25
grpc_pollset_set
struct grpc_pollset_set grpc_pollset_set
Definition: iomgr_fwd.h:23
string.h
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
useful.h
GRPC_SLICE_MALLOC
#define GRPC_SLICE_MALLOC(len)
Definition: include/grpc/slice.h:70
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
error
grpc_error_handle error
Definition: retry_filter.cc:499
error_ref_leak.err
err
Definition: error_ref_leak.py:35
gpr_format_message
GPRAPI char * gpr_format_message(int messageid)
grpc_resolved_address
Definition: resolved_address.h:34
tcp
static uv_tcp_t tcp
Definition: test-connection-fail.c:29
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
gpr_malloc
GPRAPI void * gpr_malloc(size_t size)
Definition: alloc.cc:29
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING
#define GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(desc, errs, count)
Definition: error.h:307
status
absl::Status status
Definition: rls.cc:251
socket_windows.h
GPR_DUMP_HEX
#define GPR_DUMP_HEX
Definition: string.h:34
GPR_LOG_SEVERITY_DEBUG
@ GPR_LOG_SEVERITY_DEBUG
Definition: include/grpc/impl/codegen/log.h:46
sockaddr.h
iocp_windows.h
grpc_channel_args
Definition: grpc_types.h:132
GPR_DUMP_ASCII
#define GPR_DUMP_ASCII
Definition: string.h:35
gpr_refcount
Definition: impl/codegen/sync_generic.h:39
BOOL
int BOOL
Definition: undname.c:46
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
gpr_mu_destroy
GPRAPI void gpr_mu_destroy(gpr_mu *mu)
grpc_tcp_trace
grpc_core::TraceFlag grpc_tcp_trace(false, "tcp")
DEBUG_LOCATION
#define DEBUG_LOCATION
Definition: debug_location.h:41
GRPC_WSA_ERROR
#define GRPC_WSA_ERROR(err, call_name)
windows only: create an error associated with WSAGetLastError()!=0
Definition: error.h:357
string_util.h
refcount
size_t refcount
Definition: abseil-cpp/absl/strings/internal/cordz_info.cc:122
on_read
static grpc_closure on_read
Definition: bad_server_response_test.cc:88
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
mu
Mutex mu
Definition: server_config_selector_filter.cc:74
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
gpr_mu_init
GPRAPI void gpr_mu_init(gpr_mu *mu)
bytes_read
static size_t bytes_read
Definition: test-ipc-heavy-traffic-deadlock-bug.c:47
grpc_tcp_create
grpc_endpoint * grpc_tcp_create(grpc_fd *fd, const grpc_channel_args *args, absl::string_view peer_string)
GRPC_SLICE_START_PTR
#define GRPC_SLICE_START_PTR(slice)
Definition: include/grpc/impl/codegen/slice.h:101
slice_buffer.h
arg
Definition: cmdline.cc:40
gpr_mu_lock
GPRAPI void gpr_mu_lock(gpr_mu *mu)
grpc_resolved_address::len
socklen_t len
Definition: resolved_address.h:36
grpc_slice_buffer_swap
GPRAPI void grpc_slice_buffer_swap(grpc_slice_buffer *a, grpc_slice_buffer *b)
Definition: slice/slice_buffer.cc:249
gen_synthetic_protos.base
base
Definition: gen_synthetic_protos.py:31
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
on_write
void on_write(uv_fs_t *req)
Definition: libuv/docs/code/uvcat/main.c:17
slice_internal.h
tcp_client.h
grpc_slice_buffer_init
GPRAPI void grpc_slice_buffer_init(grpc_slice_buffer *sb)
Definition: slice/slice_buffer.cc:116
GRPC_ERROR_CREATE_FROM_STATIC_STRING
#define GRPC_ERROR_CREATE_FROM_STATIC_STRING(desc)
Definition: error.h:291
GRPC_SLICE_LENGTH
#define GRPC_SLICE_LENGTH(slice)
Definition: include/grpc/impl/codegen/slice.h:104
grpc_core::TraceFlag
Definition: debug/trace.h:63
grpc_core::TraceFlag::enabled
bool enabled()
Definition: debug/trace.h:82
tcp_windows.h
IPV6_V6ONLY
#define IPV6_V6ONLY
Definition: winsock.h:46
gpr_atm
intptr_t gpr_atm
Definition: impl/codegen/atm_gcc_atomic.h:32
GPR_ARRAY_SIZE
#define GPR_ARRAY_SIZE(array)
Definition: useful.h:129
grpc_slice_buffer_add
GPRAPI void grpc_slice_buffer_add(grpc_slice_buffer *sb, grpc_slice slice)
Definition: slice/slice_buffer.cc:170
GRPC_ERROR_REF
#define GRPC_ERROR_REF(err)
Definition: error.h:261
grpc_error_set_int
grpc_error_handle grpc_error_set_int(grpc_error_handle src, grpc_error_ints which, intptr_t value)
Definition: error.cc:613
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
gpr_mu
pthread_mutex_t gpr_mu
Definition: impl/codegen/sync_posix.h:47
port.h
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
alloc.h
slices
SliceBuffer * slices
Definition: retry_filter.cc:631
regen-readme.line
line
Definition: regen-readme.py:30
log_windows.h
ok
bool ok
Definition: async_end2end_test.cc:197
sockaddr_windows.h
GRPC_ERROR_UNREF
#define GRPC_ERROR_UNREF(err)
Definition: error.h:262
grpc_core::ExecCtx::Run
static void Run(const DebugLocation &location, grpc_closure *closure, grpc_error_handle error)
Definition: exec_ctx.cc:98
timer.h
grpc_slice_buffer_destroy_internal
void grpc_slice_buffer_destroy_internal(grpc_slice_buffer *sb)
Definition: slice/slice_buffer.cc:123
grpc_slice_buffer_trim_end
GPRAPI void grpc_slice_buffer_trim_end(grpc_slice_buffer *sb, size_t n, grpc_slice_buffer *garbage)
Definition: slice/slice_buffer.cc:402
handle
static csh handle
Definition: test_arm_regression.c:16
test_server.socket
socket
Definition: test_server.py:65
grpc_slice_buffer
Definition: include/grpc/impl/codegen/slice.h:83
absl::StatusOr::value
const T & value() const &ABSL_ATTRIBUTE_LIFETIME_BOUND
Definition: abseil-cpp/absl/status/statusor.h:687
gpr_ref_init
GPRAPI void gpr_ref_init(gpr_refcount *r, int n)
Definition: sync.cc:86
absl::StatusOr< std::string >
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
gpr_unref
GPRAPI int gpr_unref(gpr_refcount *r)
Definition: sync.cc:103
grpc_error
Definition: error_internal.h:42
write_cb
static void write_cb(uv_write_t *req, int status)
Definition: benchmark-pump.c:190
grpc_pollset
Definition: bm_cq_multiple_threads.cc:37
grpc_closure
Definition: closure.h:56
grpc_sockaddr_to_uri
absl::StatusOr< std::string > grpc_sockaddr_to_uri(const grpc_resolved_address *resolved_addr)
Definition: sockaddr_utils.cc:260
grpc_resolved_address::addr
char addr[GRPC_MAX_SOCKADDR_SIZE]
Definition: resolved_address.h:35
bytes_sent
static size_t bytes_sent
Definition: test-tcp-writealot.c:44
grpc_endpoint
Definition: endpoint.h:105
gpr_ref
GPRAPI void gpr_ref(gpr_refcount *r)
Definition: sync.cc:88
grpc_slice_buffer_reset_and_unref_internal
void grpc_slice_buffer_reset_and_unref_internal(grpc_slice_buffer *sb)
Definition: slice/slice_buffer.cc:238
cb
OPENSSL_EXPORT pem_password_cb * cb
Definition: pem.h:351
slice_string_helpers.h
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
GRPC_ERROR_INT_GRPC_STATUS
@ GRPC_ERROR_INT_GRPC_STATUS
grpc status code representing this error
Definition: error.h:66
GRPC_ERROR_IS_NONE
#define GRPC_ERROR_IS_NONE(err)
Definition: error.h:241
port_platform.h


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:29