Merge branch 'master' of github.com:grpc/grpc into matrix

pull/11608/head
Yong Ni 8 years ago
commit ef698b60cd
  1. 2
      .github/ISSUE_TEMPLATE.md
  2. 71
      .pylintrc
  3. 12
      BUILD
  4. 449
      CMakeLists.txt
  5. 3
      CODE-OF-CONDUCT.md
  6. 23
      INSTALL.md
  7. 20
      LICENSE
  8. 855
      Makefile
  9. 22
      PATENTS
  10. 62
      binding.gyp
  11. 24
      build.yaml
  12. 28
      config.m4
  13. 156
      config.w32
  14. 16
      doc/PROTOCOL-HTTP2.md
  15. 6
      doc/core/grpc-error.md
  16. 23
      doc/environment_variables.md
  17. 14
      examples/cpp/helloworld/Makefile
  18. 14
      examples/cpp/route_guide/Makefile
  19. 12
      gRPC-Core.podspec
  20. 37
      grpc.gemspec
  21. 21
      include/grpc++/alarm.h
  22. 90
      include/grpc++/impl/codegen/async_unary_call.h
  23. 22
      include/grpc++/impl/codegen/call.h
  24. 2
      package.json
  25. 37
      package.xml
  26. 6
      setup.py
  27. 536
      src/boringssl/err_data.c
  28. 4
      src/compiler/objective_c_generator_helpers.h
  29. 3
      src/compiler/objective_c_plugin.cc
  30. 40
      src/compiler/php_generator.cc
  31. 14
      src/compiler/php_generator_helpers.h
  32. 1
      src/compiler/python_generator.cc
  33. 2
      src/core/ext/census/grpc_filter.c
  34. 6
      src/core/ext/filters/client_channel/channel_connectivity.c
  35. 868
      src/core/ext/filters/client_channel/client_channel.c
  36. 9
      src/core/ext/filters/client_channel/client_channel_factory.c
  37. 9
      src/core/ext/filters/client_channel/client_channel_plugin.c
  38. 10
      src/core/ext/filters/client_channel/http_connect_handshaker.c
  39. 7
      src/core/ext/filters/client_channel/http_proxy.c
  40. 26
      src/core/ext/filters/client_channel/lb_policy.c
  41. 7
      src/core/ext/filters/client_channel/lb_policy.h
  42. 8
      src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c
  43. 65
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
  44. 61
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c
  45. 54
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
  46. 8
      src/core/ext/filters/client_channel/lb_policy_factory.c
  47. 35
      src/core/ext/filters/client_channel/resolver.c
  48. 14
      src/core/ext/filters/client_channel/resolver.h
  49. 49
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
  50. 6
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
  51. 29
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
  52. 331
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
  53. 23
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
  54. 59
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c
  55. 12
      src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c
  56. 30
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c
  57. 6
      src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c
  58. 45
      src/core/ext/filters/client_channel/subchannel.c
  59. 2
      src/core/ext/filters/client_channel/subchannel.h
  60. 14
      src/core/ext/filters/deadline/deadline_filter.c
  61. 14
      src/core/ext/filters/http/client/http_client_filter.c
  62. 39
      src/core/ext/filters/http/message_compress/message_compress_filter.c
  63. 14
      src/core/ext/filters/http/server/http_server_filter.c
  64. 6
      src/core/ext/filters/load_reporting/load_reporting.c
  65. 2
      src/core/ext/filters/load_reporting/load_reporting_filter.c
  66. 18
      src/core/ext/filters/max_age/max_age_filter.c
  67. 4
      src/core/ext/filters/message_size/message_size_filter.c
  68. 4
      src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c
  69. 6
      src/core/ext/transport/chttp2/client/chttp2_connector.c
  70. 8
      src/core/ext/transport/chttp2/client/insecure/channel_create.c
  71. 6
      src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
  72. 8
      src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
  73. 2
      src/core/ext/transport/chttp2/server/chttp2_server.c
  74. 3
      src/core/ext/transport/chttp2/transport/chttp2_plugin.c
  75. 288
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  76. 4
      src/core/ext/transport/chttp2/transport/chttp2_transport.h
  77. 11
      src/core/ext/transport/chttp2/transport/frame_data.c
  78. 2
      src/core/ext/transport/chttp2/transport/frame_ping.c
  79. 2
      src/core/ext/transport/chttp2/transport/frame_rst_stream.c
  80. 3
      src/core/ext/transport/chttp2/transport/frame_window_update.c
  81. 14
      src/core/ext/transport/chttp2/transport/hpack_encoder.c
  82. 2
      src/core/ext/transport/chttp2/transport/hpack_encoder.h
  83. 10
      src/core/ext/transport/chttp2/transport/hpack_parser.c
  84. 11
      src/core/ext/transport/chttp2/transport/internal.h
  85. 14
      src/core/ext/transport/chttp2/transport/parsing.c
  86. 92
      src/core/ext/transport/chttp2/transport/writing.c
  87. 86
      src/core/ext/transport/cronet/transport/cronet_transport.c
  88. 26
      src/core/lib/channel/channel_args.c
  89. 6
      src/core/lib/channel/channel_args.h
  90. 4
      src/core/lib/channel/channel_stack.h
  91. 8
      src/core/lib/channel/handshaker.c
  92. 19
      src/core/lib/http/httpcli.c
  93. 12
      src/core/lib/http/httpcli_security_connector.c
  94. 52
      src/core/lib/iomgr/closure.c
  95. 72
      src/core/lib/iomgr/closure.h
  96. 261
      src/core/lib/iomgr/combiner.c
  97. 11
      src/core/lib/iomgr/combiner.h
  98. 4
      src/core/lib/iomgr/endpoint.c
  99. 4
      src/core/lib/iomgr/endpoint.h
  100. 55
      src/core/lib/iomgr/error.c
  101. Some files were not shown because too many files have changed in this diff Show More

@ -6,7 +6,7 @@ Create new issues for bugs and feature requests. An issue needs to be actionable
- [grpc.io mailing list](https://groups.google.com/forum/#!forum/grpc-io)
- [StackOverflow, with `grpc` tag](http://stackoverflow.com/questions/tagged/grpc)
*Please don't double post your questions in more locations, we are monitoring both channels and the time spent de-duplicating questions can is better spent answering more user questions.*
*Please don't double post your questions in more locations; we are monitoring both channels, and the time spent de-duplicating questions is better spent answering more user questions.*
### What version of gRPC and what language are you using?

@ -1,15 +1,18 @@
[VARIABLES]
# TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection
# not include "unused_" and "ignored_" by default?
dummy-variables-rgx=^ignored_|^unused_
[DESIGN]
# NOTE(nathaniel): Not particularly attached to this value; it just seems to
# be what works for us at the moment (excepting the dead-code-walking Beta
# API).
max-args=6
[MISCELLANEOUS]
# NOTE(nathaniel): We are big fans of "TODO(<issue link>): " and
# "NOTE(<username or issue link>): ". We do not allow "TODO:",
# "TODO(<username>):", "FIXME:", or anything else.
@ -17,24 +20,50 @@ notes=FIXME,XXX
[MESSAGES CONTROL]
#TODO: Enable missing-docstring
#TODO: Enable too-few-public-methods
#TODO: Enable no-init
#TODO: Enable duplicate-code
#TODO: Enable invalid-name
#TODO: Enable locally-disabled
#TODO: Enable protected-access
#TODO: Enable no-name-in-module
#TODO: Enable wrong-import-order
# TODO(https://github.com/PyCQA/pylint/issues/59#issuecomment-283774279):
# enable cyclic-import after a 1.7-or-later pylint release that recognizes our
# disable=cyclic-import suppressions.
#TODO: Enable too-many-instance-attributes
#TODO: Enable too-many-lines
#TODO: Enable redefined-variable-type
#TODO: Enable next-method-called
#TODO: Enable import-error
#TODO: Enable useless-else-on-loop
#TODO: Enable too-many-nested-blocks
disable=missing-docstring,too-few-public-methods,no-init,duplicate-code,invalid-name,locally-disabled,protected-access,no-name-in-module,wrong-import-order,cyclic-import,too-many-instance-attributes,too-many-lines,redefined-variable-type,next-method-called,import-error,useless-else-on-loop,too-many-nested-blocks
disable=
# TODO(https://github.com/PyCQA/pylint/issues/59#issuecomment-283774279):
# Enable cyclic-import after a 1.7-or-later pylint release that
# recognizes our disable=cyclic-import suppressions.
cyclic-import,
# TODO(https://github.com/grpc/grpc/issues/8622): Enable this after the
# Beta API is removed.
duplicate-code,
# TODO(https://github.com/grpc/grpc/issues/261): Doesn't seem to
# understand enum and concurrent.futures; look into this later with the
# latest pylint version.
import-error,
# TODO(https://github.com/grpc/grpc/issues/261): Enable this one.
# Should take a little configuration but not much.
invalid-name,
# TODO(https://github.com/grpc/grpc/issues/261): This doesn't seem to
# work for now? Try with a later pylint?
locally-disabled,
# NOTE(nathaniel): We don't write doc strings for most private code
# elements.
missing-docstring,
# NOTE(nathaniel): Our completely abstract interface classes don't have
# constructors.
no-init,
# TODO(https://github.com/grpc/grpc/issues/261): Doesn't yet play
# nicely with some of our code being implemented in Cython. Maybe in a
# later version?
no-name-in-module,
# TODO(https://github.com/grpc/grpc/issues/261): Suppress these where
# the odd shape of the authentication portion of the API forces them on
# us and enable everywhere else.
protected-access,
# NOTE(nathaniel): Pylint and I will probably never agree on this.
too-few-public-methods,
# NOTE(nathaniel): Pylint and I wil probably never agree on this for
# private classes. For public classes maybe?
too-many-instance-attributes,
# NOTE(nathaniel): Some of our modules have a lot of lines... of
# specification and documentation. Maybe if this were
# lines-of-code-based we would use it.
too-many-lines,
# TODO(https://github.com/grpc/grpc/issues/261): Maybe we could have
# this one if we extracted just a few more helper functions...
too-many-nested-blocks,
# NOTE(nathaniel): I have disputed the premise of this inspection from
# the beginning and will continue to do so until it goes away for good.
useless-else-on-loop,

12
BUILD

@ -335,7 +335,6 @@ grpc_cc_library(
"src/core/lib/support/log_windows.c",
"src/core/lib/support/mpscq.c",
"src/core/lib/support/murmur_hash.c",
"src/core/lib/support/stack_lockfree.c",
"src/core/lib/support/string.c",
"src/core/lib/support/string_posix.c",
"src/core/lib/support/string_util_windows.c",
@ -371,7 +370,6 @@ grpc_cc_library(
"src/core/lib/support/mpscq.h",
"src/core/lib/support/murmur_hash.h",
"src/core/lib/support/spinlock.h",
"src/core/lib/support/stack_lockfree.h",
"src/core/lib/support/string.h",
"src/core/lib/support/string_windows.h",
"src/core/lib/support/thd_internal.h",
@ -521,8 +519,6 @@ grpc_cc_library(
"src/core/lib/iomgr/wakeup_fd_nospecial.c",
"src/core/lib/iomgr/wakeup_fd_pipe.c",
"src/core/lib/iomgr/wakeup_fd_posix.c",
"src/core/lib/iomgr/workqueue_uv.c",
"src/core/lib/iomgr/workqueue_windows.c",
"src/core/lib/json/json.c",
"src/core/lib/json/json_reader.c",
"src/core/lib/json/json_string.c",
@ -640,9 +636,6 @@ grpc_cc_library(
"src/core/lib/iomgr/wakeup_fd_cv.h",
"src/core/lib/iomgr/wakeup_fd_pipe.h",
"src/core/lib/iomgr/wakeup_fd_posix.h",
"src/core/lib/iomgr/workqueue.h",
"src/core/lib/iomgr/workqueue_uv.h",
"src/core/lib/iomgr/workqueue_windows.h",
"src/core/lib/json/json.h",
"src/core/lib/json/json_common.h",
"src/core/lib/json/json_reader.h",
@ -935,8 +928,8 @@ grpc_cc_library(
deps = [
"grpc_base",
"grpc_client_channel",
"grpc_secure",
"grpc_resolver_fake",
"grpc_secure",
],
)
@ -998,6 +991,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c",
],
hdrs = [
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h",
@ -1029,8 +1023,8 @@ grpc_cc_library(
name = "grpc_resolver_fake",
srcs = ["src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c"],
hdrs = ["src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"],
visibility = ["//test:__subpackages__"],
language = "c",
visibility = ["//test:__subpackages__"],
deps = [
"grpc_base",
"grpc_client_channel",

File diff suppressed because it is too large Load Diff

@ -0,0 +1,3 @@
## Community Code of Conduct
gRPC follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).

@ -89,17 +89,19 @@ gRPC C Core library.
There are several ways to build under Windows, of varying complexity depending
on experience with the tools involved.
### Pre-generated Visual Studio solution
The pre-generated VS projects & solution are checked into the repository under the [vsprojects](/vsprojects) directory.
### Building using CMake (with BoringSSL)
### Building using CMake (RECOMMENDED)
Builds gRPC C and C++ with boringssl.
- Install [CMake](https://cmake.org/download/).
- Install [Active State Perl](http://www.activestate.com/activeperl/) (`choco install activeperl`)
- Install [Ninja](https://ninja-build.org/) (`choco install ninja`)
- Install [Go](https://golang.org/dl/) (`choco install golang`)
- Install [yasm](http://yasm.tortall.net/) and add it to `PATH` (`choco install yasm`)
- Run these commands in the repo root directory
Using Ninja (faster build, supports boringssl's assembly optimizations)
```
> md .build
> cd .build
@ -107,7 +109,14 @@ The pre-generated VS projects & solution are checked into the repository under t
> cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release
> cmake --build .
```
NOTE: Currently you can only use Ninja to build using cmake on Windows (because of the boringssl dependency).
Using Visual Studio 2015 (can only build with OPENSSL_NO_ASM)
```
> md .build
> cd .build
> cmake .. -G "Visual Studio 14 2015" -DCMAKE_BUILD_TYPE=Release
> cmake --build .
```
### msys2 (with mingw)
@ -131,3 +140,9 @@ MINGW64$ make
NOTE: While most of the make targets are buildable under Mingw, some haven't been ported to Windows yet
and may fail to build (mostly trying to include POSIX headers not available on Mingw).
### Pre-generated Visual Studio solution (DEPRECATED)
*WARNING: This used to be the recommended way to build on Windows, but because of significant limitations (hard to build dependencies including boringssl, .proto codegen is hard to support, ..), it is no longer recommended. Use cmake to build on Windows instead.*
The pre-generated VS projects & solution are checked into the repository under the [vsprojects](/vsprojects) directory.

@ -1,13 +1,14 @@
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
@ -86,6 +87,7 @@
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
@ -103,6 +105,7 @@
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
@ -120,7 +123,9 @@
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
@ -171,7 +176,18 @@
END OF TERMS AND CONDITIONS
Copyright 2015-2017 gRPC authors.
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

File diff suppressed because it is too large Load Diff

@ -1,22 +0,0 @@
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the GRPC project.
Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of GRPC, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of GRPC. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of GRPC or any code incorporated within this
implementation of GRPC constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of GRPC
shall terminate as of the date such litigation is filed.

@ -115,6 +115,15 @@
]
}, {
'conditions': [
["target_arch=='ia32'", {
"include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
}],
["target_arch=='x64'", {
"include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
}],
["target_arch=='arm'", {
"include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
}],
['grpc_alpn=="true"', {
'defines': [
'TSI_OPENSSL_ALPN_SUPPORT=1'
@ -127,17 +136,6 @@
],
'include_dirs': [
'<(node_root_dir)/deps/openssl/openssl/include',
],
'conditions': [
["target_arch=='ia32'", {
"include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ]
}],
["target_arch=='x64'", {
"include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ]
}],
["target_arch=='arm'", {
"include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ]
}]
]
}],
['OS == "win"', {
@ -174,6 +172,7 @@
'targets': [
{
'cflags': [
'-std=c++11',
'-std=c99',
'-Wall',
'-Werror'
@ -186,6 +185,7 @@
'sources': [
'src/boringssl/err_data.c',
'third_party/boringssl/crypto/aes/aes.c',
'third_party/boringssl/crypto/aes/key_wrap.c',
'third_party/boringssl/crypto/aes/mode_wrappers.c',
'third_party/boringssl/crypto/asn1/a_bitstr.c',
'third_party/boringssl/crypto/asn1/a_bool.c',
@ -217,12 +217,12 @@
'third_party/boringssl/crypto/asn1/tasn_new.c',
'third_party/boringssl/crypto/asn1/tasn_typ.c',
'third_party/boringssl/crypto/asn1/tasn_utl.c',
'third_party/boringssl/crypto/asn1/time_support.c',
'third_party/boringssl/crypto/asn1/x_bignum.c',
'third_party/boringssl/crypto/asn1/x_long.c',
'third_party/boringssl/crypto/base64/base64.c',
'third_party/boringssl/crypto/bio/bio.c',
'third_party/boringssl/crypto/bio/bio_mem.c',
'third_party/boringssl/crypto/bio/buffer.c',
'third_party/boringssl/crypto/bio/connect.c',
'third_party/boringssl/crypto/bio/fd.c',
'third_party/boringssl/crypto/bio/file.c',
@ -329,12 +329,7 @@
'third_party/boringssl/crypto/modes/ctr.c',
'third_party/boringssl/crypto/modes/gcm.c',
'third_party/boringssl/crypto/modes/ofb.c',
'third_party/boringssl/crypto/newhope/error_correction.c',
'third_party/boringssl/crypto/newhope/newhope.c',
'third_party/boringssl/crypto/newhope/ntt.c',
'third_party/boringssl/crypto/newhope/poly.c',
'third_party/boringssl/crypto/newhope/precomp.c',
'third_party/boringssl/crypto/newhope/reduce.c',
'third_party/boringssl/crypto/modes/polyval.c',
'third_party/boringssl/crypto/obj/obj.c',
'third_party/boringssl/crypto/obj/obj_xref.c',
'third_party/boringssl/crypto/pem/pem_all.c',
@ -345,14 +340,15 @@
'third_party/boringssl/crypto/pem/pem_pkey.c',
'third_party/boringssl/crypto/pem/pem_x509.c',
'third_party/boringssl/crypto/pem/pem_xaux.c',
'third_party/boringssl/crypto/pkcs8/p5_pbe.c',
'third_party/boringssl/crypto/pkcs8/p5_pbev2.c',
'third_party/boringssl/crypto/pkcs8/p8_pkey.c',
'third_party/boringssl/crypto/pkcs8/pkcs8.c',
'third_party/boringssl/crypto/poly1305/poly1305.c',
'third_party/boringssl/crypto/poly1305/poly1305_arm.c',
'third_party/boringssl/crypto/poly1305/poly1305_vec.c',
'third_party/boringssl/crypto/pool/pool.c',
'third_party/boringssl/crypto/rand/deterministic.c',
'third_party/boringssl/crypto/rand/fuchsia.c',
'third_party/boringssl/crypto/rand/rand.c',
'third_party/boringssl/crypto/rand/urandom.c',
'third_party/boringssl/crypto/rand/windows.c',
@ -364,6 +360,7 @@
'third_party/boringssl/crypto/rsa/rsa.c',
'third_party/boringssl/crypto/rsa/rsa_asn1.c',
'third_party/boringssl/crypto/rsa/rsa_impl.c',
'third_party/boringssl/crypto/sha/sha1-altivec.c',
'third_party/boringssl/crypto/sha/sha1.c',
'third_party/boringssl/crypto/sha/sha256.c',
'third_party/boringssl/crypto/sha/sha512.c',
@ -372,7 +369,6 @@
'third_party/boringssl/crypto/thread_none.c',
'third_party/boringssl/crypto/thread_pthread.c',
'third_party/boringssl/crypto/thread_win.c',
'third_party/boringssl/crypto/time_support.c',
'third_party/boringssl/crypto/x509/a_digest.c',
'third_party/boringssl/crypto/x509/a_sign.c',
'third_party/boringssl/crypto/x509/a_strex.c',
@ -456,6 +452,7 @@
'third_party/boringssl/crypto/x509v3/v3_skey.c',
'third_party/boringssl/crypto/x509v3/v3_sxnet.c',
'third_party/boringssl/crypto/x509v3/v3_utl.c',
'third_party/boringssl/ssl/bio_ssl.c',
'third_party/boringssl/ssl/custom_extensions.c',
'third_party/boringssl/ssl/d1_both.c',
'third_party/boringssl/ssl/d1_lib.c',
@ -466,7 +463,6 @@
'third_party/boringssl/ssl/handshake_client.c',
'third_party/boringssl/ssl/handshake_server.c',
'third_party/boringssl/ssl/s3_both.c',
'third_party/boringssl/ssl/s3_enc.c',
'third_party/boringssl/ssl/s3_lib.c',
'third_party/boringssl/ssl/s3_pkt.c',
'third_party/boringssl/ssl/ssl_aead_ctx.c',
@ -477,9 +473,12 @@
'third_party/boringssl/ssl/ssl_ecdh.c',
'third_party/boringssl/ssl/ssl_file.c',
'third_party/boringssl/ssl/ssl_lib.c',
'third_party/boringssl/ssl/ssl_rsa.c',
'third_party/boringssl/ssl/ssl_privkey.c',
'third_party/boringssl/ssl/ssl_privkey_cc.cc',
'third_party/boringssl/ssl/ssl_session.c',
'third_party/boringssl/ssl/ssl_stat.c',
'third_party/boringssl/ssl/ssl_transcript.c',
'third_party/boringssl/ssl/ssl_x509.c',
'third_party/boringssl/ssl/t1_enc.c',
'third_party/boringssl/ssl/t1_lib.c',
'third_party/boringssl/ssl/tls13_both.c',
@ -488,9 +487,20 @@
'third_party/boringssl/ssl/tls13_server.c',
'third_party/boringssl/ssl/tls_method.c',
'third_party/boringssl/ssl/tls_record.c',
]
],
'conditions': [
['OS=="mac"', {
'xcode_settings': {
'MACOSX_DEPLOYMENT_TARGET': '10.9',
'OTHER_CPLUSPLUSFLAGS': [
'-stdlib=libc++',
'-std=c++11'
],
}
}],
],
},
]
],
}],
['OS == "win" and runtime!="electron"', {
'targets': [
@ -594,7 +604,6 @@
'src/core/lib/support/log_windows.c',
'src/core/lib/support/mpscq.c',
'src/core/lib/support/murmur_hash.c',
'src/core/lib/support/stack_lockfree.c',
'src/core/lib/support/string.c',
'src/core/lib/support/string_posix.c',
'src/core/lib/support/string_util_windows.c',
@ -720,8 +729,6 @@
'src/core/lib/iomgr/wakeup_fd_nospecial.c',
'src/core/lib/iomgr/wakeup_fd_pipe.c',
'src/core/lib/iomgr/wakeup_fd_posix.c',
'src/core/lib/iomgr/workqueue_uv.c',
'src/core/lib/iomgr/workqueue_windows.c',
'src/core/lib/json/json.c',
'src/core/lib/json/json_reader.c',
'src/core/lib/json/json_string.c',
@ -864,6 +871,7 @@
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c',
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c',
'src/core/ext/filters/load_reporting/load_reporting.c',

@ -99,7 +99,6 @@ filegroups:
- src/core/lib/support/mpscq.h
- src/core/lib/support/murmur_hash.h
- src/core/lib/support/spinlock.h
- src/core/lib/support/stack_lockfree.h
- src/core/lib/support/string.h
- src/core/lib/support/string_windows.h
- src/core/lib/support/thd_internal.h
@ -130,7 +129,6 @@ filegroups:
- src/core/lib/support/log_windows.c
- src/core/lib/support/mpscq.c
- src/core/lib/support/murmur_hash.c
- src/core/lib/support/stack_lockfree.c
- src/core/lib/support/string.c
- src/core/lib/support/string_posix.c
- src/core/lib/support/string_util_windows.c
@ -254,9 +252,6 @@ filegroups:
- src/core/lib/iomgr/wakeup_fd_cv.h
- src/core/lib/iomgr/wakeup_fd_pipe.h
- src/core/lib/iomgr/wakeup_fd_posix.h
- src/core/lib/iomgr/workqueue.h
- src/core/lib/iomgr/workqueue_uv.h
- src/core/lib/iomgr/workqueue_windows.h
- src/core/lib/json/json.h
- src/core/lib/json/json_common.h
- src/core/lib/json/json_reader.h
@ -375,8 +370,6 @@ filegroups:
- src/core/lib/iomgr/wakeup_fd_nospecial.c
- src/core/lib/iomgr/wakeup_fd_pipe.c
- src/core/lib/iomgr/wakeup_fd_posix.c
- src/core/lib/iomgr/workqueue_uv.c
- src/core/lib/iomgr/workqueue_windows.c
- src/core/lib/json/json.c
- src/core/lib/json/json_reader.c
- src/core/lib/json/json_string.c
@ -594,6 +587,7 @@ filegroups:
- src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c
plugin: grpc_resolver_dns_ares
uses:
- grpc_base
@ -1041,6 +1035,7 @@ filegroups:
- include/grpc++/test/server_context_test_spouse.h
deps:
- grpc++
- grpc
libs:
- name: gpr
build: all
@ -1291,6 +1286,7 @@ libs:
- test/cpp/util/proto_reflection_descriptor_database.cc
deps:
- grpc++
- grpc
filegroups:
- grpc++_reflection_proto
- grpc++_config_proto
@ -1306,6 +1302,7 @@ libs:
- src/cpp/ext/proto_server_reflection_plugin.cc
deps:
- grpc++
- grpc
filegroups:
- grpc++_reflection_proto
- name: grpc++_test_config
@ -1339,6 +1336,7 @@ libs:
deps:
- grpc++
- grpc_test_util
- grpc
filegroups:
- grpc++_codegen_base
- grpc++_codegen_base_src
@ -1396,6 +1394,7 @@ libs:
deps:
- grpc++_proto_reflection_desc_db
- grpc++
- grpc
filegroups:
- grpc++_reflection_proto
- grpc++_config_proto
@ -1560,6 +1559,7 @@ libs:
- grpc_test_util
- grpc++_test_util
- grpc++
- grpc
- name: grpc_csharp_ext
build: all
language: csharp
@ -2121,15 +2121,6 @@ targets:
deps:
- gpr_test_util
- gpr
- name: gpr_stack_lockfree_test
cpu_cost: 7
build: test
language: c
src:
- test/core/support/stack_lockfree_test.c
deps:
- gpr_test_util
- gpr
- name: gpr_string_test
build: test
language: c
@ -3730,6 +3721,7 @@ targets:
- test/cpp/util/string_ref_test.cc
deps:
- grpc++
- grpc
- name: cxx_time_test
gtest: true
build: test

@ -63,7 +63,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/support/log_windows.c \
src/core/lib/support/mpscq.c \
src/core/lib/support/murmur_hash.c \
src/core/lib/support/stack_lockfree.c \
src/core/lib/support/string.c \
src/core/lib/support/string_posix.c \
src/core/lib/support/string_util_windows.c \
@ -167,8 +166,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/iomgr/wakeup_fd_nospecial.c \
src/core/lib/iomgr/wakeup_fd_pipe.c \
src/core/lib/iomgr/wakeup_fd_posix.c \
src/core/lib/iomgr/workqueue_uv.c \
src/core/lib/iomgr/workqueue_windows.c \
src/core/lib/json/json.c \
src/core/lib/json/json_reader.c \
src/core/lib/json/json_string.c \
@ -311,6 +308,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c \
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c \
src/core/ext/filters/load_reporting/load_reporting.c \
@ -337,6 +335,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/plugin_registry/grpc_plugin_registry.c \
src/boringssl/err_data.c \
third_party/boringssl/crypto/aes/aes.c \
third_party/boringssl/crypto/aes/key_wrap.c \
third_party/boringssl/crypto/aes/mode_wrappers.c \
third_party/boringssl/crypto/asn1/a_bitstr.c \
third_party/boringssl/crypto/asn1/a_bool.c \
@ -368,12 +367,12 @@ if test "$PHP_GRPC" != "no"; then
third_party/boringssl/crypto/asn1/tasn_new.c \
third_party/boringssl/crypto/asn1/tasn_typ.c \
third_party/boringssl/crypto/asn1/tasn_utl.c \
third_party/boringssl/crypto/asn1/time_support.c \
third_party/boringssl/crypto/asn1/x_bignum.c \
third_party/boringssl/crypto/asn1/x_long.c \
third_party/boringssl/crypto/base64/base64.c \
third_party/boringssl/crypto/bio/bio.c \
third_party/boringssl/crypto/bio/bio_mem.c \
third_party/boringssl/crypto/bio/buffer.c \
third_party/boringssl/crypto/bio/connect.c \
third_party/boringssl/crypto/bio/fd.c \
third_party/boringssl/crypto/bio/file.c \
@ -480,12 +479,7 @@ if test "$PHP_GRPC" != "no"; then
third_party/boringssl/crypto/modes/ctr.c \
third_party/boringssl/crypto/modes/gcm.c \
third_party/boringssl/crypto/modes/ofb.c \
third_party/boringssl/crypto/newhope/error_correction.c \
third_party/boringssl/crypto/newhope/newhope.c \
third_party/boringssl/crypto/newhope/ntt.c \
third_party/boringssl/crypto/newhope/poly.c \
third_party/boringssl/crypto/newhope/precomp.c \
third_party/boringssl/crypto/newhope/reduce.c \
third_party/boringssl/crypto/modes/polyval.c \
third_party/boringssl/crypto/obj/obj.c \
third_party/boringssl/crypto/obj/obj_xref.c \
third_party/boringssl/crypto/pem/pem_all.c \
@ -496,14 +490,15 @@ if test "$PHP_GRPC" != "no"; then
third_party/boringssl/crypto/pem/pem_pkey.c \
third_party/boringssl/crypto/pem/pem_x509.c \
third_party/boringssl/crypto/pem/pem_xaux.c \
third_party/boringssl/crypto/pkcs8/p5_pbe.c \
third_party/boringssl/crypto/pkcs8/p5_pbev2.c \
third_party/boringssl/crypto/pkcs8/p8_pkey.c \
third_party/boringssl/crypto/pkcs8/pkcs8.c \
third_party/boringssl/crypto/poly1305/poly1305.c \
third_party/boringssl/crypto/poly1305/poly1305_arm.c \
third_party/boringssl/crypto/poly1305/poly1305_vec.c \
third_party/boringssl/crypto/pool/pool.c \
third_party/boringssl/crypto/rand/deterministic.c \
third_party/boringssl/crypto/rand/fuchsia.c \
third_party/boringssl/crypto/rand/rand.c \
third_party/boringssl/crypto/rand/urandom.c \
third_party/boringssl/crypto/rand/windows.c \
@ -515,6 +510,7 @@ if test "$PHP_GRPC" != "no"; then
third_party/boringssl/crypto/rsa/rsa.c \
third_party/boringssl/crypto/rsa/rsa_asn1.c \
third_party/boringssl/crypto/rsa/rsa_impl.c \
third_party/boringssl/crypto/sha/sha1-altivec.c \
third_party/boringssl/crypto/sha/sha1.c \
third_party/boringssl/crypto/sha/sha256.c \
third_party/boringssl/crypto/sha/sha512.c \
@ -523,7 +519,6 @@ if test "$PHP_GRPC" != "no"; then
third_party/boringssl/crypto/thread_none.c \
third_party/boringssl/crypto/thread_pthread.c \
third_party/boringssl/crypto/thread_win.c \
third_party/boringssl/crypto/time_support.c \
third_party/boringssl/crypto/x509/a_digest.c \
third_party/boringssl/crypto/x509/a_sign.c \
third_party/boringssl/crypto/x509/a_strex.c \
@ -607,6 +602,7 @@ if test "$PHP_GRPC" != "no"; then
third_party/boringssl/crypto/x509v3/v3_skey.c \
third_party/boringssl/crypto/x509v3/v3_sxnet.c \
third_party/boringssl/crypto/x509v3/v3_utl.c \
third_party/boringssl/ssl/bio_ssl.c \
third_party/boringssl/ssl/custom_extensions.c \
third_party/boringssl/ssl/d1_both.c \
third_party/boringssl/ssl/d1_lib.c \
@ -617,7 +613,6 @@ if test "$PHP_GRPC" != "no"; then
third_party/boringssl/ssl/handshake_client.c \
third_party/boringssl/ssl/handshake_server.c \
third_party/boringssl/ssl/s3_both.c \
third_party/boringssl/ssl/s3_enc.c \
third_party/boringssl/ssl/s3_lib.c \
third_party/boringssl/ssl/s3_pkt.c \
third_party/boringssl/ssl/ssl_aead_ctx.c \
@ -628,9 +623,12 @@ if test "$PHP_GRPC" != "no"; then
third_party/boringssl/ssl/ssl_ecdh.c \
third_party/boringssl/ssl/ssl_file.c \
third_party/boringssl/ssl/ssl_lib.c \
third_party/boringssl/ssl/ssl_rsa.c \
third_party/boringssl/ssl/ssl_privkey.c \
third_party/boringssl/ssl/ssl_privkey_cc.cc \
third_party/boringssl/ssl/ssl_session.c \
third_party/boringssl/ssl/ssl_stat.c \
third_party/boringssl/ssl/ssl_transcript.c \
third_party/boringssl/ssl/ssl_x509.c \
third_party/boringssl/ssl/t1_enc.c \
third_party/boringssl/ssl/t1_lib.c \
third_party/boringssl/ssl/tls13_both.c \
@ -729,11 +727,11 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/md4)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/md5)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/modes)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/newhope)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/obj)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/pem)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/pkcs8)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/poly1305)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/pool)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/rand)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/rc4)
PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/rsa)

@ -40,7 +40,6 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\support\\log_windows.c " +
"src\\core\\lib\\support\\mpscq.c " +
"src\\core\\lib\\support\\murmur_hash.c " +
"src\\core\\lib\\support\\stack_lockfree.c " +
"src\\core\\lib\\support\\string.c " +
"src\\core\\lib\\support\\string_posix.c " +
"src\\core\\lib\\support\\string_util_windows.c " +
@ -144,8 +143,6 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\iomgr\\wakeup_fd_nospecial.c " +
"src\\core\\lib\\iomgr\\wakeup_fd_pipe.c " +
"src\\core\\lib\\iomgr\\wakeup_fd_posix.c " +
"src\\core\\lib\\iomgr\\workqueue_uv.c " +
"src\\core\\lib\\iomgr\\workqueue_windows.c " +
"src\\core\\lib\\json\\json.c " +
"src\\core\\lib\\json\\json_reader.c " +
"src\\core\\lib\\json\\json_string.c " +
@ -288,6 +285,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\dns_resolver_ares.c " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_posix.c " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper.c " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_fallback.c " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.c " +
"src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.c " +
"src\\core\\ext\\filters\\load_reporting\\load_reporting.c " +
@ -314,6 +312,7 @@ if (PHP_GRPC != "no") {
"src\\core\\plugin_registry\\grpc_plugin_registry.c " +
"src\\boringssl\\err_data.c " +
"third_party\\boringssl\\crypto\\aes\\aes.c " +
"third_party\\boringssl\\crypto\\aes\\key_wrap.c " +
"third_party\\boringssl\\crypto\\aes\\mode_wrappers.c " +
"third_party\\boringssl\\crypto\\asn1\\a_bitstr.c " +
"third_party\\boringssl\\crypto\\asn1\\a_bool.c " +
@ -345,12 +344,12 @@ if (PHP_GRPC != "no") {
"third_party\\boringssl\\crypto\\asn1\\tasn_new.c " +
"third_party\\boringssl\\crypto\\asn1\\tasn_typ.c " +
"third_party\\boringssl\\crypto\\asn1\\tasn_utl.c " +
"third_party\\boringssl\\crypto\\asn1\\time_support.c " +
"third_party\\boringssl\\crypto\\asn1\\x_bignum.c " +
"third_party\\boringssl\\crypto\\asn1\\x_long.c " +
"third_party\\boringssl\\crypto\\base64\\base64.c " +
"third_party\\boringssl\\crypto\\bio\\bio.c " +
"third_party\\boringssl\\crypto\\bio\\bio_mem.c " +
"third_party\\boringssl\\crypto\\bio\\buffer.c " +
"third_party\\boringssl\\crypto\\bio\\connect.c " +
"third_party\\boringssl\\crypto\\bio\\fd.c " +
"third_party\\boringssl\\crypto\\bio\\file.c " +
@ -457,12 +456,7 @@ if (PHP_GRPC != "no") {
"third_party\\boringssl\\crypto\\modes\\ctr.c " +
"third_party\\boringssl\\crypto\\modes\\gcm.c " +
"third_party\\boringssl\\crypto\\modes\\ofb.c " +
"third_party\\boringssl\\crypto\\newhope\\error_correction.c " +
"third_party\\boringssl\\crypto\\newhope\\newhope.c " +
"third_party\\boringssl\\crypto\\newhope\\ntt.c " +
"third_party\\boringssl\\crypto\\newhope\\poly.c " +
"third_party\\boringssl\\crypto\\newhope\\precomp.c " +
"third_party\\boringssl\\crypto\\newhope\\reduce.c " +
"third_party\\boringssl\\crypto\\modes\\polyval.c " +
"third_party\\boringssl\\crypto\\obj\\obj.c " +
"third_party\\boringssl\\crypto\\obj\\obj_xref.c " +
"third_party\\boringssl\\crypto\\pem\\pem_all.c " +
@ -473,14 +467,15 @@ if (PHP_GRPC != "no") {
"third_party\\boringssl\\crypto\\pem\\pem_pkey.c " +
"third_party\\boringssl\\crypto\\pem\\pem_x509.c " +
"third_party\\boringssl\\crypto\\pem\\pem_xaux.c " +
"third_party\\boringssl\\crypto\\pkcs8\\p5_pbe.c " +
"third_party\\boringssl\\crypto\\pkcs8\\p5_pbev2.c " +
"third_party\\boringssl\\crypto\\pkcs8\\p8_pkey.c " +
"third_party\\boringssl\\crypto\\pkcs8\\pkcs8.c " +
"third_party\\boringssl\\crypto\\poly1305\\poly1305.c " +
"third_party\\boringssl\\crypto\\poly1305\\poly1305_arm.c " +
"third_party\\boringssl\\crypto\\poly1305\\poly1305_vec.c " +
"third_party\\boringssl\\crypto\\pool\\pool.c " +
"third_party\\boringssl\\crypto\\rand\\deterministic.c " +
"third_party\\boringssl\\crypto\\rand\\fuchsia.c " +
"third_party\\boringssl\\crypto\\rand\\rand.c " +
"third_party\\boringssl\\crypto\\rand\\urandom.c " +
"third_party\\boringssl\\crypto\\rand\\windows.c " +
@ -492,6 +487,7 @@ if (PHP_GRPC != "no") {
"third_party\\boringssl\\crypto\\rsa\\rsa.c " +
"third_party\\boringssl\\crypto\\rsa\\rsa_asn1.c " +
"third_party\\boringssl\\crypto\\rsa\\rsa_impl.c " +
"third_party\\boringssl\\crypto\\sha\\sha1-altivec.c " +
"third_party\\boringssl\\crypto\\sha\\sha1.c " +
"third_party\\boringssl\\crypto\\sha\\sha256.c " +
"third_party\\boringssl\\crypto\\sha\\sha512.c " +
@ -500,7 +496,6 @@ if (PHP_GRPC != "no") {
"third_party\\boringssl\\crypto\\thread_none.c " +
"third_party\\boringssl\\crypto\\thread_pthread.c " +
"third_party\\boringssl\\crypto\\thread_win.c " +
"third_party\\boringssl\\crypto\\time_support.c " +
"third_party\\boringssl\\crypto\\x509\\a_digest.c " +
"third_party\\boringssl\\crypto\\x509\\a_sign.c " +
"third_party\\boringssl\\crypto\\x509\\a_strex.c " +
@ -584,6 +579,7 @@ if (PHP_GRPC != "no") {
"third_party\\boringssl\\crypto\\x509v3\\v3_skey.c " +
"third_party\\boringssl\\crypto\\x509v3\\v3_sxnet.c " +
"third_party\\boringssl\\crypto\\x509v3\\v3_utl.c " +
"third_party\\boringssl\\ssl\\bio_ssl.c " +
"third_party\\boringssl\\ssl\\custom_extensions.c " +
"third_party\\boringssl\\ssl\\d1_both.c " +
"third_party\\boringssl\\ssl\\d1_lib.c " +
@ -594,7 +590,6 @@ if (PHP_GRPC != "no") {
"third_party\\boringssl\\ssl\\handshake_client.c " +
"third_party\\boringssl\\ssl\\handshake_server.c " +
"third_party\\boringssl\\ssl\\s3_both.c " +
"third_party\\boringssl\\ssl\\s3_enc.c " +
"third_party\\boringssl\\ssl\\s3_lib.c " +
"third_party\\boringssl\\ssl\\s3_pkt.c " +
"third_party\\boringssl\\ssl\\ssl_aead_ctx.c " +
@ -605,9 +600,12 @@ if (PHP_GRPC != "no") {
"third_party\\boringssl\\ssl\\ssl_ecdh.c " +
"third_party\\boringssl\\ssl\\ssl_file.c " +
"third_party\\boringssl\\ssl\\ssl_lib.c " +
"third_party\\boringssl\\ssl\\ssl_rsa.c " +
"third_party\\boringssl\\ssl\\ssl_privkey.c " +
"third_party\\boringssl\\ssl\\ssl_privkey_cc.cc " +
"third_party\\boringssl\\ssl\\ssl_session.c " +
"third_party\\boringssl\\ssl\\ssl_stat.c " +
"third_party\\boringssl\\ssl\\ssl_transcript.c " +
"third_party\\boringssl\\ssl\\ssl_x509.c " +
"third_party\\boringssl\\ssl\\t1_enc.c " +
"third_party\\boringssl\\ssl\\t1_lib.c " +
"third_party\\boringssl\\ssl\\tls13_both.c " +
@ -641,4 +639,134 @@ if (PHP_GRPC != "no") {
"/I"+configure_module_dirname+"\\src\\php\\ext\\grpc "+
"/I"+configure_module_dirname+"\\third_party\\boringssl\\include "+
"/I"+configure_module_dirname+"\\third_party\\zlib");
base_dir = get_define('BUILD_DIR');
FSO.CreateFolder(base_dir+"\\ext");
FSO.CreateFolder(base_dir+"\\ext\\grpc");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\boringssl");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\census");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\census\\gen");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\pick_first");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\round_robin");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\fake");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\deadline");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\client");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\message_compress");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http\\server");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\load_reporting");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\max_age");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\message_size");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\workarounds");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\alpn");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\client");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\client\\insecure");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\client\\secure");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\server");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\server\\insecure");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\server\\secure");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\transport\\chttp2\\transport");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\channel");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\compression");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\debug");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\http");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\iomgr");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\json");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\profiling");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\context");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\composite");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\fake");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\google_default");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\iam");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\jwt");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\oauth2");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\plugin");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\ssl");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\transport");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\util");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\slice");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\support");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\surface");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\transport");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\plugin_registry");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\tsi");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php\\ext");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php\\ext\\grpc");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\aes");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\asn1");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\base64");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\bio");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\bn");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\bn\\asm");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\buf");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\bytestring");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\chacha");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\cipher");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\cmac");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\conf");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\curve25519");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\des");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\dh");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\digest");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\dsa");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\ec");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\ecdh");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\ecdsa");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\engine");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\err");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\evp");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\hkdf");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\hmac");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\lhash");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\md4");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\md5");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\modes");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\obj");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\pem");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\pkcs8");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\poly1305");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\pool");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\rand");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\rc4");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\rsa");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\sha");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\stack");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\x509");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\crypto\\x509v3");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\boringssl\\ssl");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\nanopb");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\third_party\\zlib");
_build_dirs = new Array();
for (i = 0; i < build_dirs.length; i++) {
if (build_dirs[i].indexOf('grpc') == -1) {
_build_dirs[_build_dirs.length] = build_dirs[i];
}
}
build_dirs = _build_dirs;
}

@ -24,7 +24,8 @@ Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames.
* **Call-Definition** → Method Scheme Path TE [Authority] [Timeout] Content-Type [Message-Type] [Message-Encoding] [Message-Accept-Encoding] [User-Agent]
* **Method** → ":method POST"
* **Scheme** → ":scheme " ("http" / "https")
* **Path** → ":path" {_path identifying method within exposed API_}
* **Path** → ":path" "/" Service-Name "/" {_method name_}
* **Service-Name** → {_IDL-specific service name_}
* **Authority** → ":authority" {_virtual host name of authority_}
* **TE** → "te" "trailers" # Used to detect incompatible proxies
* **Timeout** → "grpc-timeout" TimeoutValue TimeoutUnit
@ -51,6 +52,13 @@ Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames.
HTTP2 requires that reserved headers, ones starting with ":" appear before all other headers. Additionally implementations should send **Timeout** immediately after the reserved headers and they should send the **Call-Definition** headers before sending **Custom-Metadata**.
Some gRPC implementations may allow the **Path** format shown above
to be overridden, but this functionality is strongly discouraged.
gRPC does not go out of its way to break users that are using this kind
of override, but we do not actively support it, and some functionality
(e.g., service config support) will not work when the path is not of
the form shown above.
If **Timeout** is omitted a server should assume an infinite timeout. Client implementations are free to send a default minimum timeout based on their deployment requirements.
**Custom-Metadata** is an arbitrary set of key-value pairs defined by the application layer. Header names starting with "grpc-" but not listed here are reserved for future GRPC use and should not be used by applications as **Custom-Metadata**.
@ -238,10 +246,10 @@ If a detectable connection failure occurs on the client all calls will be closed
### Appendix A - GRPC for Protobuf
The service interfaces declared by protobuf are easily mapped onto GRPC by code generation extensions to protoc. The following defines the mapping to be used
The service interfaces declared by protobuf are easily mapped onto GRPC by
code generation extensions to protoc. The following defines the mapping
to be used.
* **Path** → / Service-Name / {_method name_}
* **Service-Name** → ?( {_proto package name_} "." ) {_service name_}
* **Message-Type** → {_fully qualified proto message name_}
* **Content-Type** → "application/grpc+proto"

@ -83,12 +83,12 @@ c->cb(exec_ctx, c->cb_arg, err);
The caller is still responsible for unref-ing the error.
However, the above line is currently being phased out! It is safer to invoke
callbacks with `grpc_closure_run` and `grpc_closure_sched`. These functions are
callbacks with `GRPC_CLOSURE_RUN` and `GRPC_CLOSURE_SCHED`. These functions are
not callbacks, so they will take ownership of the error passed to them.
```C
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured");
grpc_closure_run(exec_ctx, cb, error);
GRPC_CLOSURE_RUN(exec_ctx, cb, error);
// current function no longer has ownership of the error
```
@ -97,7 +97,7 @@ you must explicitly take a reference.
```C
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured");
grpc_closure_run(exec_ctx, cb, GRPC_ERROR_REF(error));
GRPC_CLOSURE_RUN(exec_ctx, cb, GRPC_ERROR_REF(error));
// do some other things with the error
GRPC_ERROR_UNREF(error);
```

@ -4,6 +4,10 @@ gRPC environment variables
gRPC C core based implementations (those contained in this repository) expose
some configuration as environment variables that can be set.
* http_proxy
The URI of the proxy to use for HTTP CONNECT support. Does not currently
support username or password information in the URI.
* GRPC_ABORT_ON_LEAKS
A debugging aid to cause a call to abort() when gRPC objects are leaked past
grpc_shutdown(). Set to 1 to cause the abort, if unset or 0 it does not
@ -47,8 +51,6 @@ some configuration as environment variables that can be set.
- flowctl - traces http2 flow control
- op_failure - traces error information when failure is pushed onto a
completion queue
- pending_tags - [debug builds only] traces still-in-progress tags on
completion queues
- round_robin - traces the round_robin load balancing policy
- glb - traces the grpclb load balancer
- queue_pluck
@ -59,6 +61,23 @@ some configuration as environment variables that can be set.
- transport_security - traces metadata about secure channel establishment
- tcp - traces bytes in and out of a channel
The following tracers will only run in binaries built in DEBUG mode. This is
accomplished by invoking `CONFIG=dbg make <target>`
- metadata - tracks creation and mutation of metadata
- closure - tracks closure creation, scheduling, and completion
- pending_tags - traces still-in-progress tags on completion queues
- polling - traces the selected polling engine
- queue_refcount
- error_refcount
- stream_refcount
- workqueue_refcount
- fd_refcount
- auth_context_refcount
- security_connector_refcount
- resolver_refcount
- lb_policy_refcount
- chttp2_refcount
'all' can additionally be used to turn all traces on.
Individual traces can be disabled by prefixing them with '-'.

@ -17,16 +17,16 @@
HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
SYSTEM ?= $(HOST_SYSTEM)
CXX = g++
CPPFLAGS += -I/usr/local/include -pthread
CPPFLAGS += `pkg-config --cflags protobuf grpc`
CXXFLAGS += -std=c++11
ifeq ($(SYSTEM),Darwin)
LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++ grpc` \
-lgrpc++_reflection \
-lprotobuf -lpthread -ldl
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
-lgrpc++_reflection\
-ldl
else
LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++ grpc` \
-Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed \
-lprotobuf -lpthread -ldl
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
-Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\
-ldl
endif
PROTOC = protoc
GRPC_CPP_PLUGIN = grpc_cpp_plugin

@ -17,16 +17,16 @@
HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
SYSTEM ?= $(HOST_SYSTEM)
CXX = g++
CPPFLAGS += -I/usr/local/include -pthread
CPPFLAGS += `pkg-config --cflags protobuf grpc`
CXXFLAGS += -std=c++11
ifeq ($(SYSTEM),Darwin)
LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` \
-lgrpc++_reflection \
-lprotobuf -lpthread -ldl
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++`\
-lgrpc++_reflection\
-ldl
else
LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` \
-Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed \
-lprotobuf -lpthread -ldl
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++`\
-Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\
-ldl
endif
PROTOC = protoc
GRPC_CPP_PLUGIN = grpc_cpp_plugin

@ -193,7 +193,6 @@ Pod::Spec.new do |s|
'src/core/lib/support/mpscq.h',
'src/core/lib/support/murmur_hash.h',
'src/core/lib/support/spinlock.h',
'src/core/lib/support/stack_lockfree.h',
'src/core/lib/support/string.h',
'src/core/lib/support/string_windows.h',
'src/core/lib/support/thd_internal.h',
@ -223,7 +222,6 @@ Pod::Spec.new do |s|
'src/core/lib/support/log_windows.c',
'src/core/lib/support/mpscq.c',
'src/core/lib/support/murmur_hash.c',
'src/core/lib/support/stack_lockfree.c',
'src/core/lib/support/string.c',
'src/core/lib/support/string_posix.c',
'src/core/lib/support/string_util_windows.c',
@ -318,9 +316,6 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/wakeup_fd_cv.h',
'src/core/lib/iomgr/wakeup_fd_pipe.h',
'src/core/lib/iomgr/wakeup_fd_posix.h',
'src/core/lib/iomgr/workqueue.h',
'src/core/lib/iomgr/workqueue_uv.h',
'src/core/lib/iomgr/workqueue_windows.h',
'src/core/lib/json/json.h',
'src/core/lib/json/json_common.h',
'src/core/lib/json/json_reader.h',
@ -546,8 +541,6 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/wakeup_fd_nospecial.c',
'src/core/lib/iomgr/wakeup_fd_pipe.c',
'src/core/lib/iomgr/wakeup_fd_posix.c',
'src/core/lib/iomgr/workqueue_uv.c',
'src/core/lib/iomgr/workqueue_windows.c',
'src/core/lib/json/json.c',
'src/core/lib/json/json_reader.c',
'src/core/lib/json/json_string.c',
@ -690,6 +683,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c',
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c',
'src/core/ext/filters/load_reporting/load_reporting.c',
@ -727,7 +721,6 @@ Pod::Spec.new do |s|
'src/core/lib/support/mpscq.h',
'src/core/lib/support/murmur_hash.h',
'src/core/lib/support/spinlock.h',
'src/core/lib/support/stack_lockfree.h',
'src/core/lib/support/string.h',
'src/core/lib/support/string_windows.h',
'src/core/lib/support/thd_internal.h',
@ -806,9 +799,6 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/wakeup_fd_cv.h',
'src/core/lib/iomgr/wakeup_fd_pipe.h',
'src/core/lib/iomgr/wakeup_fd_posix.h',
'src/core/lib/iomgr/workqueue.h',
'src/core/lib/iomgr/workqueue_uv.h',
'src/core/lib/iomgr/workqueue_windows.h',
'src/core/lib/json/json.h',
'src/core/lib/json/json_common.h',
'src/core/lib/json/json_reader.h',

@ -92,7 +92,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/support/mpscq.h )
s.files += %w( src/core/lib/support/murmur_hash.h )
s.files += %w( src/core/lib/support/spinlock.h )
s.files += %w( src/core/lib/support/stack_lockfree.h )
s.files += %w( src/core/lib/support/string.h )
s.files += %w( src/core/lib/support/string_windows.h )
s.files += %w( src/core/lib/support/thd_internal.h )
@ -122,7 +121,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/support/log_windows.c )
s.files += %w( src/core/lib/support/mpscq.c )
s.files += %w( src/core/lib/support/murmur_hash.c )
s.files += %w( src/core/lib/support/stack_lockfree.c )
s.files += %w( src/core/lib/support/string.c )
s.files += %w( src/core/lib/support/string_posix.c )
s.files += %w( src/core/lib/support/string_util_windows.c )
@ -249,9 +247,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/wakeup_fd_cv.h )
s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.h )
s.files += %w( src/core/lib/iomgr/wakeup_fd_posix.h )
s.files += %w( src/core/lib/iomgr/workqueue.h )
s.files += %w( src/core/lib/iomgr/workqueue_uv.h )
s.files += %w( src/core/lib/iomgr/workqueue_windows.h )
s.files += %w( src/core/lib/json/json.h )
s.files += %w( src/core/lib/json/json_common.h )
s.files += %w( src/core/lib/json/json_reader.h )
@ -477,8 +472,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/wakeup_fd_nospecial.c )
s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.c )
s.files += %w( src/core/lib/iomgr/wakeup_fd_posix.c )
s.files += %w( src/core/lib/iomgr/workqueue_uv.c )
s.files += %w( src/core/lib/iomgr/workqueue_windows.c )
s.files += %w( src/core/lib/json/json.c )
s.files += %w( src/core/lib/json/json_reader.c )
s.files += %w( src/core/lib/json/json_string.c )
@ -621,6 +614,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c )
s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c )
s.files += %w( src/core/ext/filters/load_reporting/load_reporting.c )
@ -660,14 +654,14 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl/crypto/digest/md32_common.h )
s.files += %w( third_party/boringssl/crypto/ec/internal.h )
s.files += %w( third_party/boringssl/crypto/ec/p256-x86_64-table.h )
s.files += %w( third_party/boringssl/crypto/ec/p256-x86_64.h )
s.files += %w( third_party/boringssl/crypto/evp/internal.h )
s.files += %w( third_party/boringssl/crypto/internal.h )
s.files += %w( third_party/boringssl/crypto/modes/internal.h )
s.files += %w( third_party/boringssl/crypto/newhope/internal.h )
s.files += %w( third_party/boringssl/crypto/obj/obj_dat.h )
s.files += %w( third_party/boringssl/crypto/obj/obj_xref.h )
s.files += %w( third_party/boringssl/crypto/pkcs8/internal.h )
s.files += %w( third_party/boringssl/crypto/poly1305/internal.h )
s.files += %w( third_party/boringssl/crypto/pool/internal.h )
s.files += %w( third_party/boringssl/crypto/rand/internal.h )
s.files += %w( third_party/boringssl/crypto/rsa/internal.h )
s.files += %w( third_party/boringssl/crypto/x509/charmap.h )
@ -717,7 +711,6 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl/include/openssl/md4.h )
s.files += %w( third_party/boringssl/include/openssl/md5.h )
s.files += %w( third_party/boringssl/include/openssl/mem.h )
s.files += %w( third_party/boringssl/include/openssl/newhope.h )
s.files += %w( third_party/boringssl/include/openssl/nid.h )
s.files += %w( third_party/boringssl/include/openssl/obj.h )
s.files += %w( third_party/boringssl/include/openssl/obj_mac.h )
@ -730,6 +723,7 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl/include/openssl/pkcs7.h )
s.files += %w( third_party/boringssl/include/openssl/pkcs8.h )
s.files += %w( third_party/boringssl/include/openssl/poly1305.h )
s.files += %w( third_party/boringssl/include/openssl/pool.h )
s.files += %w( third_party/boringssl/include/openssl/rand.h )
s.files += %w( third_party/boringssl/include/openssl/rc4.h )
s.files += %w( third_party/boringssl/include/openssl/ripemd.h )
@ -742,7 +736,6 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl/include/openssl/stack.h )
s.files += %w( third_party/boringssl/include/openssl/stack_macros.h )
s.files += %w( third_party/boringssl/include/openssl/thread.h )
s.files += %w( third_party/boringssl/include/openssl/time_support.h )
s.files += %w( third_party/boringssl/include/openssl/tls1.h )
s.files += %w( third_party/boringssl/include/openssl/type_check.h )
s.files += %w( third_party/boringssl/include/openssl/x509.h )
@ -751,6 +744,7 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl/ssl/internal.h )
s.files += %w( src/boringssl/err_data.c )
s.files += %w( third_party/boringssl/crypto/aes/aes.c )
s.files += %w( third_party/boringssl/crypto/aes/key_wrap.c )
s.files += %w( third_party/boringssl/crypto/aes/mode_wrappers.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_bitstr.c )
s.files += %w( third_party/boringssl/crypto/asn1/a_bool.c )
@ -782,12 +776,12 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl/crypto/asn1/tasn_new.c )
s.files += %w( third_party/boringssl/crypto/asn1/tasn_typ.c )
s.files += %w( third_party/boringssl/crypto/asn1/tasn_utl.c )
s.files += %w( third_party/boringssl/crypto/asn1/time_support.c )
s.files += %w( third_party/boringssl/crypto/asn1/x_bignum.c )
s.files += %w( third_party/boringssl/crypto/asn1/x_long.c )
s.files += %w( third_party/boringssl/crypto/base64/base64.c )
s.files += %w( third_party/boringssl/crypto/bio/bio.c )
s.files += %w( third_party/boringssl/crypto/bio/bio_mem.c )
s.files += %w( third_party/boringssl/crypto/bio/buffer.c )
s.files += %w( third_party/boringssl/crypto/bio/connect.c )
s.files += %w( third_party/boringssl/crypto/bio/fd.c )
s.files += %w( third_party/boringssl/crypto/bio/file.c )
@ -894,12 +888,7 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl/crypto/modes/ctr.c )
s.files += %w( third_party/boringssl/crypto/modes/gcm.c )
s.files += %w( third_party/boringssl/crypto/modes/ofb.c )
s.files += %w( third_party/boringssl/crypto/newhope/error_correction.c )
s.files += %w( third_party/boringssl/crypto/newhope/newhope.c )
s.files += %w( third_party/boringssl/crypto/newhope/ntt.c )
s.files += %w( third_party/boringssl/crypto/newhope/poly.c )
s.files += %w( third_party/boringssl/crypto/newhope/precomp.c )
s.files += %w( third_party/boringssl/crypto/newhope/reduce.c )
s.files += %w( third_party/boringssl/crypto/modes/polyval.c )
s.files += %w( third_party/boringssl/crypto/obj/obj.c )
s.files += %w( third_party/boringssl/crypto/obj/obj_xref.c )
s.files += %w( third_party/boringssl/crypto/pem/pem_all.c )
@ -910,14 +899,15 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl/crypto/pem/pem_pkey.c )
s.files += %w( third_party/boringssl/crypto/pem/pem_x509.c )
s.files += %w( third_party/boringssl/crypto/pem/pem_xaux.c )
s.files += %w( third_party/boringssl/crypto/pkcs8/p5_pbe.c )
s.files += %w( third_party/boringssl/crypto/pkcs8/p5_pbev2.c )
s.files += %w( third_party/boringssl/crypto/pkcs8/p8_pkey.c )
s.files += %w( third_party/boringssl/crypto/pkcs8/pkcs8.c )
s.files += %w( third_party/boringssl/crypto/poly1305/poly1305.c )
s.files += %w( third_party/boringssl/crypto/poly1305/poly1305_arm.c )
s.files += %w( third_party/boringssl/crypto/poly1305/poly1305_vec.c )
s.files += %w( third_party/boringssl/crypto/pool/pool.c )
s.files += %w( third_party/boringssl/crypto/rand/deterministic.c )
s.files += %w( third_party/boringssl/crypto/rand/fuchsia.c )
s.files += %w( third_party/boringssl/crypto/rand/rand.c )
s.files += %w( third_party/boringssl/crypto/rand/urandom.c )
s.files += %w( third_party/boringssl/crypto/rand/windows.c )
@ -929,6 +919,7 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl/crypto/rsa/rsa.c )
s.files += %w( third_party/boringssl/crypto/rsa/rsa_asn1.c )
s.files += %w( third_party/boringssl/crypto/rsa/rsa_impl.c )
s.files += %w( third_party/boringssl/crypto/sha/sha1-altivec.c )
s.files += %w( third_party/boringssl/crypto/sha/sha1.c )
s.files += %w( third_party/boringssl/crypto/sha/sha256.c )
s.files += %w( third_party/boringssl/crypto/sha/sha512.c )
@ -937,7 +928,6 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl/crypto/thread_none.c )
s.files += %w( third_party/boringssl/crypto/thread_pthread.c )
s.files += %w( third_party/boringssl/crypto/thread_win.c )
s.files += %w( third_party/boringssl/crypto/time_support.c )
s.files += %w( third_party/boringssl/crypto/x509/a_digest.c )
s.files += %w( third_party/boringssl/crypto/x509/a_sign.c )
s.files += %w( third_party/boringssl/crypto/x509/a_strex.c )
@ -1021,6 +1011,7 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl/crypto/x509v3/v3_skey.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_sxnet.c )
s.files += %w( third_party/boringssl/crypto/x509v3/v3_utl.c )
s.files += %w( third_party/boringssl/ssl/bio_ssl.c )
s.files += %w( third_party/boringssl/ssl/custom_extensions.c )
s.files += %w( third_party/boringssl/ssl/d1_both.c )
s.files += %w( third_party/boringssl/ssl/d1_lib.c )
@ -1031,7 +1022,6 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl/ssl/handshake_client.c )
s.files += %w( third_party/boringssl/ssl/handshake_server.c )
s.files += %w( third_party/boringssl/ssl/s3_both.c )
s.files += %w( third_party/boringssl/ssl/s3_enc.c )
s.files += %w( third_party/boringssl/ssl/s3_lib.c )
s.files += %w( third_party/boringssl/ssl/s3_pkt.c )
s.files += %w( third_party/boringssl/ssl/ssl_aead_ctx.c )
@ -1042,9 +1032,12 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl/ssl/ssl_ecdh.c )
s.files += %w( third_party/boringssl/ssl/ssl_file.c )
s.files += %w( third_party/boringssl/ssl/ssl_lib.c )
s.files += %w( third_party/boringssl/ssl/ssl_rsa.c )
s.files += %w( third_party/boringssl/ssl/ssl_privkey.c )
s.files += %w( third_party/boringssl/ssl/ssl_privkey_cc.cc )
s.files += %w( third_party/boringssl/ssl/ssl_session.c )
s.files += %w( third_party/boringssl/ssl/ssl_stat.c )
s.files += %w( third_party/boringssl/ssl/ssl_transcript.c )
s.files += %w( third_party/boringssl/ssl/ssl_x509.c )
s.files += %w( third_party/boringssl/ssl/t1_enc.c )
s.files += %w( third_party/boringssl/ssl/t1_lib.c )
s.files += %w( third_party/boringssl/ssl/tls13_both.c )

@ -52,8 +52,25 @@ class Alarm : private GrpcLibraryCodegen {
alarm_(grpc_alarm_create(cq->cq(), TimePoint<T>(deadline).raw_time(),
static_cast<void*>(&tag_))) {}
/// Alarms aren't copyable.
Alarm(const Alarm&) = delete;
Alarm& operator=(const Alarm&) = delete;
/// Alarms are movable.
Alarm(Alarm&& rhs) : tag_(rhs.tag_), alarm_(rhs.alarm_) {
rhs.alarm_ = nullptr;
}
Alarm& operator=(Alarm&& rhs) {
tag_ = rhs.tag_;
alarm_ = rhs.alarm_;
rhs.alarm_ = nullptr;
return *this;
}
/// Destroy the given completion queue alarm, cancelling it in the process.
~Alarm() { grpc_alarm_destroy(alarm_); }
~Alarm() {
if (alarm_ != nullptr) grpc_alarm_destroy(alarm_);
}
/// Cancel a completion queue alarm. Calling this function over an alarm that
/// has already fired has no effect.
@ -73,7 +90,7 @@ class Alarm : private GrpcLibraryCodegen {
};
AlarmEntry tag_;
grpc_alarm* const alarm_; // owned
grpc_alarm* alarm_; // owned
};
} // namespace grpc

@ -87,6 +87,28 @@ class ClientAsyncResponseReader final
ClientAsyncResponseReader(call, context, request);
}
/// TODO(vjpai): Delete the below constructor
/// PLEASE DO NOT USE THIS CONSTRUCTOR IN NEW CODE
/// This code is only present as a short-term workaround
/// for users that bypassed the code-generator and directly
/// created this struct rather than properly using a stub.
/// This code will not remain a valid public constructor for long.
template <class W>
ClientAsyncResponseReader(ChannelInterface* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
const W& request)
: context_(context),
call_(channel->CreateCall(method, context, cq)),
collection_(std::make_shared<Ops>()) {
collection_->init_buf.SetCollection(collection_);
collection_->init_buf.SendInitialMetadata(
context->send_initial_metadata_, context->initial_metadata_flags());
// TODO(ctiller): don't assert
GPR_CODEGEN_ASSERT(collection_->init_buf.SendMessage(request).ok());
collection_->init_buf.ClientSendClose();
call_.PerformOps(&collection_->init_buf);
}
// always allocated against a call arena, no memory free required
static void operator delete(void* ptr, std::size_t size) {
assert(size == sizeof(ClientAsyncResponseReader));
@ -101,9 +123,18 @@ class ClientAsyncResponseReader final
void ReadInitialMetadata(void* tag) {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
meta_buf_.set_output_tag(tag);
meta_buf_.RecvInitialMetadata(context_);
call_.PerformOps(&meta_buf_);
Ops& o = ops_;
// TODO(vjpai): Remove the collection_ specialization as soon
// as the public constructor is deleted
if (collection_) {
o = *collection_;
collection_->meta_buf.SetCollection(collection_);
}
o.meta_buf.set_output_tag(tag);
o.meta_buf.RecvInitialMetadata(context_);
call_.PerformOps(&o.meta_buf);
}
/// See \a ClientAysncResponseReaderInterface::Finish for semantics.
@ -112,14 +143,23 @@ class ClientAsyncResponseReader final
/// - the \a ClientContext associated with this call is updated with
/// possible initial and trailing metadata sent from the server.
void Finish(R* msg, Status* status, void* tag) {
finish_buf_.set_output_tag(tag);
Ops& o = ops_;
// TODO(vjpai): Remove the collection_ specialization as soon
// as the public constructor is deleted
if (collection_) {
o = *collection_;
collection_->finish_buf.SetCollection(collection_);
}
o.finish_buf.set_output_tag(tag);
if (!context_->initial_metadata_received_) {
finish_buf_.RecvInitialMetadata(context_);
o.finish_buf.RecvInitialMetadata(context_);
}
finish_buf_.RecvMessage(msg);
finish_buf_.AllowNoMessage();
finish_buf_.ClientRecvStatus(context_, status);
call_.PerformOps(&finish_buf_);
o.finish_buf.RecvMessage(msg);
o.finish_buf.AllowNoMessage();
o.finish_buf.ClientRecvStatus(context_, status);
call_.PerformOps(&o.finish_buf);
}
private:
@ -129,25 +169,33 @@ class ClientAsyncResponseReader final
template <class W>
ClientAsyncResponseReader(Call call, ClientContext* context, const W& request)
: context_(context), call_(call) {
init_buf_.SendInitialMetadata(context->send_initial_metadata_,
context->initial_metadata_flags());
ops_.init_buf.SendInitialMetadata(context->send_initial_metadata_,
context->initial_metadata_flags());
// TODO(ctiller): don't assert
GPR_CODEGEN_ASSERT(init_buf_.SendMessage(request).ok());
init_buf_.ClientSendClose();
call_.PerformOps(&init_buf_);
GPR_CODEGEN_ASSERT(ops_.init_buf.SendMessage(request).ok());
ops_.init_buf.ClientSendClose();
call_.PerformOps(&ops_.init_buf);
}
// disable operator new
static void* operator new(std::size_t size);
static void* operator new(std::size_t size, void* p) { return p; }
SneakyCallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpClientSendClose>
init_buf_;
CallOpSet<CallOpRecvInitialMetadata> meta_buf_;
CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>,
CallOpClientRecvStatus>
finish_buf_;
// TODO(vjpai): Remove the reference to CallOpSetCollectionInterface
// as soon as the related workaround (public constructor) is deleted
struct Ops : public CallOpSetCollectionInterface {
SneakyCallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpClientSendClose>
init_buf;
CallOpSet<CallOpRecvInitialMetadata> meta_buf;
CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>,
CallOpClientRecvStatus>
finish_buf;
} ops_;
// TODO(vjpai): Remove the collection_ as soon as the related workaround
// (public constructor) is deleted
std::shared_ptr<Ops> collection_;
};
/// Async server-side API for handling unary calls, where the single

@ -544,6 +544,11 @@ class CallOpClientRecvStatus {
grpc_slice error_message_;
};
/// TODO(vjpai): Remove the existence of CallOpSetCollectionInterface
/// and references to it. This code is deprecated-on-arrival and is
/// only added for users that bypassed the code-generator.
class CallOpSetCollectionInterface {};
/// An abstract collection of call ops, used to generate the
/// grpc_call_op structure to pass down to the lower layers,
/// and as it is-a CompletionQueueTag, also massages the final
@ -554,6 +559,18 @@ class CallOpSetInterface : public CompletionQueueTag {
/// Fills in grpc_op, starting from ops[*nops] and moving
/// upwards.
virtual void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) = 0;
/// TODO(vjpai): Remove the SetCollection method and comment. This is only
/// a short-term workaround for users that bypassed the code generator
/// Mark this as belonging to a collection if needed
void SetCollection(std::shared_ptr<CallOpSetCollectionInterface> collection) {
collection_ = collection;
}
protected:
/// TODO(vjpai): Remove the collection_ field once the idea of bypassing the
/// code generator is forbidden. This is already deprecated
std::shared_ptr<CallOpSetCollectionInterface> collection_;
};
/// Primary implementaiton of CallOpSetInterface.
@ -593,6 +610,11 @@ class CallOpSet : public CallOpSetInterface,
this->Op5::FinishOp(status);
this->Op6::FinishOp(status);
*tag = return_tag_;
// TODO(vjpai): Remove the reference to collection_ once the idea of
// bypassing the code generator is forbidden. It is already deprecated
collection_.reset();
g_core_codegen_interface->grpc_call_unref(call_);
return true;
}

@ -33,7 +33,7 @@
"arguejs": "^0.2.3",
"lodash": "^4.15.0",
"nan": "^2.0.0",
"node-pre-gyp": "^0.6.0",
"node-pre-gyp": "^0.6.35",
"protobufjs": "^5.0.0"
},
"devDependencies": {

@ -106,7 +106,6 @@
<file baseinstalldir="/" name="src/core/lib/support/mpscq.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/murmur_hash.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/spinlock.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/stack_lockfree.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/string.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/string_windows.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/thd_internal.h" role="src" />
@ -136,7 +135,6 @@
<file baseinstalldir="/" name="src/core/lib/support/log_windows.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/mpscq.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/murmur_hash.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/stack_lockfree.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/string.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/string_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/string_util_windows.c" role="src" />
@ -263,9 +261,6 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/wakeup_fd_cv.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/wakeup_fd_pipe.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/wakeup_fd_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/workqueue.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/workqueue_uv.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/workqueue_windows.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json_common.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json_reader.h" role="src" />
@ -491,8 +486,6 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/wakeup_fd_nospecial.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/wakeup_fd_pipe.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/wakeup_fd_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/workqueue_uv.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/workqueue_windows.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json_reader.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json_string.c" role="src" />
@ -635,6 +628,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/load_reporting/load_reporting.c" role="src" />
@ -674,14 +668,14 @@
<file baseinstalldir="/" name="third_party/boringssl/crypto/digest/md32_common.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/ec/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/ec/p256-x86_64-table.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/ec/p256-x86_64.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/evp/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/modes/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/newhope/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/obj/obj_dat.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/obj/obj_xref.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/pkcs8/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/poly1305/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/pool/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/rand/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/rsa/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/x509/charmap.h" role="src" />
@ -731,7 +725,6 @@
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/md4.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/md5.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/mem.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/newhope.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/nid.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/obj.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/obj_mac.h" role="src" />
@ -744,6 +737,7 @@
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/pkcs7.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/pkcs8.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/poly1305.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/pool.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/rand.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/rc4.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/ripemd.h" role="src" />
@ -756,7 +750,6 @@
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/stack.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/stack_macros.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/thread.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/time_support.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/tls1.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/type_check.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/include/openssl/x509.h" role="src" />
@ -765,6 +758,7 @@
<file baseinstalldir="/" name="third_party/boringssl/ssl/internal.h" role="src" />
<file baseinstalldir="/" name="src/boringssl/err_data.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/aes/aes.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/aes/key_wrap.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/aes/mode_wrappers.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_bitstr.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_bool.c" role="src" />
@ -796,12 +790,12 @@
<file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/tasn_new.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/tasn_typ.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/tasn_utl.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/time_support.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/x_bignum.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/x_long.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/base64/base64.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/bio/bio.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/bio/bio_mem.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/bio/buffer.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/bio/connect.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/bio/fd.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/bio/file.c" role="src" />
@ -908,12 +902,7 @@
<file baseinstalldir="/" name="third_party/boringssl/crypto/modes/ctr.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/modes/gcm.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/modes/ofb.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/newhope/error_correction.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/newhope/newhope.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/newhope/ntt.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/newhope/poly.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/newhope/precomp.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/newhope/reduce.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/modes/polyval.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/obj/obj.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/obj/obj_xref.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/pem/pem_all.c" role="src" />
@ -924,14 +913,15 @@
<file baseinstalldir="/" name="third_party/boringssl/crypto/pem/pem_pkey.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/pem/pem_x509.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/pem/pem_xaux.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/pkcs8/p5_pbe.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/pkcs8/p5_pbev2.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/pkcs8/p8_pkey.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/pkcs8/pkcs8.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/poly1305/poly1305.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/poly1305/poly1305_arm.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/poly1305/poly1305_vec.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/pool/pool.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/rand/deterministic.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/rand/fuchsia.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/rand/rand.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/rand/urandom.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/rand/windows.c" role="src" />
@ -943,6 +933,7 @@
<file baseinstalldir="/" name="third_party/boringssl/crypto/rsa/rsa.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/rsa/rsa_asn1.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/rsa/rsa_impl.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/sha/sha1-altivec.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/sha/sha1.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/sha/sha256.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/sha/sha512.c" role="src" />
@ -951,7 +942,6 @@
<file baseinstalldir="/" name="third_party/boringssl/crypto/thread_none.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/thread_pthread.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/thread_win.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/time_support.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/x509/a_digest.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/x509/a_sign.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/x509/a_strex.c" role="src" />
@ -1035,6 +1025,7 @@
<file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_skey.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_sxnet.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_utl.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/bio_ssl.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/custom_extensions.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/d1_both.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/d1_lib.c" role="src" />
@ -1045,7 +1036,6 @@
<file baseinstalldir="/" name="third_party/boringssl/ssl/handshake_client.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/handshake_server.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/s3_both.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/s3_enc.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/s3_lib.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/s3_pkt.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_aead_ctx.c" role="src" />
@ -1056,9 +1046,12 @@
<file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_ecdh.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_file.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_lib.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_rsa.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_privkey.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_privkey_cc.cc" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_session.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_stat.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_transcript.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_x509.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/t1_enc.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/t1_lib.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/ssl/tls13_both.c" role="src" />

@ -101,9 +101,9 @@ if EXTRA_ENV_COMPILE_ARGS is None:
elif 'win32' in sys.platform:
EXTRA_ENV_COMPILE_ARGS += ' -D_PYTHON_MSVC'
elif "linux" in sys.platform:
EXTRA_ENV_COMPILE_ARGS += ' -std=c++11 -std=gnu99 -fvisibility=hidden -fno-wrapv'
EXTRA_ENV_COMPILE_ARGS += ' -std=c++11 -std=gnu99 -fvisibility=hidden -fno-wrapv -fno-exceptions'
elif "darwin" in sys.platform:
EXTRA_ENV_COMPILE_ARGS += ' -fvisibility=hidden -fno-wrapv'
EXTRA_ENV_COMPILE_ARGS += ' -fvisibility=hidden -fno-wrapv -fno-exceptions'
if EXTRA_ENV_LINK_ARGS is None:
EXTRA_ENV_LINK_ARGS = ''
@ -117,7 +117,7 @@ if EXTRA_ENV_LINK_ARGS is None:
' -static-libgcc -static-libstdc++ -mcrtdll={msvcr} '
'-static'.format(msvcr=msvcr))
if "linux" in sys.platform:
EXTRA_ENV_LINK_ARGS += ' -Wl,-wrap,memcpy'
EXTRA_ENV_LINK_ARGS += ' -Wl,-wrap,memcpy -static-libgcc'
EXTRA_COMPILE_ARGS = shlex.split(EXTRA_ENV_COMPILE_ARGS)
EXTRA_LINK_ARGS = shlex.split(EXTRA_ENV_LINK_ARGS)

@ -178,42 +178,42 @@ const uint32_t kOpenSSLReasonValues[] = {
0x28340c19,
0x283480ac,
0x283500ea,
0x2c3228ca,
0x2c32a8d8,
0x2c3328ea,
0x2c33a8fc,
0x2c342910,
0x2c34a922,
0x2c35293d,
0x2c35a94f,
0x2c362962,
0x2c3229b1,
0x2c32a9bf,
0x2c3329d1,
0x2c33a9e3,
0x2c3429f7,
0x2c34aa09,
0x2c352a24,
0x2c35aa36,
0x2c362a49,
0x2c36832d,
0x2c37296f,
0x2c37a981,
0x2c382994,
0x2c38a9ab,
0x2c3929b9,
0x2c39a9c9,
0x2c3a29db,
0x2c3aa9ef,
0x2c3b2a00,
0x2c3baa1f,
0x2c3c2a33,
0x2c3caa49,
0x2c3d2a62,
0x2c3daa7f,
0x2c3e2a90,
0x2c3eaa9e,
0x2c3f2ab6,
0x2c3faace,
0x2c402adb,
0x2c372a56,
0x2c37aa68,
0x2c382a7b,
0x2c38aa92,
0x2c392aa0,
0x2c39aab0,
0x2c3a2ac2,
0x2c3aaad6,
0x2c3b2ae7,
0x2c3bab06,
0x2c3c2b1a,
0x2c3cab30,
0x2c3d2b49,
0x2c3dab66,
0x2c3e2b77,
0x2c3eab85,
0x2c3f2b9d,
0x2c3fabb5,
0x2c402bc2,
0x2c4090e7,
0x2c412aec,
0x2c41aaff,
0x2c412bd3,
0x2c41abe6,
0x2c4210c0,
0x2c42ab10,
0x2c42abf7,
0x2c430720,
0x2c43aa11,
0x2c43aaf8,
0x30320000,
0x30328015,
0x3033001f,
@ -366,180 +366,189 @@ const uint32_t kOpenSSLReasonValues[] = {
0x403b9861,
0x403c0064,
0x403c8083,
0x403d18aa,
0x403d98c0,
0x403e18cf,
0x403e98e2,
0x403f18fc,
0x403f990a,
0x4040191f,
0x40409933,
0x40411950,
0x4041996b,
0x40421984,
0x40429997,
0x404319ab,
0x404399c3,
0x404419da,
0x403d18c1,
0x403d98d7,
0x403e18e6,
0x403e98f9,
0x403f1913,
0x403f9921,
0x40401936,
0x4040994a,
0x40411967,
0x40419982,
0x4042199b,
0x404299ae,
0x404319c2,
0x404399da,
0x404419f1,
0x404480ac,
0x404519ef,
0x40459a01,
0x40461a25,
0x40469a45,
0x40471a53,
0x40479a7a,
0x40481ab7,
0x40489ad0,
0x40491ae7,
0x40499b01,
0x404a1b18,
0x404a9b36,
0x404b1b4e,
0x404b9b65,
0x404c1b7b,
0x404c9b8d,
0x404d1bae,
0x404d9bd0,
0x404e1be4,
0x404e9bf1,
0x404f1c1e,
0x404f9c47,
0x40501c71,
0x40509c85,
0x40511ca0,
0x40519cb0,
0x40521cc7,
0x40529ceb,
0x40531d03,
0x40539d16,
0x40541d2b,
0x40549d4e,
0x40551d5c,
0x40559d79,
0x40561d86,
0x40569d9f,
0x40571db7,
0x40579dca,
0x40581ddf,
0x40589e06,
0x40591e35,
0x40599e62,
0x405a1e76,
0x405a9e86,
0x405b1e9e,
0x405b9eaf,
0x405c1ec2,
0x405c9ed3,
0x405d1ee0,
0x405d9ef7,
0x405e1f17,
0x40451a06,
0x40459a18,
0x40461a3c,
0x40469a5c,
0x40471a6a,
0x40479a91,
0x40481ace,
0x40489ae7,
0x40491afe,
0x40499b18,
0x404a1b2f,
0x404a9b4d,
0x404b1b65,
0x404b9b7c,
0x404c1b92,
0x404c9ba4,
0x404d1bc5,
0x404d9be7,
0x404e1bfb,
0x404e9c08,
0x404f1c35,
0x404f9c5e,
0x40501c99,
0x40509cad,
0x40511cc8,
0x40519cd8,
0x40521cef,
0x40529d13,
0x40531d2b,
0x40539d3e,
0x40541d53,
0x40549d76,
0x40551d84,
0x40559da1,
0x40561dae,
0x40569dc7,
0x40571ddf,
0x40579df2,
0x40581e07,
0x40589e2e,
0x40591e5d,
0x40599e8a,
0x405a1e9e,
0x405a9eae,
0x405b1ec6,
0x405b9ed7,
0x405c1eea,
0x405c9f0b,
0x405d1f18,
0x405d9f2f,
0x405e1f6d,
0x405e8a95,
0x405f1f38,
0x405f9f45,
0x40601f53,
0x40609f75,
0x40611f9d,
0x40619fb2,
0x40621fc9,
0x40629fda,
0x40631feb,
0x4063a000,
0x40642017,
0x4064a043,
0x4065205e,
0x4065a075,
0x4066208d,
0x4066a0b7,
0x406720e2,
0x4067a103,
0x40682116,
0x4068a137,
0x40692169,
0x4069a197,
0x406a21b8,
0x406aa1d8,
0x406b2360,
0x406ba383,
0x406c2399,
0x406ca5c5,
0x406d25f4,
0x406da61c,
0x406e264a,
0x406ea662,
0x406f2681,
0x406fa696,
0x407026a9,
0x4070a6c6,
0x405f1f8e,
0x405f9f9b,
0x40601fa9,
0x40609fcb,
0x4061200f,
0x4061a047,
0x4062205e,
0x4062a06f,
0x40632080,
0x4063a095,
0x406420ac,
0x4064a0d8,
0x406520f3,
0x4065a10a,
0x40662122,
0x4066a14c,
0x40672177,
0x4067a198,
0x406821ab,
0x4068a1cc,
0x406921fe,
0x4069a22c,
0x406a224d,
0x406aa26d,
0x406b23f5,
0x406ba418,
0x406c242e,
0x406ca690,
0x406d26bf,
0x406da6e7,
0x406e2715,
0x406ea749,
0x406f2768,
0x406fa77d,
0x40702790,
0x4070a7ad,
0x40710800,
0x4071a6d8,
0x407226eb,
0x4072a704,
0x4073271c,
0x4071a7bf,
0x407227d2,
0x4072a7eb,
0x40732803,
0x4073936d,
0x40742730,
0x4074a74a,
0x4075275b,
0x4075a76f,
0x4076277d,
0x40742817,
0x4074a831,
0x40752842,
0x4075a856,
0x40762864,
0x407691aa,
0x407727a2,
0x4077a7c4,
0x407827df,
0x4078a818,
0x4079282f,
0x4079a845,
0x407a2851,
0x407aa864,
0x407b2879,
0x407ba88b,
0x407c28a0,
0x407ca8a9,
0x407d2152,
0x407d9c57,
0x407e27f4,
0x407e9e16,
0x407f1a67,
0x40772889,
0x4077a8ab,
0x407828c6,
0x4078a8ff,
0x40792916,
0x4079a92c,
0x407a2938,
0x407aa94b,
0x407b2960,
0x407ba972,
0x407c2987,
0x407ca990,
0x407d21e7,
0x407d9c6e,
0x407e28db,
0x407e9e3e,
0x407f1a7e,
0x407f9887,
0x40801c2e,
0x40809a8f,
0x40811cd9,
0x40819c08,
0x40822635,
0x40801c45,
0x40809aa6,
0x40811d01,
0x40819c1f,
0x40822700,
0x4082986d,
0x40831df1,
0x4083a028,
0x40841aa3,
0x40849e4e,
0x41f4228b,
0x41f9231d,
0x41fe2210,
0x41fea3ec,
0x41ff24dd,
0x420322a4,
0x420822c6,
0x4208a302,
0x420921f4,
0x4209a33c,
0x420a224b,
0x420aa22b,
0x420b226b,
0x420ba2e4,
0x420c24f9,
0x420ca3b9,
0x420d23d3,
0x420da40a,
0x42122424,
0x421724c0,
0x4217a466,
0x421c2488,
0x421f2443,
0x42212510,
0x422624a3,
0x422b25a9,
0x422ba572,
0x422c2591,
0x422ca54c,
0x422d252b,
0x40831e19,
0x4083a0bd,
0x40841aba,
0x40849e76,
0x40851efb,
0x40859ff3,
0x40861f4f,
0x40869c88,
0x4087272d,
0x4087a024,
0x408818aa,
0x41f42320,
0x41f923b2,
0x41fe22a5,
0x41fea481,
0x41ff2572,
0x42032339,
0x4208235b,
0x4208a397,
0x42092289,
0x4209a3d1,
0x420a22e0,
0x420aa2c0,
0x420b2300,
0x420ba379,
0x420c258e,
0x420ca44e,
0x420d2468,
0x420da49f,
0x421224b9,
0x42172555,
0x4217a4fb,
0x421c251d,
0x421f24d8,
0x422125a5,
0x42262538,
0x422b2674,
0x422ba622,
0x422c265c,
0x422ca5e1,
0x422d25c0,
0x422da641,
0x422e2607,
0x4432072b,
0x4432873a,
0x44330746,
@ -582,69 +591,69 @@ const uint32_t kOpenSSLReasonValues[] = {
0x4c3d136d,
0x4c3d937c,
0x4c3e1389,
0x50322b22,
0x5032ab31,
0x50332b3c,
0x5033ab4c,
0x50342b65,
0x5034ab7f,
0x50352b8d,
0x5035aba3,
0x50362bb5,
0x5036abcb,
0x50372be4,
0x5037abf7,
0x50382c0f,
0x5038ac20,
0x50392c35,
0x5039ac49,
0x503a2c69,
0x503aac7f,
0x503b2c97,
0x503baca9,
0x503c2cc5,
0x503cacdc,
0x503d2cf5,
0x503dad0b,
0x503e2d18,
0x503ead2e,
0x503f2d40,
0x50322c09,
0x5032ac18,
0x50332c23,
0x5033ac33,
0x50342c4c,
0x5034ac66,
0x50352c74,
0x5035ac8a,
0x50362c9c,
0x5036acb2,
0x50372ccb,
0x5037acde,
0x50382cf6,
0x5038ad07,
0x50392d1c,
0x5039ad30,
0x503a2d50,
0x503aad66,
0x503b2d7e,
0x503bad90,
0x503c2dac,
0x503cadc3,
0x503d2ddc,
0x503dadf2,
0x503e2dff,
0x503eae15,
0x503f2e27,
0x503f8382,
0x50402d53,
0x5040ad63,
0x50412d7d,
0x5041ad8c,
0x50422da6,
0x5042adc3,
0x50432dd3,
0x5043ade3,
0x50442df2,
0x50402e3a,
0x5040ae4a,
0x50412e64,
0x5041ae73,
0x50422e8d,
0x5042aeaa,
0x50432eba,
0x5043aeca,
0x50442ed9,
0x5044843f,
0x50452e06,
0x5045ae24,
0x50462e37,
0x5046ae4d,
0x50472e5f,
0x5047ae74,
0x50482e9a,
0x5048aea8,
0x50492ebb,
0x5049aed0,
0x504a2ee6,
0x504aaef6,
0x504b2f16,
0x504baf29,
0x504c2f4c,
0x504caf7a,
0x504d2f8c,
0x504dafa9,
0x504e2fc4,
0x504eafe0,
0x504f2ff2,
0x504fb009,
0x50503018,
0x50452eed,
0x5045af0b,
0x50462f1e,
0x5046af34,
0x50472f46,
0x5047af5b,
0x50482f81,
0x5048af8f,
0x50492fa2,
0x5049afb7,
0x504a2fcd,
0x504aafdd,
0x504b2ffd,
0x504bb010,
0x504c3033,
0x504cb061,
0x504d3073,
0x504db090,
0x504e30ab,
0x504eb0c7,
0x504f30d9,
0x504fb0f0,
0x505030ff,
0x505086ef,
0x5051302b,
0x50513112,
0x58320ec9,
0x68320e8b,
0x68328c25,
@ -1007,6 +1016,7 @@ const char kOpenSSLReasonStringData[] =
"BIO_NOT_SET\0"
"BLOCK_CIPHER_PAD_IS_WRONG\0"
"BUFFERED_MESSAGES_ON_CIPHER_CHANGE\0"
"CANNOT_PARSE_LEAF_CERT\0"
"CA_DN_LENGTH_MISMATCH\0"
"CA_DN_TOO_LONG\0"
"CCS_RECEIVED_EARLY\0"
@ -1050,6 +1060,7 @@ const char kOpenSSLReasonStringData[] =
"INVALID_COMPRESSION_LIST\0"
"INVALID_MESSAGE\0"
"INVALID_OUTER_RECORD_TYPE\0"
"INVALID_SCT_LIST\0"
"INVALID_SSL_SESSION\0"
"INVALID_TICKET_KEYS_LENGTH\0"
"LENGTH_MISMATCH\0"
@ -1079,15 +1090,19 @@ const char kOpenSSLReasonStringData[] =
"NO_RENEGOTIATION\0"
"NO_REQUIRED_DIGEST\0"
"NO_SHARED_CIPHER\0"
"NO_SHARED_GROUP\0"
"NULL_SSL_CTX\0"
"NULL_SSL_METHOD_PASSED\0"
"OLD_SESSION_CIPHER_NOT_RETURNED\0"
"OLD_SESSION_PRF_HASH_MISMATCH\0"
"OLD_SESSION_VERSION_NOT_RETURNED\0"
"PARSE_TLSEXT\0"
"PATH_TOO_LONG\0"
"PEER_DID_NOT_RETURN_A_CERTIFICATE\0"
"PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE\0"
"PRE_SHARED_KEY_MUST_BE_LAST\0"
"PROTOCOL_IS_SHUTDOWN\0"
"PSK_IDENTITY_BINDER_COUNT_MISMATCH\0"
"PSK_IDENTITY_NOT_FOUND\0"
"PSK_NO_CLIENT_CB\0"
"PSK_NO_SERVER_CB\0"
@ -1139,7 +1154,9 @@ const char kOpenSSLReasonStringData[] =
"TLSV1_ALERT_USER_CANCELLED\0"
"TLSV1_BAD_CERTIFICATE_HASH_VALUE\0"
"TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE\0"
"TLSV1_CERTIFICATE_REQUIRED\0"
"TLSV1_CERTIFICATE_UNOBTAINABLE\0"
"TLSV1_UNKNOWN_PSK_IDENTITY\0"
"TLSV1_UNRECOGNIZED_NAME\0"
"TLSV1_UNSUPPORTED_EXTENSION\0"
"TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\0"
@ -1147,6 +1164,7 @@ const char kOpenSSLReasonStringData[] =
"TOO_MANY_EMPTY_FRAGMENTS\0"
"TOO_MANY_KEY_UPDATES\0"
"TOO_MANY_WARNING_ALERTS\0"
"TOO_MUCH_SKIPPED_EARLY_DATA\0"
"UNABLE_TO_FIND_ECDH_PARAMETERS\0"
"UNEXPECTED_EXTENSION\0"
"UNEXPECTED_MESSAGE\0"

@ -23,6 +23,8 @@
#include "src/compiler/config.h"
#include "src/compiler/generator_helpers.h"
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
namespace grpc_objective_c_generator {
using ::grpc::protobuf::FileDescriptor;
@ -30,7 +32,7 @@ using ::grpc::protobuf::ServiceDescriptor;
using ::grpc::string;
inline string MessageHeaderName(const FileDescriptor *file) {
return grpc_generator::FileNameInUpperCamel(file) + ".pbobjc.h";
return google::protobuf::compiler::objectivec::FilePath(file) + ".pbobjc.h";
}
inline string ServiceClassName(const ServiceDescriptor *service) {

@ -44,7 +44,8 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
return true;
}
::grpc::string file_name = grpc_generator::FileNameInUpperCamel(file);
::grpc::string file_name =
google::protobuf::compiler::objectivec::FilePath(file);
::grpc::string prefix = file->options().objc_class_prefix();
{

@ -52,14 +52,16 @@ void PrintMethod(const MethodDescriptor *method, Printer *out) {
vars["input_type_id"] = MessageIdentifierName(input_type->full_name());
vars["output_type_id"] = MessageIdentifierName(output_type->full_name());
out->Print(GetPHPComments(method, " //").c_str());
out->Print("/**\n");
out->Print(GetPHPComments(method, " *").c_str());
if (method->client_streaming()) {
out->Print(vars,
" // @param array $$metadata metadata\n"
" // @param array $$options call options\n"
" * @param array $$metadata metadata\n"
" * @param array $$options call options\n */\n"
"public function $name$($$metadata = [], "
"$$options = []) {\n");
out->Indent();
out->Indent();
if (method->server_streaming()) {
out->Print("return $$this->_bidiRequest(");
} else {
@ -71,12 +73,13 @@ void PrintMethod(const MethodDescriptor *method, Printer *out) {
"$$metadata, $$options);\n");
} else {
out->Print(vars,
" // @param \\$input_type_id$ $$argument input argument\n"
" // @param array $$metadata metadata\n"
" // @param array $$options call options\n"
" * @param \\$input_type_id$ $$argument input argument\n"
" * @param array $$metadata metadata\n"
" * @param array $$options call options\n */\n"
"public function $name$(\\$input_type_id$ $$argument,\n"
" $$metadata = [], $$options = []) {\n");
out->Indent();
out->Indent();
if (method->server_streaming()) {
out->Print("return $$this->_serverStreamRequest(");
} else {
@ -89,26 +92,32 @@ void PrintMethod(const MethodDescriptor *method, Printer *out) {
"$$metadata, $$options);\n");
}
out->Outdent();
out->Outdent();
out->Print("}\n\n");
}
// Prints out the service descriptor object
void PrintService(const ServiceDescriptor *service, Printer *out) {
map<grpc::string, grpc::string> vars;
out->Print(GetPHPComments(service, "//").c_str());
out->Print("/**\n");
out->Print(GetPHPComments(service, " *").c_str());
out->Print(" */\n");
vars["name"] = service->name();
out->Print(vars, "class $name$Client extends \\Grpc\\BaseStub {\n\n");
out->Indent();
out->Indent();
out->Print(
" // @param string $$hostname hostname\n"
" // @param array $$opts channel options\n"
" // @param \\Grpc\\Channel $$channel (optional) re-use channel "
"object\n"
"/**\n * @param string $$hostname hostname\n"
" * @param array $$opts channel options\n"
" * @param \\Grpc\\Channel $$channel (optional) re-use channel "
"object\n */\n"
"public function __construct($$hostname, $$opts, "
"$$channel = null) {\n");
out->Indent();
out->Indent();
out->Print("parent::__construct($$hostname, $$opts, $$channel);\n");
out->Outdent();
out->Outdent();
out->Print("}\n\n");
for (int i = 0; i < service->method_count(); i++) {
grpc::string method_name =
@ -116,7 +125,8 @@ void PrintService(const ServiceDescriptor *service, Printer *out) {
PrintMethod(service->method(i), out);
}
out->Outdent();
out->Print("}\n\n");
out->Outdent();
out->Print("}\n");
}
}
@ -138,13 +148,9 @@ grpc::string GenerateFile(const FileDescriptor *file,
map<grpc::string, grpc::string> vars;
vars["package"] = MessageIdentifierName(file->package());
out.Print(vars, "namespace $package$ {\n\n");
out.Indent();
out.Print(vars, "namespace $package$;\n\n");
PrintService(service, &out);
out.Outdent();
out.Print("}\n");
}
return output;
}

@ -39,12 +39,24 @@ inline grpc::string GetPHPServiceFilename(
return oss.str() + "/" + service->name() + "Client.php";
}
// ReplaceAll replaces all instances of search with replace in s.
inline grpc::string ReplaceAll(grpc::string s, const grpc::string &search,
const grpc::string &replace) {
size_t pos = 0;
while ((pos = s.find(search, pos)) != grpc::string::npos) {
s.replace(pos, search.length(), replace);
pos += replace.length();
}
return s;
}
// Get leading or trailing comments in a string. Comment lines start with "// ".
// Leading detached comments are put in in front of leading comments.
template <typename DescriptorType>
inline grpc::string GetPHPComments(const DescriptorType *desc,
grpc::string prefix) {
return grpc_generator::GetPrefixedComments(desc, true, prefix);
return ReplaceAll(grpc_generator::GetPrefixedComments(desc, true, prefix),
"*/", "&#42;/");
}
} // namespace grpc_php_generator

@ -756,6 +756,7 @@ bool PythonGrpcGenerator::Generate(const FileDescriptor* file,
file->name().find_last_of(".proto") == file->name().size() - 1) {
grpc::string base =
file->name().substr(0, file->name().size() - proto_suffix_length);
std::replace(base.begin(), base.end(), '-', '_');
pb2_file_name = base + "_pb2.py";
pb2_grpc_file_name = base + "_pb2_grpc.py";
} else {

@ -141,7 +141,7 @@ static grpc_error *server_init_call_elem(grpc_exec_ctx *exec_ctx,
memset(d, 0, sizeof(*d));
d->start_ts = args->start_time;
/* TODO(hongyu): call census_tracing_start_op here. */
grpc_closure_init(&d->finish_recv, server_on_done_recv, elem,
GRPC_CLOSURE_INIT(&d->finish_recv, server_on_done_recv, elem,
grpc_schedule_on_exec_ctx);
return GRPC_ERROR_NONE;
}

@ -211,9 +211,9 @@ void grpc_channel_watch_connectivity_state(
grpc_cq_begin_op(cq, tag);
gpr_mu_init(&w->mu);
grpc_closure_init(&w->on_complete, watch_complete, w,
GRPC_CLOSURE_INIT(&w->on_complete, watch_complete, w,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&w->on_timeout, timeout_complete, w,
GRPC_CLOSURE_INIT(&w->on_timeout, timeout_complete, w,
grpc_schedule_on_exec_ctx);
w->phase = WAITING;
w->state = last_observed_state;
@ -225,7 +225,7 @@ void grpc_channel_watch_connectivity_state(
watcher_timer_init_arg *wa = gpr_malloc(sizeof(watcher_timer_init_arg));
wa->w = w;
wa->deadline = deadline;
grpc_closure_init(&w->watcher_timer_init, watcher_timer_init, wa,
GRPC_CLOSURE_INIT(&w->watcher_timer_init, watcher_timer_init, wa,
grpc_schedule_on_exec_ctx);
if (client_channel_elem->filter == &grpc_client_channel_filter) {

File diff suppressed because it is too large Load Diff

@ -17,6 +17,7 @@
*/
#include "src/core/ext/filters/client_channel/client_channel_factory.h"
#include "src/core/lib/channel/channel_args.h"
void grpc_client_channel_factory_ref(grpc_client_channel_factory* factory) {
factory->vtable->ref(factory);
@ -63,10 +64,6 @@ static const grpc_arg_pointer_vtable factory_arg_vtable = {
grpc_arg grpc_client_channel_factory_create_channel_arg(
grpc_client_channel_factory* factory) {
grpc_arg arg;
arg.type = GRPC_ARG_POINTER;
arg.key = GRPC_ARG_CLIENT_CHANNEL_FACTORY;
arg.value.pointer.p = factory;
arg.value.pointer.vtable = &factory_arg_vtable;
return arg;
return grpc_channel_arg_pointer_create(GRPC_ARG_CLIENT_CHANNEL_FACTORY,
factory, &factory_arg_vtable);
}

@ -54,10 +54,8 @@ static bool set_default_host_if_unset(grpc_exec_ctx *exec_ctx,
char *default_authority = grpc_get_default_authority(
exec_ctx, grpc_channel_stack_builder_get_target(builder));
if (default_authority != NULL) {
grpc_arg arg;
arg.type = GRPC_ARG_STRING;
arg.key = GRPC_ARG_DEFAULT_AUTHORITY;
arg.value.string = default_authority;
grpc_arg arg = grpc_channel_arg_string_create(GRPC_ARG_DEFAULT_AUTHORITY,
default_authority);
grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
grpc_channel_stack_builder_set_channel_arguments(exec_ctx, builder,
new_args);
@ -80,6 +78,9 @@ void grpc_client_channel_init(void) {
GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, append_filter,
(void *)&grpc_client_channel_filter);
grpc_http_connect_register_handshaker_factory();
#ifndef NDEBUG
grpc_register_tracer("resolver_refcount", &grpc_trace_resolver_refcount);
#endif
}
void grpc_client_channel_shutdown(void) {

@ -118,7 +118,7 @@ static void handshake_failed_locked(grpc_exec_ctx* exec_ctx,
handshaker->shutdown = true;
}
// Invoke callback.
grpc_closure_sched(exec_ctx, handshaker->on_handshake_done, error);
GRPC_CLOSURE_SCHED(exec_ctx, handshaker->on_handshake_done, error);
}
// Callback invoked when finished writing HTTP CONNECT request.
@ -217,7 +217,7 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
goto done;
}
// Success. Invoke handshake-done callback.
grpc_closure_sched(exec_ctx, handshaker->on_handshake_done, error);
GRPC_CLOSURE_SCHED(exec_ctx, handshaker->on_handshake_done, error);
done:
// Set shutdown to true so that subsequent calls to
// http_connect_handshaker_shutdown() do nothing.
@ -266,7 +266,7 @@ static void http_connect_handshaker_do_handshake(
gpr_mu_lock(&handshaker->mu);
handshaker->shutdown = true;
gpr_mu_unlock(&handshaker->mu);
grpc_closure_sched(exec_ctx, on_handshake_done, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, on_handshake_done, GRPC_ERROR_NONE);
return;
}
GPR_ASSERT(arg->type == GRPC_ARG_STRING);
@ -339,9 +339,9 @@ static grpc_handshaker* grpc_http_connect_handshaker_create() {
gpr_mu_init(&handshaker->mu);
gpr_ref_init(&handshaker->refcount, 1);
grpc_slice_buffer_init(&handshaker->write_buffer);
grpc_closure_init(&handshaker->request_done_closure, on_write_done,
GRPC_CLOSURE_INIT(&handshaker->request_done_closure, on_write_done,
handshaker, grpc_schedule_on_exec_ctx);
grpc_closure_init(&handshaker->response_read_closure, on_read_done,
GRPC_CLOSURE_INIT(&handshaker->response_read_closure, on_read_done,
handshaker, grpc_schedule_on_exec_ctx);
grpc_http_parser_init(&handshaker->http_parser, GRPC_HTTP_RESPONSE,
&handshaker->http_response);

@ -80,10 +80,9 @@ static bool proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
grpc_uri_destroy(uri);
return false;
}
grpc_arg new_arg;
new_arg.key = GRPC_ARG_HTTP_CONNECT_SERVER;
new_arg.type = GRPC_ARG_STRING;
new_arg.value.string = uri->path[0] == '/' ? uri->path + 1 : uri->path;
grpc_arg new_arg = grpc_channel_arg_string_create(
GRPC_ARG_HTTP_CONNECT_SERVER,
uri->path[0] == '/' ? uri->path + 1 : uri->path);
*new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1);
grpc_uri_destroy(uri);
return true;

@ -21,6 +21,10 @@
#define WEAK_REF_BITS 16
#ifndef NDEBUG
grpc_tracer_flag grpc_trace_lb_policy_refcount = GRPC_TRACER_INITIALIZER(false);
#endif
void grpc_lb_policy_init(grpc_lb_policy *policy,
const grpc_lb_policy_vtable *vtable,
grpc_combiner *combiner) {
@ -30,7 +34,7 @@ void grpc_lb_policy_init(grpc_lb_policy *policy,
policy->combiner = GRPC_COMBINER_REF(combiner, "lb_policy");
}
#ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG
#ifndef NDEBUG
#define REF_FUNC_EXTRA_ARGS , const char *file, int line, const char *reason
#define REF_MUTATE_EXTRA_ARGS REF_FUNC_EXTRA_ARGS, const char *purpose
#define REF_FUNC_PASS_ARGS(new_reason) , file, line, new_reason
@ -46,11 +50,12 @@ static gpr_atm ref_mutate(grpc_lb_policy *c, gpr_atm delta,
int barrier REF_MUTATE_EXTRA_ARGS) {
gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta)
: gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta);
#ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"LB_POLICY: 0x%" PRIxPTR " %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR
" [%s]",
(intptr_t)c, purpose, old_val, old_val + delta, reason);
#ifndef NDEBUG
if (GRPC_TRACER_ON(grpc_trace_lb_policy_refcount)) {
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"LB_POLICY: 0x%p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", c,
purpose, old_val, old_val + delta, reason);
}
#endif
return old_val;
}
@ -74,11 +79,10 @@ void grpc_lb_policy_unref(grpc_exec_ctx *exec_ctx,
gpr_atm mask = ~(gpr_atm)((1 << WEAK_REF_BITS) - 1);
gpr_atm check = 1 << WEAK_REF_BITS;
if ((old_val & mask) == check) {
grpc_closure_sched(
exec_ctx,
grpc_closure_create(shutdown_locked, policy,
grpc_combiner_scheduler(policy->combiner, false)),
GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, GRPC_CLOSURE_CREATE(
shutdown_locked, policy,
grpc_combiner_scheduler(policy->combiner)),
GRPC_ERROR_NONE);
} else {
grpc_lb_policy_weak_unref(exec_ctx,
policy REF_FUNC_PASS_ARGS("strong-unref"));

@ -29,6 +29,10 @@ typedef struct grpc_lb_policy grpc_lb_policy;
typedef struct grpc_lb_policy_vtable grpc_lb_policy_vtable;
typedef struct grpc_lb_policy_args grpc_lb_policy_args;
#ifndef NDEBUG
extern grpc_tracer_flag grpc_trace_lb_policy_refcount;
#endif
struct grpc_lb_policy {
const grpc_lb_policy_vtable *vtable;
gpr_atm ref_pair;
@ -96,8 +100,7 @@ struct grpc_lb_policy_vtable {
const grpc_lb_policy_args *args);
};
//#define GRPC_LB_POLICY_REFCOUNT_DEBUG
#ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG
#ifndef NDEBUG
/* Strong references: the policy will shutdown when they reach zero */
#define GRPC_LB_POLICY_REF(p, r) \

@ -53,7 +53,7 @@ static void on_complete_for_send(grpc_exec_ctx *exec_ctx, void *arg,
if (error == GRPC_ERROR_NONE) {
calld->send_initial_metadata_succeeded = true;
}
grpc_closure_run(exec_ctx, calld->original_on_complete_for_send,
GRPC_CLOSURE_RUN(exec_ctx, calld->original_on_complete_for_send,
GRPC_ERROR_REF(error));
}
@ -63,7 +63,7 @@ static void recv_initial_metadata_ready(grpc_exec_ctx *exec_ctx, void *arg,
if (error == GRPC_ERROR_NONE) {
calld->recv_initial_metadata_succeeded = true;
}
grpc_closure_run(exec_ctx, calld->original_recv_initial_metadata_ready,
GRPC_CLOSURE_RUN(exec_ctx, calld->original_recv_initial_metadata_ready,
GRPC_ERROR_REF(error));
}
@ -104,7 +104,7 @@ static void start_transport_stream_op_batch(
// Intercept send_initial_metadata.
if (batch->send_initial_metadata) {
calld->original_on_complete_for_send = batch->on_complete;
grpc_closure_init(&calld->on_complete_for_send, on_complete_for_send, calld,
GRPC_CLOSURE_INIT(&calld->on_complete_for_send, on_complete_for_send, calld,
grpc_schedule_on_exec_ctx);
batch->on_complete = &calld->on_complete_for_send;
}
@ -112,7 +112,7 @@ static void start_transport_stream_op_batch(
if (batch->recv_initial_metadata) {
calld->original_recv_initial_metadata_ready =
batch->payload->recv_initial_metadata.recv_initial_metadata_ready;
grpc_closure_init(&calld->recv_initial_metadata_ready,
GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready,
recv_initial_metadata_ready, calld,
grpc_schedule_on_exec_ctx);
batch->payload->recv_initial_metadata.recv_initial_metadata_ready =

@ -184,7 +184,7 @@ static void wrapped_rr_closure(grpc_exec_ctx *exec_ctx, void *arg,
wrapped_rr_closure_arg *wc_arg = arg;
GPR_ASSERT(wc_arg->wrapped_closure != NULL);
grpc_closure_sched(exec_ctx, wc_arg->wrapped_closure, GRPC_ERROR_REF(error));
GRPC_CLOSURE_SCHED(exec_ctx, wc_arg->wrapped_closure, GRPC_ERROR_REF(error));
if (wc_arg->rr_policy != NULL) {
/* if *target is NULL, no pick has been made by the RR policy (eg, all
@ -256,7 +256,7 @@ static void add_pending_pick(pending_pick **root,
pp->wrapped_on_complete_arg.lb_token_mdelem_storage =
pick_args->lb_token_mdelem_storage;
pp->wrapped_on_complete_arg.free_when_done = pp;
grpc_closure_init(&pp->wrapped_on_complete_arg.wrapper_closure,
GRPC_CLOSURE_INIT(&pp->wrapped_on_complete_arg.wrapper_closure,
wrapped_rr_closure, &pp->wrapped_on_complete_arg,
grpc_schedule_on_exec_ctx);
*root = pp;
@ -275,7 +275,7 @@ static void add_pending_ping(pending_ping **root, grpc_closure *notify) {
pping->wrapped_notify_arg.wrapped_closure = notify;
pping->wrapped_notify_arg.free_when_done = pping;
pping->next = *root;
grpc_closure_init(&pping->wrapped_notify_arg.wrapper_closure,
GRPC_CLOSURE_INIT(&pping->wrapped_notify_arg.wrapper_closure,
wrapped_rr_closure, &pping->wrapped_notify_arg,
grpc_schedule_on_exec_ctx);
*root = pping;
@ -635,7 +635,7 @@ static bool pick_from_internal_rr_locked(
grpc_grpclb_client_stats_unref(wc_arg->client_stats);
if (force_async) {
GPR_ASSERT(wc_arg->wrapped_closure != NULL);
grpc_closure_sched(exec_ctx, wc_arg->wrapped_closure, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, wc_arg->wrapped_closure, GRPC_ERROR_NONE);
gpr_free(wc_arg->free_when_done);
return false;
}
@ -663,7 +663,7 @@ static bool pick_from_internal_rr_locked(
wc_arg->context[GRPC_GRPCLB_CLIENT_STATS].destroy = destroy_client_stats;
if (force_async) {
GPR_ASSERT(wc_arg->wrapped_closure != NULL);
grpc_closure_sched(exec_ctx, wc_arg->wrapped_closure, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, wc_arg->wrapped_closure, GRPC_ERROR_NONE);
gpr_free(wc_arg->free_when_done);
return false;
}
@ -739,9 +739,9 @@ static void create_rr_locked(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy,
* It'll be deallocated in glb_rr_connectivity_changed() */
rr_connectivity_data *rr_connectivity =
gpr_zalloc(sizeof(rr_connectivity_data));
grpc_closure_init(&rr_connectivity->on_change,
GRPC_CLOSURE_INIT(&rr_connectivity->on_change,
glb_rr_connectivity_changed_locked, rr_connectivity,
grpc_combiner_scheduler(glb_policy->base.combiner, false));
grpc_combiner_scheduler(glb_policy->base.combiner));
rr_connectivity->glb_policy = glb_policy;
rr_connectivity->state = rr_state;
@ -974,10 +974,8 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
// Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
// since we use this to trigger the client_load_reporting filter.
grpc_arg new_arg;
new_arg.key = GRPC_ARG_LB_POLICY_NAME;
new_arg.type = GRPC_ARG_STRING;
new_arg.value.string = "grpclb";
grpc_arg new_arg =
grpc_channel_arg_string_create(GRPC_ARG_LB_POLICY_NAME, "grpclb");
static const char *args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
glb_policy->args = grpc_channel_args_copy_and_add_and_remove(
args->args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1);
@ -1004,9 +1002,9 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
return NULL;
}
grpc_closure_init(&glb_policy->lb_channel_on_connectivity_changed,
GRPC_CLOSURE_INIT(&glb_policy->lb_channel_on_connectivity_changed,
glb_lb_channel_on_connectivity_changed_cb, glb_policy,
grpc_combiner_scheduler(args->combiner, false));
grpc_combiner_scheduler(args->combiner));
grpc_lb_policy_init(&glb_policy->base, &glb_lb_policy_vtable, args->combiner);
grpc_connectivity_state_init(&glb_policy->state_tracker, GRPC_CHANNEL_IDLE,
"grpclb");
@ -1078,14 +1076,14 @@ static void glb_shutdown_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
while (pp != NULL) {
pending_pick *next = pp->next;
*pp->target = NULL;
grpc_closure_sched(exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
GRPC_CLOSURE_SCHED(exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
GRPC_ERROR_NONE);
pp = next;
}
while (pping != NULL) {
pending_ping *next = pping->next;
grpc_closure_sched(exec_ctx, &pping->wrapped_notify_arg.wrapper_closure,
GRPC_CLOSURE_SCHED(exec_ctx, &pping->wrapped_notify_arg.wrapper_closure,
GRPC_ERROR_NONE);
pping = next;
}
@ -1101,7 +1099,7 @@ static void glb_cancel_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
pending_pick *next = pp->next;
if (pp->target == target) {
*target = NULL;
grpc_closure_sched(exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
GRPC_CLOSURE_SCHED(exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Pick Cancelled", &error, 1));
} else {
@ -1125,7 +1123,7 @@ static void glb_cancel_picks_locked(grpc_exec_ctx *exec_ctx,
pending_pick *next = pp->next;
if ((pp->pick_args.initial_metadata_flags & initial_metadata_flags_mask) ==
initial_metadata_flags_eq) {
grpc_closure_sched(exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
GRPC_CLOSURE_SCHED(exec_ctx, &pp->wrapped_on_complete_arg.wrapper_closure,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Pick Cancelled", &error, 1));
} else {
@ -1160,7 +1158,7 @@ static int glb_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
grpc_closure *on_complete) {
if (pick_args->lb_token_mdelem_storage == NULL) {
*target = NULL;
grpc_closure_sched(exec_ctx, on_complete,
GRPC_CLOSURE_SCHED(exec_ctx, on_complete,
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"No mdelem storage for the LB token. Load reporting "
"won't work without it. Failing"));
@ -1179,7 +1177,7 @@ static int glb_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
wrapped_rr_closure_arg *wc_arg = gpr_zalloc(sizeof(wrapped_rr_closure_arg));
grpc_closure_init(&wc_arg->wrapper_closure, wrapped_rr_closure, wc_arg,
GRPC_CLOSURE_INIT(&wc_arg->wrapper_closure, wrapped_rr_closure, wc_arg,
grpc_schedule_on_exec_ctx);
wc_arg->rr_policy = glb_policy->rr_policy;
wc_arg->target = target;
@ -1250,9 +1248,9 @@ static void schedule_next_client_load_report(grpc_exec_ctx *exec_ctx,
const gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
const gpr_timespec next_client_load_report_time =
gpr_time_add(now, glb_policy->client_stats_report_interval);
grpc_closure_init(&glb_policy->client_load_report_closure,
GRPC_CLOSURE_INIT(&glb_policy->client_load_report_closure,
send_client_load_report_locked, glb_policy,
grpc_combiner_scheduler(glb_policy->base.combiner, false));
grpc_combiner_scheduler(glb_policy->base.combiner));
grpc_timer_init(exec_ctx, &glb_policy->client_load_report_timer,
next_client_load_report_time,
&glb_policy->client_load_report_closure, now);
@ -1278,9 +1276,9 @@ static void do_send_client_load_report_locked(grpc_exec_ctx *exec_ctx,
memset(&op, 0, sizeof(op));
op.op = GRPC_OP_SEND_MESSAGE;
op.data.send_message.send_message = glb_policy->client_load_report_payload;
grpc_closure_init(&glb_policy->client_load_report_closure,
GRPC_CLOSURE_INIT(&glb_policy->client_load_report_closure,
client_load_report_done_locked, glb_policy,
grpc_combiner_scheduler(glb_policy->base.combiner, false));
grpc_combiner_scheduler(glb_policy->base.combiner));
grpc_call_error call_error = grpc_call_start_batch_and_execute(
exec_ctx, glb_policy->lb_call, &op, 1,
&glb_policy->client_load_report_closure);
@ -1384,15 +1382,15 @@ static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
grpc_slice_unref_internal(exec_ctx, request_payload_slice);
grpc_grpclb_request_destroy(request);
grpc_closure_init(&glb_policy->lb_on_sent_initial_request,
GRPC_CLOSURE_INIT(&glb_policy->lb_on_sent_initial_request,
lb_on_sent_initial_request_locked, glb_policy,
grpc_combiner_scheduler(glb_policy->base.combiner, false));
grpc_closure_init(&glb_policy->lb_on_server_status_received,
grpc_combiner_scheduler(glb_policy->base.combiner));
GRPC_CLOSURE_INIT(&glb_policy->lb_on_server_status_received,
lb_on_server_status_received_locked, glb_policy,
grpc_combiner_scheduler(glb_policy->base.combiner, false));
grpc_closure_init(&glb_policy->lb_on_response_received,
grpc_combiner_scheduler(glb_policy->base.combiner));
GRPC_CLOSURE_INIT(&glb_policy->lb_on_response_received,
lb_on_response_received_locked, glb_policy,
grpc_combiner_scheduler(glb_policy->base.combiner, false));
grpc_combiner_scheduler(glb_policy->base.combiner));
gpr_backoff_init(&glb_policy->lb_call_backoff_state,
GRPC_GRPCLB_INITIAL_CONNECT_BACKOFF_SECONDS,
@ -1693,9 +1691,9 @@ static void lb_on_server_status_received_locked(grpc_exec_ctx *exec_ctx,
}
}
GRPC_LB_POLICY_WEAK_REF(&glb_policy->base, "grpclb_retry_timer");
grpc_closure_init(
&glb_policy->lb_on_call_retry, lb_call_on_retry_timer_locked,
glb_policy, grpc_combiner_scheduler(glb_policy->base.combiner, false));
GRPC_CLOSURE_INIT(&glb_policy->lb_on_call_retry,
lb_call_on_retry_timer_locked, glb_policy,
grpc_combiner_scheduler(glb_policy->base.combiner));
glb_policy->retry_timer_active = true;
grpc_timer_init(exec_ctx, &glb_policy->lb_call_retry_timer, next_try,
&glb_policy->lb_on_call_retry, now);
@ -1882,6 +1880,9 @@ static bool maybe_add_client_load_reporting_filter(
void grpc_lb_policy_grpclb_init() {
grpc_register_lb_policy(grpc_glb_lb_factory_create());
grpc_register_tracer("glb", &grpc_lb_glb_trace);
#ifndef NDEBUG
grpc_register_tracer("lb_policy_refcount", &grpc_trace_lb_policy_refcount);
#endif
grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL,
GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
maybe_add_client_load_reporting_filter,

@ -95,6 +95,9 @@ static void pf_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
gpr_free(p->subchannels);
gpr_free(p->new_subchannels);
gpr_free(p);
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
gpr_log(GPR_DEBUG, "Pick First %p destroyed.", (void *)p);
}
}
static void pf_shutdown_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
@ -118,7 +121,7 @@ static void pf_shutdown_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
while (pp != NULL) {
pending_pick *next = pp->next;
*pp->target = NULL;
grpc_closure_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
gpr_free(pp);
pp = next;
}
@ -135,7 +138,7 @@ static void pf_cancel_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
pending_pick *next = pp->next;
if (pp->target == target) {
*target = NULL;
grpc_closure_sched(exec_ctx, pp->on_complete,
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Pick Cancelled", &error, 1));
gpr_free(pp);
@ -160,7 +163,7 @@ static void pf_cancel_picks_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
pending_pick *next = pp->next;
if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
initial_metadata_flags_eq) {
grpc_closure_sched(exec_ctx, pp->on_complete,
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Pick Cancelled", &error, 1));
gpr_free(pp);
@ -258,7 +261,7 @@ static void pf_ping_one_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
if (p->selected) {
grpc_connected_subchannel_ping(exec_ctx, p->selected, closure);
} else {
grpc_closure_sched(exec_ctx, closure,
GRPC_CLOSURE_SCHED(exec_ctx, closure,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Not connected"));
}
}
@ -268,11 +271,20 @@ static void stop_connectivity_watchers(grpc_exec_ctx *exec_ctx,
pick_first_lb_policy *p) {
if (p->num_subchannels > 0) {
GPR_ASSERT(p->selected == NULL);
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
gpr_log(GPR_DEBUG, "Pick First %p unsubscribing from subchannel %p",
(void *)p, (void *)p->subchannels[p->checking_subchannel]);
}
grpc_subchannel_notify_on_state_change(
exec_ctx, p->subchannels[p->checking_subchannel], NULL, NULL,
&p->connectivity_changed);
p->updating_subchannels = true;
} else if (p->selected != NULL) {
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
gpr_log(GPR_DEBUG,
"Pick First %p unsubscribing from selected subchannel %p",
(void *)p, (void *)p->selected);
}
grpc_connected_subchannel_notify_on_state_change(
exec_ctx, p->selected, NULL, NULL, &p->connectivity_changed);
p->updating_selected = true;
@ -451,12 +463,25 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_subchannel *selected_subchannel;
pending_pick *pp;
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
gpr_log(
GPR_DEBUG,
"Pick First %p connectivity changed. Updating selected: %d; Updating "
"subchannels: %d; Checking %lu index (%lu total); State: %d; ",
(void *)p, p->updating_selected, p->updating_subchannels,
(unsigned long)p->checking_subchannel,
(unsigned long)p->num_subchannels, p->checking_connectivity);
}
bool restart = false;
if (p->updating_selected && error == GRPC_ERROR_CANCELLED) {
if (p->updating_selected && error != GRPC_ERROR_NONE) {
/* Captured the unsubscription for p->selected */
GPR_ASSERT(p->selected != NULL);
GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, p->selected,
"pf_update_connectivity");
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
gpr_log(GPR_DEBUG, "Pick First %p unreffing selected subchannel %p",
(void *)p, (void *)p->selected);
}
p->updating_selected = false;
if (p->num_new_subchannels == 0) {
p->selected = NULL;
@ -464,12 +489,16 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
}
restart = true;
}
if (p->updating_subchannels && error == GRPC_ERROR_CANCELLED) {
if (p->updating_subchannels && error != GRPC_ERROR_NONE) {
/* Captured the unsubscription for the checking subchannel */
GPR_ASSERT(p->selected == NULL);
for (size_t i = 0; i < p->num_subchannels; i++) {
GRPC_SUBCHANNEL_UNREF(exec_ctx, p->subchannels[i],
"pf_update_connectivity");
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
gpr_log(GPR_DEBUG, "Pick First %p unreffing subchannel %p", (void *)p,
(void *)p->subchannels[i]);
}
}
gpr_free(p->subchannels);
p->subchannels = NULL;
@ -481,14 +510,12 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
if (restart) {
p->selected = NULL;
p->selected_key = NULL;
GPR_ASSERT(p->new_subchannels != NULL);
GPR_ASSERT(p->num_new_subchannels > 0);
p->num_subchannels = p->num_new_subchannels;
p->subchannels = p->new_subchannels;
p->num_new_subchannels = 0;
p->new_subchannels = NULL;
if (p->started_picking) {
/* If we were picking, continue to do so over the new subchannels,
* starting from the 0th index. */
@ -542,7 +569,9 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
"picked_first");
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
gpr_log(GPR_INFO, "Selected subchannel %p", (void *)p->selected);
gpr_log(GPR_INFO,
"Pick First %p selected subchannel %p (connected %p)",
(void *)p, (void *)selected_subchannel, (void *)p->selected);
}
p->selected_key = grpc_subchannel_get_key(selected_subchannel);
/* drop the pick list: we are connected now */
@ -557,7 +586,7 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
"Servicing pending pick with selected subchannel %p",
(void *)p->selected);
}
grpc_closure_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
gpr_free(pp);
}
grpc_connected_subchannel_notify_on_state_change(
@ -568,7 +597,8 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
p->checking_subchannel =
(p->checking_subchannel + 1) % p->num_subchannels;
if (p->checking_subchannel == 0) {
/* only trigger transient failure when we've tried all alternatives */
/* only trigger transient failure when we've tried all alternatives
*/
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "connecting_transient_failure");
@ -610,7 +640,7 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
while ((pp = p->pending_picks)) {
p->pending_picks = pp->next;
*pp->target = NULL;
grpc_closure_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
gpr_free(pp);
}
GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base,
@ -652,10 +682,13 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
grpc_lb_policy_args *args) {
GPR_ASSERT(args->client_channel_factory != NULL);
pick_first_lb_policy *p = gpr_zalloc(sizeof(*p));
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
gpr_log(GPR_DEBUG, "Pick First %p created.", (void *)p);
}
pf_update_locked(exec_ctx, &p->base, args);
grpc_lb_policy_init(&p->base, &pick_first_lb_policy_vtable, args->combiner);
grpc_closure_init(&p->connectivity_changed, pf_connectivity_changed_locked, p,
grpc_combiner_scheduler(args->combiner, false));
GRPC_CLOSURE_INIT(&p->connectivity_changed, pf_connectivity_changed_locked, p,
grpc_combiner_scheduler(args->combiner));
return &p->base;
}

@ -126,6 +126,8 @@ struct rr_subchannel_list {
size_t num_ready;
/** how many subchannels are in state TRANSIENT_FAILURE */
size_t num_transient_failures;
/** how many subchannels are in state SHUTDOWN */
size_t num_shutdown;
/** how many subchannels are in state IDLE */
size_t num_idle;
@ -288,7 +290,7 @@ static void rr_shutdown_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
while ((pp = p->pending_picks)) {
p->pending_picks = pp->next;
*pp->target = NULL;
grpc_closure_sched(
GRPC_CLOSURE_SCHED(
exec_ctx, pp->on_complete,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel Shutdown"));
gpr_free(pp);
@ -311,7 +313,7 @@ static void rr_cancel_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
pending_pick *next = pp->next;
if (pp->target == target) {
*target = NULL;
grpc_closure_sched(exec_ctx, pp->on_complete,
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Pick cancelled", &error, 1));
gpr_free(pp);
@ -336,7 +338,7 @@ static void rr_cancel_picks_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
initial_metadata_flags_eq) {
*pp->target = NULL;
grpc_closure_sched(exec_ctx, pp->on_complete,
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Pick cancelled", &error, 1));
gpr_free(pp);
@ -425,6 +427,9 @@ static void update_state_counters_locked(subchannel_data *sd) {
} else if (sd->prev_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
GPR_ASSERT(subchannel_list->num_transient_failures > 0);
--subchannel_list->num_transient_failures;
} else if (sd->prev_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
GPR_ASSERT(subchannel_list->num_shutdown > 0);
--subchannel_list->num_shutdown;
} else if (sd->prev_connectivity_state == GRPC_CHANNEL_IDLE) {
GPR_ASSERT(subchannel_list->num_idle > 0);
--subchannel_list->num_idle;
@ -433,6 +438,8 @@ static void update_state_counters_locked(subchannel_data *sd) {
++subchannel_list->num_ready;
} else if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
++subchannel_list->num_transient_failures;
} else if (sd->curr_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
++subchannel_list->num_shutdown;
} else if (sd->curr_connectivity_state == GRPC_CHANNEL_IDLE) {
++subchannel_list->num_idle;
}
@ -455,7 +462,8 @@ static grpc_connectivity_state update_lb_connectivity_status_locked(
* CHECK: sd->curr_connectivity_state == CONNECTING.
*
* 3) RULE: ALL subchannels are SHUTDOWN => policy is SHUTDOWN.
* CHECK: p->subchannel_list->num_subchannels = 0.
* CHECK: p->subchannel_list->num_shutdown ==
* p->subchannel_list->num_subchannels.
*
* 4) RULE: ALL subchannels are TRANSIENT_FAILURE => policy is
* TRANSIENT_FAILURE.
@ -464,37 +472,39 @@ static grpc_connectivity_state update_lb_connectivity_status_locked(
* 5) RULE: ALL subchannels are IDLE => policy is IDLE.
* CHECK: p->num_idle == p->subchannel_list->num_subchannels.
*/
grpc_connectivity_state new_state = sd->curr_connectivity_state;
rr_subchannel_list *subchannel_list = sd->subchannel_list;
round_robin_lb_policy *p = subchannel_list->policy;
if (subchannel_list->num_ready > 0) { /* 1) READY */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "rr_ready");
return GRPC_CHANNEL_READY;
new_state = GRPC_CHANNEL_READY;
} else if (sd->curr_connectivity_state ==
GRPC_CHANNEL_CONNECTING) { /* 2) CONNECTING */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
"rr_connecting");
return GRPC_CHANNEL_CONNECTING;
} else if (p->subchannel_list->num_subchannels == 0) { /* 3) SHUTDOWN */
new_state = GRPC_CHANNEL_CONNECTING;
} else if (p->subchannel_list->num_shutdown ==
p->subchannel_list->num_subchannels) { /* 3) SHUTDOWN */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error),
"rr_shutdown");
return GRPC_CHANNEL_SHUTDOWN;
new_state = GRPC_CHANNEL_SHUTDOWN;
} else if (subchannel_list->num_transient_failures ==
p->subchannel_list->num_subchannels) { /* 4) TRANSIENT_FAILURE */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "rr_transient_failure");
return GRPC_CHANNEL_TRANSIENT_FAILURE;
new_state = GRPC_CHANNEL_TRANSIENT_FAILURE;
} else if (subchannel_list->num_idle ==
p->subchannel_list->num_subchannels) { /* 5) IDLE */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker, GRPC_CHANNEL_IDLE,
GRPC_ERROR_NONE, "rr_idle");
return GRPC_CHANNEL_IDLE;
new_state = GRPC_CHANNEL_IDLE;
}
/* no change */
return sd->curr_connectivity_state;
GRPC_ERROR_UNREF(error);
return new_state;
}
static void rr_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
@ -553,7 +563,7 @@ static void rr_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
while ((pp = p->pending_picks)) {
p->pending_picks = pp->next;
*pp->target = NULL;
grpc_closure_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
gpr_free(pp);
}
}
@ -571,13 +581,15 @@ static void rr_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
GPR_ASSERT(sd->subchannel_list == p->latest_pending_subchannel_list);
GPR_ASSERT(!sd->subchannel_list->shutting_down);
if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
const unsigned long num_subchannels =
p->subchannel_list != NULL
? (unsigned long)p->subchannel_list->num_subchannels
: 0;
gpr_log(GPR_DEBUG,
"[RR %p] phasing out subchannel list %p (size %lu) in favor "
"of %p (size %lu)",
(void *)p, (void *)p->subchannel_list,
(unsigned long)p->subchannel_list->num_subchannels,
(void *)sd->subchannel_list,
(unsigned long)sd->subchannel_list->num_subchannels);
(void *)p, (void *)p->subchannel_list, num_subchannels,
(void *)sd->subchannel_list, num_subchannels);
}
if (p->subchannel_list != NULL) {
// dispose of the current subchannel_list
@ -614,7 +626,7 @@ static void rr_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
(void *)selected->subchannel,
(unsigned long)next_ready_index);
}
grpc_closure_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
gpr_free(pp);
}
}
@ -655,7 +667,7 @@ static void rr_ping_one_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
grpc_connected_subchannel_ping(exec_ctx, target, closure);
GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, target, "rr_picked");
} else {
grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
GRPC_CLOSURE_SCHED(exec_ctx, closure, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Round Robin not connected"));
}
}
@ -747,9 +759,9 @@ static void rr_update_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
subchannel_data *sd = &subchannel_list->subchannels[subchannel_index++];
sd->subchannel_list = subchannel_list;
sd->subchannel = subchannel;
grpc_closure_init(&sd->connectivity_changed_closure,
GRPC_CLOSURE_INIT(&sd->connectivity_changed_closure,
rr_connectivity_changed_locked, sd,
grpc_combiner_scheduler(args->combiner, false));
grpc_combiner_scheduler(args->combiner));
/* use some sentinel value outside of the range of
* grpc_connectivity_state to signal an undefined previous state. We
* won't be referring to this value again and it'll be overwritten after

@ -138,12 +138,8 @@ static const grpc_arg_pointer_vtable lb_addresses_arg_vtable = {
grpc_arg grpc_lb_addresses_create_channel_arg(
const grpc_lb_addresses* addresses) {
grpc_arg arg;
arg.type = GRPC_ARG_POINTER;
arg.key = GRPC_ARG_LB_ADDRESSES;
arg.value.pointer.p = (void*)addresses;
arg.value.pointer.vtable = &lb_addresses_arg_vtable;
return arg;
return grpc_channel_arg_pointer_create(
GRPC_ARG_LB_ADDRESSES, (void*)addresses, &lb_addresses_arg_vtable);
}
grpc_lb_addresses* grpc_lb_addresses_find_channel_arg(

@ -19,6 +19,10 @@
#include "src/core/ext/filters/client_channel/resolver.h"
#include "src/core/lib/iomgr/combiner.h"
#ifndef NDEBUG
grpc_tracer_flag grpc_trace_resolver_refcount = GRPC_TRACER_INITIALIZER(false);
#endif
void grpc_resolver_init(grpc_resolver *resolver,
const grpc_resolver_vtable *vtable,
grpc_combiner *combiner) {
@ -27,25 +31,30 @@ void grpc_resolver_init(grpc_resolver *resolver,
gpr_ref_init(&resolver->refs, 1);
}
#ifdef GRPC_RESOLVER_REFCOUNT_DEBUG
void grpc_resolver_ref(grpc_resolver *resolver, grpc_closure_list *closure_list,
const char *file, int line, const char *reason) {
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "RESOLVER:%p ref %d -> %d %s",
resolver, (int)resolver->refs.count, (int)resolver->refs.count + 1,
reason);
#ifndef NDEBUG
void grpc_resolver_ref(grpc_resolver *resolver, const char *file, int line,
const char *reason) {
if (GRPC_TRACER_ON(grpc_trace_resolver_refcount)) {
gpr_atm old_refs = gpr_atm_no_barrier_load(&resolver->refs.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"RESOLVER:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", resolver,
old_refs, old_refs + 1, reason);
}
#else
void grpc_resolver_ref(grpc_resolver *resolver) {
#endif
gpr_ref(&resolver->refs);
}
#ifdef GRPC_RESOLVER_REFCOUNT_DEBUG
void grpc_resolver_unref(grpc_resolver *resolver,
grpc_closure_list *closure_list, const char *file,
int line, const char *reason) {
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "RESOLVER:%p unref %d -> %d %s",
resolver, (int)resolver->refs.count, (int)resolver->refs.count - 1,
reason);
#ifndef NDEBUG
void grpc_resolver_unref(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
const char *file, int line, const char *reason) {
if (GRPC_TRACER_ON(grpc_trace_resolver_refcount)) {
gpr_atm old_refs = gpr_atm_no_barrier_load(&resolver->refs.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"RESOLVER:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", resolver,
old_refs, old_refs - 1, reason);
}
#else
void grpc_resolver_unref(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver) {
#endif

@ -25,6 +25,10 @@
typedef struct grpc_resolver grpc_resolver;
typedef struct grpc_resolver_vtable grpc_resolver_vtable;
#ifndef NDEBUG
extern grpc_tracer_flag grpc_trace_resolver_refcount;
#endif
/** \a grpc_resolver provides \a grpc_channel_args objects to its caller */
struct grpc_resolver {
const grpc_resolver_vtable *vtable;
@ -41,17 +45,17 @@ struct grpc_resolver_vtable {
grpc_channel_args **result, grpc_closure *on_complete);
};
#ifdef GRPC_RESOLVER_REFCOUNT_DEBUG
#ifndef NDEBUG
#define GRPC_RESOLVER_REF(p, r) grpc_resolver_ref((p), __FILE__, __LINE__, (r))
#define GRPC_RESOLVER_UNREF(cl, p, r) \
grpc_resolver_unref((cl), (p), __FILE__, __LINE__, (r))
#define GRPC_RESOLVER_UNREF(e, p, r) \
grpc_resolver_unref((e), (p), __FILE__, __LINE__, (r))
void grpc_resolver_ref(grpc_resolver *policy, const char *file, int line,
const char *reason);
void grpc_resolver_unref(grpc_resolver *policy, grpc_closure_list *closure_list,
void grpc_resolver_unref(grpc_exec_ctx *exec_ctx, grpc_resolver *policy,
const char *file, int line, const char *reason);
#else
#define GRPC_RESOLVER_REF(p, r) grpc_resolver_ref((p))
#define GRPC_RESOLVER_UNREF(cl, p, r) grpc_resolver_unref((cl), (p))
#define GRPC_RESOLVER_UNREF(e, p, r) grpc_resolver_unref((e), (p))
void grpc_resolver_ref(grpc_resolver *policy);
void grpc_resolver_unref(grpc_exec_ctx *exec_ctx, grpc_resolver *policy);
#endif

@ -65,6 +65,8 @@ typedef struct {
grpc_combiner *combiner;
/** are we currently resolving? */
bool resolving;
/** the pending resolving request */
grpc_ares_request *pending_request;
/** which version of the result have we published? */
int published_version;
/** which version of the result is current? */
@ -82,7 +84,7 @@ typedef struct {
gpr_backoff backoff_state;
/** currently resolving addresses */
grpc_resolved_addresses *addresses;
grpc_lb_addresses *lb_addresses;
} ares_dns_resolver;
static void dns_ares_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
@ -109,9 +111,12 @@ static void dns_ares_shutdown_locked(grpc_exec_ctx *exec_ctx,
if (r->have_retry_timer) {
grpc_timer_cancel(exec_ctx, &r->retry_timer);
}
if (r->pending_request != NULL) {
grpc_cancel_ares_request(exec_ctx, r->pending_request);
}
if (r->next_completion != NULL) {
*r->target_result = NULL;
grpc_closure_sched(
GRPC_CLOSURE_SCHED(
exec_ctx, r->next_completion,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver Shutdown"));
r->next_completion = NULL;
@ -145,19 +150,11 @@ static void dns_ares_on_resolved_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_channel_args *result = NULL;
GPR_ASSERT(r->resolving);
r->resolving = false;
if (r->addresses != NULL) {
grpc_lb_addresses *addresses = grpc_lb_addresses_create(
r->addresses->naddrs, NULL /* user_data_vtable */);
for (size_t i = 0; i < r->addresses->naddrs; ++i) {
grpc_lb_addresses_set_address(
addresses, i, &r->addresses->addrs[i].addr,
r->addresses->addrs[i].len, false /* is_balancer */,
NULL /* balancer_name */, NULL /* user_data */);
}
grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses);
r->pending_request = NULL;
if (r->lb_addresses != NULL) {
grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(r->lb_addresses);
result = grpc_channel_args_copy_and_add(r->channel_args, &new_arg, 1);
grpc_resolved_addresses_destroy(r->addresses);
grpc_lb_addresses_destroy(exec_ctx, addresses);
grpc_lb_addresses_destroy(exec_ctx, r->lb_addresses);
} else {
const char *msg = grpc_error_string(error);
gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg);
@ -209,10 +206,11 @@ static void dns_ares_start_resolving_locked(grpc_exec_ctx *exec_ctx,
GRPC_RESOLVER_REF(&r->base, "dns-resolving");
GPR_ASSERT(!r->resolving);
r->resolving = true;
r->addresses = NULL;
grpc_dns_lookup_ares(exec_ctx, r->dns_server, r->name_to_resolve,
r->default_port, r->interested_parties,
&r->dns_ares_on_resolved_locked, &r->addresses);
r->lb_addresses = NULL;
r->pending_request = grpc_dns_lookup_ares(
exec_ctx, r->dns_server, r->name_to_resolve, r->default_port,
r->interested_parties, &r->dns_ares_on_resolved_locked, &r->lb_addresses,
true /* check_grpclb */);
}
static void dns_ares_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
@ -222,7 +220,8 @@ static void dns_ares_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
*r->target_result = r->resolved_result == NULL
? NULL
: grpc_channel_args_copy(r->resolved_result);
grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
gpr_log(GPR_DEBUG, "dns_ares_maybe_finish_next_locked");
GRPC_CLOSURE_SCHED(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
r->next_completion = NULL;
r->published_version = r->resolved_version;
}
@ -245,10 +244,10 @@ static void dns_ares_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
static grpc_resolver *dns_ares_create(grpc_exec_ctx *exec_ctx,
grpc_resolver_args *args,
const char *default_port) {
// Get name from args.
/* Get name from args. */
const char *path = args->uri->path;
if (path[0] == '/') ++path;
// Create resolver.
/* Create resolver. */
ares_dns_resolver *r = gpr_zalloc(sizeof(ares_dns_resolver));
grpc_resolver_init(&r->base, &dns_ares_resolver_vtable, args->combiner);
if (0 != strcmp(args->uri->authority, "")) {
@ -267,12 +266,12 @@ static grpc_resolver *dns_ares_create(grpc_exec_ctx *exec_ctx,
GRPC_DNS_RECONNECT_JITTER,
GRPC_DNS_MIN_CONNECT_TIMEOUT_SECONDS * 1000,
GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS * 1000);
grpc_closure_init(&r->dns_ares_on_retry_timer_locked,
GRPC_CLOSURE_INIT(&r->dns_ares_on_retry_timer_locked,
dns_ares_on_retry_timer_locked, r,
grpc_combiner_scheduler(r->base.combiner, false));
grpc_closure_init(&r->dns_ares_on_resolved_locked,
grpc_combiner_scheduler(r->base.combiner));
GRPC_CLOSURE_INIT(&r->dns_ares_on_resolved_locked,
dns_ares_on_resolved_locked, r,
grpc_combiner_scheduler(r->base.combiner, false));
grpc_combiner_scheduler(r->base.combiner));
return &r->base;
}

@ -19,8 +19,6 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H
#include <ares.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/pollset_set.h"
@ -47,5 +45,9 @@ grpc_error *grpc_ares_ev_driver_create(grpc_ares_ev_driver **ev_driver,
of ARES_ECANCELLED. */
void grpc_ares_ev_driver_destroy(grpc_ares_ev_driver *ev_driver);
/* Shutdown all the grpc_fds used by \a ev_driver */
void grpc_ares_ev_driver_shutdown(grpc_exec_ctx *exec_ctx,
grpc_ares_ev_driver *ev_driver);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H \
*/

@ -19,6 +19,8 @@
#include "src/core/lib/iomgr/port.h"
#if GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET)
#include <ares.h>
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
#include <grpc/support/alloc.h>
@ -99,9 +101,12 @@ static void fd_node_destroy(grpc_exec_ctx *exec_ctx, fd_node *fdn) {
GPR_ASSERT(!fdn->writable_registered);
gpr_mu_destroy(&fdn->mu);
grpc_pollset_set_del_fd(exec_ctx, fdn->ev_driver->pollset_set, fdn->grpc_fd);
grpc_fd_shutdown(exec_ctx, fdn->grpc_fd,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("fd node destroyed"));
grpc_fd_orphan(exec_ctx, fdn->grpc_fd, NULL, NULL, "c-ares query finished");
/* c-ares library has closed the fd inside grpc_fd. This fd may be picked up
immediately by another thread, and should not be closed by the following
grpc_fd_orphan. To prevent this fd from being closed by grpc_fd_orphan,
a fd pointer is provided. */
int fd;
grpc_fd_orphan(exec_ctx, fdn->grpc_fd, NULL, &fd, "c-ares query finished");
gpr_free(fdn);
}
@ -140,6 +145,20 @@ void grpc_ares_ev_driver_destroy(grpc_ares_ev_driver *ev_driver) {
grpc_ares_ev_driver_unref(ev_driver);
}
void grpc_ares_ev_driver_shutdown(grpc_exec_ctx *exec_ctx,
grpc_ares_ev_driver *ev_driver) {
gpr_mu_lock(&ev_driver->mu);
ev_driver->shutting_down = true;
fd_node *fn = ev_driver->fds;
while (fn != NULL) {
grpc_fd_shutdown(
exec_ctx, fn->grpc_fd,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("grpc_ares_ev_driver_shutdown"));
fn = fn->next;
}
gpr_mu_unlock(&ev_driver->mu);
}
// Search fd in the fd_node list head. This is an O(n) search, the max possible
// value of n is ARES_GETSOCK_MAXNUM (16). n is typically 1 - 2 in our tests.
static fd_node *pop_fd_node(fd_node **head, int fd) {
@ -240,9 +259,9 @@ static void grpc_ares_notify_on_event_locked(grpc_exec_ctx *exec_ctx,
fdn->readable_registered = false;
fdn->writable_registered = false;
gpr_mu_init(&fdn->mu);
grpc_closure_init(&fdn->read_closure, on_readable_cb, fdn,
GRPC_CLOSURE_INIT(&fdn->read_closure, on_readable_cb, fdn,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&fdn->write_closure, on_writable_cb, fdn,
GRPC_CLOSURE_INIT(&fdn->write_closure, on_writable_cb, fdn,
grpc_schedule_on_exec_ctx);
grpc_pollset_set_add_fd(exec_ctx, ev_driver->pollset_set,
fdn->grpc_fd);

@ -33,6 +33,7 @@
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
#include <grpc/support/useful.h>
#include <nameser.h>
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
@ -45,20 +46,14 @@
static gpr_once g_basic_init = GPR_ONCE_INIT;
static gpr_mu g_init_mu;
typedef struct grpc_ares_request {
struct grpc_ares_request {
/** indicates the DNS server to use, if specified */
struct ares_addr_port_node dns_server_addr;
/** following members are set in grpc_resolve_address_ares_impl */
/** host to resolve, parsed from the name to resolve */
char *host;
/** port to fill in sockaddr_in, parsed from the name to resolve */
char *port;
/** default port to use */
char *default_port;
/** closure to call when the request completes */
grpc_closure *on_done;
/** the pointer to receive the resolved addresses */
grpc_resolved_addresses **addrs_out;
grpc_lb_addresses **lb_addrs_out;
/** the evernt driver used by this request */
grpc_ares_ev_driver *ev_driver;
/** number of ongoing queries */
@ -70,7 +65,19 @@ typedef struct grpc_ares_request {
bool success;
/** the errors explaining the request failure, set in on_done_cb */
grpc_error *error;
} grpc_ares_request;
};
typedef struct grpc_ares_hostbyname_request {
/** following members are set in create_hostbyname_request */
/** the top-level request instance */
grpc_ares_request *parent_request;
/** host to resolve, parsed from the name to resolve */
char *host;
/** port to fill in sockaddr_in, parsed from the name to resolve */
uint16_t port;
/** is it a grpclb address */
bool is_balancer;
} grpc_ares_hostbyname_request;
static void do_basic_init(void) { gpr_mu_init(&g_init_mu); }
@ -83,6 +90,10 @@ static uint16_t strhtons(const char *port) {
return htons((unsigned short)atoi(port));
}
static void grpc_ares_request_ref(grpc_ares_request *r) {
gpr_ref(&r->pending_queries);
}
static void grpc_ares_request_unref(grpc_exec_ctx *exec_ctx,
grpc_ares_request *r) {
/* If there are no pending queries, invoke on_done callback and destroy the
@ -96,74 +107,102 @@ static void grpc_ares_request_unref(grpc_exec_ctx *exec_ctx,
acquire locks in on_done. ares_dns_resolver is using combiner to
protect resources needed by on_done. */
grpc_exec_ctx new_exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_closure_sched(&new_exec_ctx, r->on_done, r->error);
GRPC_CLOSURE_SCHED(&new_exec_ctx, r->on_done, r->error);
grpc_exec_ctx_finish(&new_exec_ctx);
} else {
grpc_closure_sched(exec_ctx, r->on_done, r->error);
GRPC_CLOSURE_SCHED(exec_ctx, r->on_done, r->error);
}
gpr_mu_destroy(&r->mu);
grpc_ares_ev_driver_destroy(r->ev_driver);
gpr_free(r->host);
gpr_free(r->port);
gpr_free(r->default_port);
gpr_free(r);
}
}
static void on_done_cb(void *arg, int status, int timeouts,
struct hostent *hostent) {
grpc_ares_request *r = (grpc_ares_request *)arg;
static grpc_ares_hostbyname_request *create_hostbyname_request(
grpc_ares_request *parent_request, char *host, uint16_t port,
bool is_balancer) {
grpc_ares_hostbyname_request *hr =
gpr_zalloc(sizeof(grpc_ares_hostbyname_request));
hr->parent_request = parent_request;
hr->host = gpr_strdup(host);
hr->port = port;
hr->is_balancer = is_balancer;
grpc_ares_request_ref(parent_request);
return hr;
}
static void destroy_hostbyname_request(grpc_exec_ctx *exec_ctx,
grpc_ares_hostbyname_request *hr) {
grpc_ares_request_unref(exec_ctx, hr->parent_request);
gpr_free(hr->host);
gpr_free(hr);
}
static void on_hostbyname_done_cb(void *arg, int status, int timeouts,
struct hostent *hostent) {
grpc_ares_hostbyname_request *hr = (grpc_ares_hostbyname_request *)arg;
grpc_ares_request *r = hr->parent_request;
gpr_mu_lock(&r->mu);
if (status == ARES_SUCCESS) {
GRPC_ERROR_UNREF(r->error);
r->error = GRPC_ERROR_NONE;
r->success = true;
grpc_resolved_addresses **addresses = r->addrs_out;
if (*addresses == NULL) {
*addresses = gpr_malloc(sizeof(grpc_resolved_addresses));
(*addresses)->naddrs = 0;
(*addresses)->addrs = NULL;
grpc_lb_addresses **lb_addresses = r->lb_addrs_out;
if (*lb_addresses == NULL) {
*lb_addresses = grpc_lb_addresses_create(0, NULL);
}
size_t prev_naddr = (*addresses)->naddrs;
size_t prev_naddr = (*lb_addresses)->num_addresses;
size_t i;
for (i = 0; hostent->h_addr_list[i] != NULL; i++) {
}
(*addresses)->naddrs += i;
(*addresses)->addrs =
gpr_realloc((*addresses)->addrs,
sizeof(grpc_resolved_address) * (*addresses)->naddrs);
for (i = prev_naddr; i < (*addresses)->naddrs; i++) {
memset(&(*addresses)->addrs[i], 0, sizeof(grpc_resolved_address));
if (hostent->h_addrtype == AF_INET6) {
(*addresses)->addrs[i].len = sizeof(struct sockaddr_in6);
struct sockaddr_in6 *addr =
(struct sockaddr_in6 *)&(*addresses)->addrs[i].addr;
addr->sin6_family = (sa_family_t)hostent->h_addrtype;
addr->sin6_port = strhtons(r->port);
char output[INET6_ADDRSTRLEN];
memcpy(&addr->sin6_addr, hostent->h_addr_list[i - prev_naddr],
sizeof(struct in6_addr));
ares_inet_ntop(AF_INET6, &addr->sin6_addr, output, INET6_ADDRSTRLEN);
gpr_log(GPR_DEBUG,
"c-ares resolver gets a AF_INET6 result: \n"
" addr: %s\n port: %s\n sin6_scope_id: %d\n",
output, r->port, addr->sin6_scope_id);
} else {
(*addresses)->addrs[i].len = sizeof(struct sockaddr_in);
struct sockaddr_in *addr =
(struct sockaddr_in *)&(*addresses)->addrs[i].addr;
memcpy(&addr->sin_addr, hostent->h_addr_list[i - prev_naddr],
sizeof(struct in_addr));
addr->sin_family = (sa_family_t)hostent->h_addrtype;
addr->sin_port = strhtons(r->port);
char output[INET_ADDRSTRLEN];
ares_inet_ntop(AF_INET, &addr->sin_addr, output, INET_ADDRSTRLEN);
gpr_log(GPR_DEBUG,
"c-ares resolver gets a AF_INET result: \n"
" addr: %s\n port: %s\n",
output, r->port);
(*lb_addresses)->num_addresses += i;
(*lb_addresses)->addresses =
gpr_realloc((*lb_addresses)->addresses,
sizeof(grpc_lb_address) * (*lb_addresses)->num_addresses);
for (i = prev_naddr; i < (*lb_addresses)->num_addresses; i++) {
switch (hostent->h_addrtype) {
case AF_INET6: {
size_t addr_len = sizeof(struct sockaddr_in6);
struct sockaddr_in6 addr;
memset(&addr, 0, addr_len);
memcpy(&addr.sin6_addr, hostent->h_addr_list[i - prev_naddr],
sizeof(struct in6_addr));
addr.sin6_family = (sa_family_t)hostent->h_addrtype;
addr.sin6_port = hr->port;
grpc_lb_addresses_set_address(
*lb_addresses, i, &addr, addr_len,
hr->is_balancer /* is_balancer */,
hr->is_balancer ? strdup(hr->host) : NULL /* balancer_name */,
NULL /* user_data */);
char output[INET6_ADDRSTRLEN];
ares_inet_ntop(AF_INET6, &addr.sin6_addr, output, INET6_ADDRSTRLEN);
gpr_log(GPR_DEBUG,
"c-ares resolver gets a AF_INET6 result: \n"
" addr: %s\n port: %d\n sin6_scope_id: %d\n",
output, ntohs(hr->port), addr.sin6_scope_id);
break;
}
case AF_INET: {
size_t addr_len = sizeof(struct sockaddr_in);
struct sockaddr_in addr;
memset(&addr, 0, addr_len);
memcpy(&addr.sin_addr, hostent->h_addr_list[i - prev_naddr],
sizeof(struct in_addr));
addr.sin_family = (sa_family_t)hostent->h_addrtype;
addr.sin_port = hr->port;
grpc_lb_addresses_set_address(
*lb_addresses, i, &addr, addr_len,
hr->is_balancer /* is_balancer */,
hr->is_balancer ? strdup(hr->host) : NULL /* balancer_name */,
NULL /* user_data */);
char output[INET_ADDRSTRLEN];
ares_inet_ntop(AF_INET, &addr.sin_addr, output, INET_ADDRSTRLEN);
gpr_log(GPR_DEBUG,
"c-ares resolver gets a AF_INET result: \n"
" addr: %s\n port: %d\n",
output, ntohs(hr->port));
break;
}
}
}
} else if (!r->success) {
@ -179,14 +218,58 @@ static void on_done_cb(void *arg, int status, int timeouts,
}
}
gpr_mu_unlock(&r->mu);
grpc_ares_request_unref(NULL, r);
destroy_hostbyname_request(NULL, hr);
}
static void on_srv_query_done_cb(void *arg, int status, int timeouts,
unsigned char *abuf, int alen) {
grpc_ares_request *r = (grpc_ares_request *)arg;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_log(GPR_DEBUG, "on_query_srv_done_cb");
if (status == ARES_SUCCESS) {
gpr_log(GPR_DEBUG, "on_query_srv_done_cb ARES_SUCCESS");
struct ares_srv_reply *reply;
const int parse_status = ares_parse_srv_reply(abuf, alen, &reply);
if (parse_status == ARES_SUCCESS) {
ares_channel *channel = grpc_ares_ev_driver_get_channel(r->ev_driver);
for (struct ares_srv_reply *srv_it = reply; srv_it != NULL;
srv_it = srv_it->next) {
if (grpc_ipv6_loopback_available()) {
grpc_ares_hostbyname_request *hr = create_hostbyname_request(
r, srv_it->host, srv_it->port, true /* is_balancer */);
ares_gethostbyname(*channel, hr->host, AF_INET6,
on_hostbyname_done_cb, hr);
}
grpc_ares_hostbyname_request *hr = create_hostbyname_request(
r, srv_it->host, srv_it->port, true /* is_balancer */);
ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_cb,
hr);
grpc_ares_ev_driver_start(&exec_ctx, r->ev_driver);
}
}
if (reply != NULL) {
ares_free_data(reply);
}
} else if (!r->success) {
char *error_msg;
gpr_asprintf(&error_msg, "C-ares status is not ARES_SUCCESS: %s",
ares_strerror(status));
grpc_error *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
gpr_free(error_msg);
if (r->error == GRPC_ERROR_NONE) {
r->error = error;
} else {
r->error = grpc_error_add_child(error, r->error);
}
}
grpc_ares_request_unref(&exec_ctx, r);
grpc_exec_ctx_finish(&exec_ctx);
}
void grpc_dns_lookup_ares(grpc_exec_ctx *exec_ctx, const char *dns_server,
const char *name, const char *default_port,
grpc_pollset_set *interested_parties,
grpc_closure *on_done,
grpc_resolved_addresses **addrs) {
static grpc_ares_request *grpc_dns_lookup_ares_impl(
grpc_exec_ctx *exec_ctx, const char *dns_server, const char *name,
const char *default_port, grpc_pollset_set *interested_parties,
grpc_closure *on_done, grpc_lb_addresses **addrs, bool check_grpclb) {
grpc_error *error = GRPC_ERROR_NONE;
/* TODO(zyc): Enable tracing after #9603 is checked in */
/* if (grpc_dns_trace) {
@ -221,10 +304,7 @@ void grpc_dns_lookup_ares(grpc_exec_ctx *exec_ctx, const char *dns_server,
gpr_mu_init(&r->mu);
r->ev_driver = ev_driver;
r->on_done = on_done;
r->addrs_out = addrs;
r->default_port = gpr_strdup(default_port);
r->port = port;
r->host = host;
r->lb_addrs_out = addrs;
r->success = false;
r->error = GRPC_ERROR_NONE;
ares_channel *channel = grpc_ares_ev_driver_get_channel(r->ev_driver);
@ -248,6 +328,7 @@ void grpc_dns_lookup_ares(grpc_exec_ctx *exec_ctx, const char *dns_server,
error = grpc_error_set_str(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("cannot parse authority"),
GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
gpr_free(r);
goto error_cleanup;
}
int status = ares_set_servers_ports(*channel, &r->dns_server_addr);
@ -257,41 +338,55 @@ void grpc_dns_lookup_ares(grpc_exec_ctx *exec_ctx, const char *dns_server,
ares_strerror(status));
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
gpr_free(error_msg);
gpr_free(r);
goto error_cleanup;
}
}
// An extra reference is put here to avoid destroying the request in
// on_done_cb before calling grpc_ares_ev_driver_start.
gpr_ref_init(&r->pending_queries, 2);
gpr_ref_init(&r->pending_queries, 1);
if (grpc_ipv6_loopback_available()) {
gpr_ref(&r->pending_queries);
ares_gethostbyname(*channel, r->host, AF_INET6, on_done_cb, r);
grpc_ares_hostbyname_request *hr = create_hostbyname_request(
r, host, strhtons(port), false /* is_balancer */);
ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_cb, hr);
}
grpc_ares_hostbyname_request *hr = create_hostbyname_request(
r, host, strhtons(port), false /* is_balancer */);
ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_cb, hr);
if (check_grpclb) {
/* Query the SRV record */
grpc_ares_request_ref(r);
char *service_name;
gpr_asprintf(&service_name, "_grpclb._tcp.%s", host);
ares_query(*channel, service_name, ns_c_in, ns_t_srv, on_srv_query_done_cb,
r);
gpr_free(service_name);
}
ares_gethostbyname(*channel, r->host, AF_INET, on_done_cb, r);
/* TODO(zyc): Handle CNAME records here. */
grpc_ares_ev_driver_start(exec_ctx, r->ev_driver);
grpc_ares_request_unref(exec_ctx, r);
return;
gpr_free(host);
gpr_free(port);
return r;
error_cleanup:
grpc_closure_sched(exec_ctx, on_done, error);
GRPC_CLOSURE_SCHED(exec_ctx, on_done, error);
gpr_free(host);
gpr_free(port);
return NULL;
}
void grpc_resolve_address_ares_impl(grpc_exec_ctx *exec_ctx, const char *name,
const char *default_port,
grpc_pollset_set *interested_parties,
grpc_closure *on_done,
grpc_resolved_addresses **addrs) {
grpc_dns_lookup_ares(exec_ctx, NULL /* dns_server */, name, default_port,
interested_parties, on_done, addrs);
}
grpc_ares_request *(*grpc_dns_lookup_ares)(
grpc_exec_ctx *exec_ctx, const char *dns_server, const char *name,
const char *default_port, grpc_pollset_set *interested_parties,
grpc_closure *on_done, grpc_lb_addresses **addrs,
bool check_grpclb) = grpc_dns_lookup_ares_impl;
void (*grpc_resolve_address_ares)(
grpc_exec_ctx *exec_ctx, const char *name, const char *default_port,
grpc_pollset_set *interested_parties, grpc_closure *on_done,
grpc_resolved_addresses **addrs) = grpc_resolve_address_ares_impl;
void grpc_cancel_ares_request(grpc_exec_ctx *exec_ctx, grpc_ares_request *r) {
if (grpc_dns_lookup_ares == grpc_dns_lookup_ares_impl) {
grpc_ares_ev_driver_shutdown(exec_ctx, r->ev_driver);
}
}
grpc_error *grpc_ares_init(void) {
gpr_once_init(&g_basic_init, do_basic_init);
@ -316,4 +411,66 @@ void grpc_ares_cleanup(void) {
gpr_mu_unlock(&g_init_mu);
}
/*
* grpc_resolve_address_ares related structs and functions
*/
typedef struct grpc_resolve_address_ares_request {
/** the pointer to receive the resolved addresses */
grpc_resolved_addresses **addrs_out;
/** currently resolving lb addresses */
grpc_lb_addresses *lb_addrs;
/** closure to call when the resolve_address_ares request completes */
grpc_closure *on_resolve_address_done;
/** a closure wrapping on_dns_lookup_done_cb, which should be invoked when the
grpc_dns_lookup_ares operation is done. */
grpc_closure on_dns_lookup_done;
} grpc_resolve_address_ares_request;
static void on_dns_lookup_done_cb(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
grpc_resolve_address_ares_request *r =
(grpc_resolve_address_ares_request *)arg;
grpc_resolved_addresses **resolved_addresses = r->addrs_out;
if (r->lb_addrs == NULL || r->lb_addrs->num_addresses == 0) {
*resolved_addresses = NULL;
} else {
*resolved_addresses = gpr_zalloc(sizeof(grpc_resolved_addresses));
(*resolved_addresses)->naddrs = r->lb_addrs->num_addresses;
(*resolved_addresses)->addrs = gpr_zalloc(sizeof(grpc_resolved_address) *
(*resolved_addresses)->naddrs);
for (size_t i = 0; i < (*resolved_addresses)->naddrs; i++) {
GPR_ASSERT(!r->lb_addrs->addresses[i].is_balancer);
memcpy(&(*resolved_addresses)->addrs[i],
&r->lb_addrs->addresses[i].address, sizeof(grpc_resolved_address));
}
}
GRPC_CLOSURE_SCHED(exec_ctx, r->on_resolve_address_done,
GRPC_ERROR_REF(error));
grpc_lb_addresses_destroy(exec_ctx, r->lb_addrs);
gpr_free(r);
}
static void grpc_resolve_address_ares_impl(grpc_exec_ctx *exec_ctx,
const char *name,
const char *default_port,
grpc_pollset_set *interested_parties,
grpc_closure *on_done,
grpc_resolved_addresses **addrs) {
grpc_resolve_address_ares_request *r =
gpr_zalloc(sizeof(grpc_resolve_address_ares_request));
r->addrs_out = addrs;
r->on_resolve_address_done = on_done;
GRPC_CLOSURE_INIT(&r->on_dns_lookup_done, on_dns_lookup_done_cb, r,
grpc_schedule_on_exec_ctx);
grpc_dns_lookup_ares(exec_ctx, NULL /* dns_server */, name, default_port,
interested_parties, &r->on_dns_lookup_done, &r->lb_addrs,
false /* check_grpclb */);
}
void (*grpc_resolve_address_ares)(
grpc_exec_ctx *exec_ctx, const char *name, const char *default_port,
grpc_pollset_set *interested_parties, grpc_closure *on_done,
grpc_resolved_addresses **addrs) = grpc_resolve_address_ares_impl;
#endif /* GRPC_ARES == 1 && !defined(GRPC_UV) */

@ -19,11 +19,14 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/iomgr/resolve_address.h"
typedef struct grpc_ares_request grpc_ares_request;
/* Asynchronously resolve addr. Use \a default_port if a port isn't designated
in addr, otherwise use the port in addr. grpc_ares_init() must be called at
least once before this function. \a on_done may be called directly in this
@ -36,11 +39,21 @@ extern void (*grpc_resolve_address_ares)(grpc_exec_ctx *exec_ctx,
grpc_closure *on_done,
grpc_resolved_addresses **addresses);
void grpc_dns_lookup_ares(grpc_exec_ctx *exec_ctx, const char *dns_server,
const char *addr, const char *default_port,
grpc_pollset_set *interested_parties,
grpc_closure *on_done,
grpc_resolved_addresses **addresses);
/* Asynchronously resolve addr. It will try to resolve grpclb SRV records in
addition to the normal address records. For normal address records, it uses
\a default_port if a port isn't designated in \a addr, otherwise it uses the
port in \a addr. grpc_ares_init() must be called at least once before this
function. \a on_done may be called directly in this function without being
scheduled with \a exec_ctx, it must not try to acquire locks that are being
held by the caller. */
extern grpc_ares_request *(*grpc_dns_lookup_ares)(
grpc_exec_ctx *exec_ctx, const char *dns_server, const char *addr,
const char *default_port, grpc_pollset_set *interested_parties,
grpc_closure *on_done, grpc_lb_addresses **addresses, bool check_grpclb);
/* Cancel the pending grpc_ares_request \a request */
void grpc_cancel_ares_request(grpc_exec_ctx *exec_ctx,
grpc_ares_request *request);
/* Initialize gRPC ares wrapper. Must be called at least once before
grpc_resolve_address_ares(). */

@ -0,0 +1,59 @@
/*
*
* Copyright 2016-2017 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#if GRPC_ARES != 1 || defined(GRPC_UV)
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
struct grpc_ares_request {
char val;
};
static grpc_ares_request *grpc_dns_lookup_ares_impl(
grpc_exec_ctx *exec_ctx, const char *dns_server, const char *name,
const char *default_port, grpc_pollset_set *interested_parties,
grpc_closure *on_done, grpc_lb_addresses **addrs, bool check_grpclb) {
return NULL;
}
grpc_ares_request *(*grpc_dns_lookup_ares)(
grpc_exec_ctx *exec_ctx, const char *dns_server, const char *name,
const char *default_port, grpc_pollset_set *interested_parties,
grpc_closure *on_done, grpc_lb_addresses **addrs,
bool check_grpclb) = grpc_dns_lookup_ares_impl;
void grpc_cancel_ares_request(grpc_exec_ctx *exec_ctx, grpc_ares_request *r) {}
grpc_error *grpc_ares_init(void) { return GRPC_ERROR_NONE; }
void grpc_ares_cleanup(void) {}
static void grpc_resolve_address_ares_impl(grpc_exec_ctx *exec_ctx,
const char *name,
const char *default_port,
grpc_pollset_set *interested_parties,
grpc_closure *on_done,
grpc_resolved_addresses **addrs) {}
void (*grpc_resolve_address_ares)(
grpc_exec_ctx *exec_ctx, const char *name, const char *default_port,
grpc_pollset_set *interested_parties, grpc_closure *on_done,
grpc_resolved_addresses **addrs) = grpc_resolve_address_ares_impl;
#endif /* GRPC_ARES != 1 || defined(GRPC_UV) */

@ -99,7 +99,7 @@ static void dns_shutdown_locked(grpc_exec_ctx *exec_ctx,
}
if (r->next_completion != NULL) {
*r->target_result = NULL;
grpc_closure_sched(
GRPC_CLOSURE_SCHED(
exec_ctx, r->next_completion,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver Shutdown"));
r->next_completion = NULL;
@ -178,8 +178,8 @@ static void dns_on_resolved_locked(grpc_exec_ctx *exec_ctx, void *arg,
} else {
gpr_log(GPR_DEBUG, "retrying immediately");
}
grpc_closure_init(&r->on_retry, dns_on_retry_timer_locked, r,
grpc_combiner_scheduler(r->base.combiner, false));
GRPC_CLOSURE_INIT(&r->on_retry, dns_on_retry_timer_locked, r,
grpc_combiner_scheduler(r->base.combiner));
grpc_timer_init(exec_ctx, &r->retry_timer, next_try, &r->on_retry, now);
}
if (r->resolved_result != NULL) {
@ -200,8 +200,8 @@ static void dns_start_resolving_locked(grpc_exec_ctx *exec_ctx,
r->addresses = NULL;
grpc_resolve_address(
exec_ctx, r->name_to_resolve, r->default_port, r->interested_parties,
grpc_closure_create(dns_on_resolved_locked, r,
grpc_combiner_scheduler(r->base.combiner, false)),
GRPC_CLOSURE_CREATE(dns_on_resolved_locked, r,
grpc_combiner_scheduler(r->base.combiner)),
&r->addresses);
}
@ -212,7 +212,7 @@ static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
*r->target_result = r->resolved_result == NULL
? NULL
: grpc_channel_args_copy(r->resolved_result);
grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
r->next_completion = NULL;
r->published_version = r->resolved_version;
}

@ -56,6 +56,10 @@ typedef struct {
// grpc_resolver_next_locked()'s closure.
grpc_channel_args* next_results;
// Results to use for the pretended re-resolution in
// fake_resolver_channel_saw_error_locked().
grpc_channel_args* results_upon_error;
// pending next completion, or NULL
grpc_closure* next_completion;
// target result address for next completion
@ -65,6 +69,7 @@ typedef struct {
static void fake_resolver_destroy(grpc_exec_ctx* exec_ctx, grpc_resolver* gr) {
fake_resolver* r = (fake_resolver*)gr;
grpc_channel_args_destroy(exec_ctx, r->next_results);
grpc_channel_args_destroy(exec_ctx, r->results_upon_error);
grpc_channel_args_destroy(exec_ctx, r->channel_args);
gpr_free(r);
}
@ -74,7 +79,9 @@ static void fake_resolver_shutdown_locked(grpc_exec_ctx* exec_ctx,
fake_resolver* r = (fake_resolver*)resolver;
if (r->next_completion != NULL) {
*r->target_result = NULL;
grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(
exec_ctx, r->next_completion,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver Shutdown"));
r->next_completion = NULL;
}
}
@ -85,15 +92,19 @@ static void fake_resolver_maybe_finish_next_locked(grpc_exec_ctx* exec_ctx,
*r->target_result =
grpc_channel_args_union(r->next_results, r->channel_args);
grpc_channel_args_destroy(exec_ctx, r->next_results);
grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
r->next_completion = NULL;
r->next_results = NULL;
GRPC_CLOSURE_SCHED(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
r->next_completion = NULL;
}
}
static void fake_resolver_channel_saw_error_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver) {
fake_resolver* r = (fake_resolver*)resolver;
if (r->next_results == NULL && r->results_upon_error != NULL) {
// Pretend we re-resolved.
r->next_results = grpc_channel_args_copy(r->results_upon_error);
}
fake_resolver_maybe_finish_next_locked(exec_ctx, r);
}
@ -149,6 +160,10 @@ static void set_response_cb(grpc_exec_ctx* exec_ctx, void* arg,
grpc_channel_args_destroy(exec_ctx, r->next_results);
}
r->next_results = generator->next_response;
if (r->results_upon_error != NULL) {
grpc_channel_args_destroy(exec_ctx, r->results_upon_error);
}
r->results_upon_error = grpc_channel_args_copy(generator->next_response);
fake_resolver_maybe_finish_next_locked(exec_ctx, r);
}
@ -157,11 +172,10 @@ void grpc_fake_resolver_response_generator_set_response(
grpc_channel_args* next_response) {
GPR_ASSERT(generator->resolver != NULL);
generator->next_response = grpc_channel_args_copy(next_response);
grpc_closure_sched(
exec_ctx,
grpc_closure_create(
set_response_cb, generator,
grpc_combiner_scheduler(generator->resolver->base.combiner, false)),
GRPC_CLOSURE_SCHED(
exec_ctx, GRPC_CLOSURE_CREATE(set_response_cb, generator,
grpc_combiner_scheduler(
generator->resolver->base.combiner)),
GRPC_ERROR_NONE);
}

@ -73,7 +73,9 @@ static void sockaddr_shutdown_locked(grpc_exec_ctx *exec_ctx,
sockaddr_resolver *r = (sockaddr_resolver *)resolver;
if (r->next_completion != NULL) {
*r->target_result = NULL;
grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(
exec_ctx, r->next_completion,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver Shutdown"));
r->next_completion = NULL;
}
}
@ -103,7 +105,7 @@ static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
grpc_arg arg = grpc_lb_addresses_create_channel_arg(r->addresses);
*r->target_result =
grpc_channel_args_copy_and_add(r->channel_args, &arg, 1);
grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
r->next_completion = NULL;
}
}

@ -140,25 +140,13 @@ struct grpc_subchannel_call {
static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *subchannel,
grpc_error *error);
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
#ifndef NDEBUG
#define REF_REASON reason
#define REF_LOG(name, p) \
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "%s: %p ref %d -> %d %s", \
(name), (p), (p)->refs.count, (p)->refs.count + 1, reason)
#define UNREF_LOG(name, p) \
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "%s: %p unref %d -> %d %s", \
(name), (p), (p)->refs.count, (p)->refs.count - 1, reason)
#define REF_MUTATE_EXTRA_ARGS \
GRPC_SUBCHANNEL_REF_EXTRA_ARGS, const char *purpose
#define REF_MUTATE_PURPOSE(x) , file, line, reason, x
#else
#define REF_REASON ""
#define REF_LOG(name, p) \
do { \
} while (0)
#define UNREF_LOG(name, p) \
do { \
} while (0)
#define REF_MUTATE_EXTRA_ARGS
#define REF_MUTATE_PURPOSE(x)
#endif
@ -207,10 +195,12 @@ static gpr_atm ref_mutate(grpc_subchannel *c, gpr_atm delta,
int barrier REF_MUTATE_EXTRA_ARGS) {
gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta)
: gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta);
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"SUBCHANNEL: %p %s 0x%08" PRIxPTR " -> 0x%08" PRIxPTR " [%s]", c,
purpose, old_val, old_val + delta, reason);
#ifndef NDEBUG
if (GRPC_TRACER_ON(grpc_trace_stream_refcount)) {
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"SUBCHANNEL: %p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", c,
purpose, old_val, old_val + delta, reason);
}
#endif
return old_val;
}
@ -283,7 +273,7 @@ void grpc_subchannel_weak_unref(grpc_exec_ctx *exec_ctx,
gpr_atm old_refs;
old_refs = ref_mutate(c, -(gpr_atm)1, 1 REF_MUTATE_PURPOSE("WEAK_UNREF"));
if (old_refs == 1) {
grpc_closure_sched(exec_ctx, grpc_closure_create(subchannel_destroy, c,
GRPC_CLOSURE_SCHED(exec_ctx, GRPC_CLOSURE_CREATE(subchannel_destroy, c,
grpc_schedule_on_exec_ctx),
GRPC_ERROR_NONE);
}
@ -333,7 +323,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
if (new_args != NULL) grpc_channel_args_destroy(exec_ctx, new_args);
c->root_external_state_watcher.next = c->root_external_state_watcher.prev =
&c->root_external_state_watcher;
grpc_closure_init(&c->connected, subchannel_connected, c,
GRPC_CLOSURE_INIT(&c->connected, subchannel_connected, c,
grpc_schedule_on_exec_ctx);
grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE,
"subchannel");
@ -421,7 +411,7 @@ static void on_external_state_watcher_done(grpc_exec_ctx *exec_ctx, void *arg,
gpr_mu_unlock(&w->subchannel->mu);
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, w->subchannel, "external_state_watcher");
gpr_free(w);
grpc_closure_run(exec_ctx, follow_up, GRPC_ERROR_REF(error));
GRPC_CLOSURE_RUN(exec_ctx, follow_up, GRPC_ERROR_REF(error));
}
static void on_alarm(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
@ -488,7 +478,7 @@ static void maybe_start_connecting_locked(grpc_exec_ctx *exec_ctx,
gpr_log(GPR_INFO, "Retry in %" PRId64 ".%09d seconds",
time_til_next.tv_sec, time_til_next.tv_nsec);
}
grpc_closure_init(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx);
GRPC_CLOSURE_INIT(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx);
grpc_timer_init(exec_ctx, &c->alarm, c->next_attempt, &c->on_alarm, now);
}
}
@ -514,7 +504,7 @@ void grpc_subchannel_notify_on_state_change(
w->subchannel = c;
w->pollset_set = interested_parties;
w->notify = notify;
grpc_closure_init(&w->closure, on_external_state_watcher_done, w,
GRPC_CLOSURE_INIT(&w->closure, on_external_state_watcher_done, w,
grpc_schedule_on_exec_ctx);
if (interested_parties != NULL) {
grpc_pollset_set_add_pollset_set(exec_ctx, c->pollset_set,
@ -635,7 +625,7 @@ static bool publish_transport_locked(grpc_exec_ctx *exec_ctx,
sw_subchannel = gpr_malloc(sizeof(*sw_subchannel));
sw_subchannel->subchannel = c;
sw_subchannel->connectivity_state = GRPC_CHANNEL_READY;
grpc_closure_init(&sw_subchannel->closure, subchannel_on_child_state_changed,
GRPC_CLOSURE_INIT(&sw_subchannel->closure, subchannel_on_child_state_changed,
sw_subchannel, grpc_schedule_on_exec_ctx);
if (c->disconnected) {
@ -819,10 +809,7 @@ const char *grpc_get_subchannel_address_uri_arg(const grpc_channel_args *args) {
}
grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address *addr) {
grpc_arg new_arg;
new_arg.key = GRPC_ARG_SUBCHANNEL_ADDRESS;
new_arg.type = GRPC_ARG_STRING;
new_arg.value.string =
addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup("");
return new_arg;
return grpc_channel_arg_string_create(
GRPC_ARG_SUBCHANNEL_ADDRESS,
addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup(""));
}

@ -37,7 +37,7 @@ typedef struct grpc_subchannel_call grpc_subchannel_call;
typedef struct grpc_subchannel_args grpc_subchannel_args;
typedef struct grpc_subchannel_key grpc_subchannel_key;
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
#ifndef NDEBUG
#define GRPC_SUBCHANNEL_REF(p, r) \
grpc_subchannel_ref((p), __FILE__, __LINE__, (r))
#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \

@ -74,7 +74,7 @@ retry:
// If we've already created and destroyed a timer, we always create a
// new closure: we have no other guarantee that the inlined closure is
// not in use (it may hold a pending call to timer_callback)
closure = grpc_closure_create(timer_callback, elem,
closure = GRPC_CLOSURE_CREATE(timer_callback, elem,
grpc_schedule_on_exec_ctx);
} else {
goto retry;
@ -85,7 +85,7 @@ retry:
GRPC_DEADLINE_STATE_INITIAL,
GRPC_DEADLINE_STATE_PENDING)) {
closure =
grpc_closure_init(&deadline_state->timer_callback, timer_callback,
GRPC_CLOSURE_INIT(&deadline_state->timer_callback, timer_callback,
elem, grpc_schedule_on_exec_ctx);
} else {
goto retry;
@ -115,7 +115,7 @@ static void on_complete(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
grpc_deadline_state* deadline_state = arg;
cancel_timer_if_needed(exec_ctx, deadline_state);
// Invoke the next callback.
grpc_closure_run(exec_ctx, deadline_state->next_on_complete,
GRPC_CLOSURE_RUN(exec_ctx, deadline_state->next_on_complete,
GRPC_ERROR_REF(error));
}
@ -123,7 +123,7 @@ static void on_complete(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
static void inject_on_complete_cb(grpc_deadline_state* deadline_state,
grpc_transport_stream_op_batch* op) {
deadline_state->next_on_complete = op->on_complete;
grpc_closure_init(&deadline_state->on_complete, on_complete, deadline_state,
GRPC_CLOSURE_INIT(&deadline_state->on_complete, on_complete, deadline_state,
grpc_schedule_on_exec_ctx);
op->on_complete = &deadline_state->on_complete;
}
@ -161,9 +161,9 @@ void grpc_deadline_state_init(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
struct start_timer_after_init_state* state = gpr_malloc(sizeof(*state));
state->elem = elem;
state->deadline = deadline;
grpc_closure_init(&state->closure, start_timer_after_init, state,
GRPC_CLOSURE_INIT(&state->closure, start_timer_after_init, state,
grpc_schedule_on_exec_ctx);
grpc_closure_sched(exec_ctx, &state->closure, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, &state->closure, GRPC_ERROR_NONE);
}
}
@ -281,7 +281,7 @@ static void server_start_transport_stream_op_batch(
op->payload->recv_initial_metadata.recv_initial_metadata_ready;
calld->recv_initial_metadata =
op->payload->recv_initial_metadata.recv_initial_metadata;
grpc_closure_init(&calld->recv_initial_metadata_ready,
GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready,
recv_initial_metadata_ready, elem,
grpc_schedule_on_exec_ctx);
op->payload->recv_initial_metadata.recv_initial_metadata_ready =

@ -158,7 +158,7 @@ static void hc_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx,
} else {
GRPC_ERROR_REF(error);
}
grpc_closure_run(exec_ctx, calld->on_done_recv_initial_metadata, error);
GRPC_CLOSURE_RUN(exec_ctx, calld->on_done_recv_initial_metadata, error);
}
static void hc_on_recv_trailing_metadata(grpc_exec_ctx *exec_ctx,
@ -171,7 +171,7 @@ static void hc_on_recv_trailing_metadata(grpc_exec_ctx *exec_ctx,
} else {
GRPC_ERROR_REF(error);
}
grpc_closure_run(exec_ctx, calld->on_done_recv_trailing_metadata, error);
GRPC_CLOSURE_RUN(exec_ctx, calld->on_done_recv_trailing_metadata, error);
}
static void hc_on_complete(grpc_exec_ctx *exec_ctx, void *user_data,
@ -445,17 +445,17 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
calld->payload_bytes = NULL;
calld->send_message_blocked = false;
grpc_slice_buffer_init(&calld->slices);
grpc_closure_init(&calld->hc_on_recv_initial_metadata,
GRPC_CLOSURE_INIT(&calld->hc_on_recv_initial_metadata,
hc_on_recv_initial_metadata, elem,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&calld->hc_on_recv_trailing_metadata,
GRPC_CLOSURE_INIT(&calld->hc_on_recv_trailing_metadata,
hc_on_recv_trailing_metadata, elem,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&calld->hc_on_complete, hc_on_complete, elem,
GRPC_CLOSURE_INIT(&calld->hc_on_complete, hc_on_complete, elem,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&calld->got_slice, got_slice, elem,
GRPC_CLOSURE_INIT(&calld->got_slice, got_slice, elem,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&calld->send_done, send_done, elem,
GRPC_CLOSURE_INIT(&calld->send_done, send_done, elem,
grpc_schedule_on_exec_ctx);
return GRPC_ERROR_NONE;
}

@ -255,6 +255,23 @@ static void continue_send_message(grpc_exec_ctx *exec_ctx,
}
}
static void handle_send_message_batch(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_transport_stream_op_batch *op,
bool has_compression_algorithm) {
call_data *calld = elem->call_data;
if (!skip_compression(elem, op->payload->send_message.send_message->flags,
has_compression_algorithm)) {
calld->send_op = op;
calld->send_length = op->payload->send_message.send_message->length;
calld->send_flags = op->payload->send_message.send_message->flags;
continue_send_message(exec_ctx, elem);
} else {
/* pass control down the stack */
grpc_call_next_op(exec_ctx, elem, op);
}
}
static void compress_start_transport_stream_op_batch(
grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_transport_stream_op_batch *op) {
@ -307,8 +324,9 @@ static void compress_start_transport_stream_op_batch(
goto retry_send_im;
}
if (cur != INITIAL_METADATA_UNSEEN) {
grpc_call_next_op(exec_ctx, elem,
(grpc_transport_stream_op_batch *)cur);
handle_send_message_batch(exec_ctx, elem,
(grpc_transport_stream_op_batch *)cur,
has_compression_algorithm);
}
}
}
@ -325,17 +343,8 @@ static void compress_start_transport_stream_op_batch(
break;
case HAS_COMPRESSION_ALGORITHM:
case NO_COMPRESSION_ALGORITHM:
if (!skip_compression(elem,
op->payload->send_message.send_message->flags,
cur == HAS_COMPRESSION_ALGORITHM)) {
calld->send_op = op;
calld->send_length = op->payload->send_message.send_message->length;
calld->send_flags = op->payload->send_message.send_message->flags;
continue_send_message(exec_ctx, elem);
} else {
/* pass control down the stack */
grpc_call_next_op(exec_ctx, elem, op);
}
handle_send_message_batch(exec_ctx, elem, op,
cur == HAS_COMPRESSION_ALGORITHM);
break;
default:
if (cur & CANCELLED_BIT) {
@ -364,9 +373,9 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
/* initialize members */
grpc_slice_buffer_init(&calld->slices);
grpc_closure_init(&calld->got_slice, got_slice, elem,
GRPC_CLOSURE_INIT(&calld->got_slice, got_slice, elem,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&calld->send_done, send_done, elem,
GRPC_CLOSURE_INIT(&calld->send_done, send_done, elem,
grpc_schedule_on_exec_ctx);
return GRPC_ERROR_NONE;

@ -269,7 +269,7 @@ static void hs_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
} else {
GRPC_ERROR_REF(err);
}
grpc_closure_run(exec_ctx, calld->on_done_recv, err);
GRPC_CLOSURE_RUN(exec_ctx, calld->on_done_recv, err);
}
static void hs_on_complete(grpc_exec_ctx *exec_ctx, void *user_data,
@ -281,11 +281,11 @@ static void hs_on_complete(grpc_exec_ctx *exec_ctx, void *user_data,
*calld->pp_recv_message = calld->payload_bin_delivered
? NULL
: (grpc_byte_stream *)&calld->read_stream;
grpc_closure_run(exec_ctx, calld->recv_message_ready, GRPC_ERROR_REF(err));
GRPC_CLOSURE_RUN(exec_ctx, calld->recv_message_ready, GRPC_ERROR_REF(err));
calld->recv_message_ready = NULL;
calld->payload_bin_delivered = true;
}
grpc_closure_run(exec_ctx, calld->on_complete, GRPC_ERROR_REF(err));
GRPC_CLOSURE_RUN(exec_ctx, calld->on_complete, GRPC_ERROR_REF(err));
}
static void hs_recv_message_ready(grpc_exec_ctx *exec_ctx, void *user_data,
@ -296,7 +296,7 @@ static void hs_recv_message_ready(grpc_exec_ctx *exec_ctx, void *user_data,
/* do nothing. This is probably a GET request, and payload will be returned
in hs_on_complete callback. */
} else {
grpc_closure_run(exec_ctx, calld->recv_message_ready, GRPC_ERROR_REF(err));
GRPC_CLOSURE_RUN(exec_ctx, calld->recv_message_ready, GRPC_ERROR_REF(err));
}
}
@ -383,11 +383,11 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
/* grab pointers to our data from the call element */
call_data *calld = elem->call_data;
/* initialize members */
grpc_closure_init(&calld->hs_on_recv, hs_on_recv, elem,
GRPC_CLOSURE_INIT(&calld->hs_on_recv, hs_on_recv, elem,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&calld->hs_on_complete, hs_on_complete, elem,
GRPC_CLOSURE_INIT(&calld->hs_on_complete, hs_on_complete, elem,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&calld->hs_recv_message_ready, hs_recv_message_ready, elem,
GRPC_CLOSURE_INIT(&calld->hs_recv_message_ready, hs_recv_message_ready, elem,
grpc_schedule_on_exec_ctx);
grpc_slice_buffer_init(&calld->read_slice_buffer);
return GRPC_ERROR_NONE;

@ -50,11 +50,7 @@ static bool maybe_add_load_reporting_filter(grpc_exec_ctx *exec_ctx,
}
grpc_arg grpc_load_reporting_enable_arg() {
grpc_arg arg;
arg.type = GRPC_ARG_INTEGER;
arg.key = GRPC_ARG_ENABLE_LOAD_REPORTING;
arg.value.integer = 1;
return arg;
return grpc_channel_arg_integer_create(GRPC_ARG_ENABLE_LOAD_REPORTING, 1);
}
/* Plugin registration */

@ -90,7 +90,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
const grpc_call_element_args *args) {
call_data *calld = elem->call_data;
calld->id = (intptr_t)args->call_stack;
grpc_closure_init(&calld->on_initial_md_ready, on_initial_md_ready, elem,
GRPC_CLOSURE_INIT(&calld->on_initial_md_ready, on_initial_md_ready, elem,
grpc_schedule_on_exec_ctx);
/* TODO(dgq): do something with the data

@ -329,23 +329,23 @@ static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
: gpr_time_from_millis(value, GPR_TIMESPAN);
}
}
grpc_closure_init(&chand->close_max_idle_channel, close_max_idle_channel,
GRPC_CLOSURE_INIT(&chand->close_max_idle_channel, close_max_idle_channel,
chand, grpc_schedule_on_exec_ctx);
grpc_closure_init(&chand->close_max_age_channel, close_max_age_channel, chand,
GRPC_CLOSURE_INIT(&chand->close_max_age_channel, close_max_age_channel, chand,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&chand->force_close_max_age_channel,
GRPC_CLOSURE_INIT(&chand->force_close_max_age_channel,
force_close_max_age_channel, chand,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&chand->start_max_idle_timer_after_init,
GRPC_CLOSURE_INIT(&chand->start_max_idle_timer_after_init,
start_max_idle_timer_after_init, chand,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&chand->start_max_age_timer_after_init,
GRPC_CLOSURE_INIT(&chand->start_max_age_timer_after_init,
start_max_age_timer_after_init, chand,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&chand->start_max_age_grace_timer_after_goaway_op,
GRPC_CLOSURE_INIT(&chand->start_max_age_grace_timer_after_goaway_op,
start_max_age_grace_timer_after_goaway_op, chand,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&chand->channel_connectivity_changed,
GRPC_CLOSURE_INIT(&chand->channel_connectivity_changed,
channel_connectivity_changed, chand,
grpc_schedule_on_exec_ctx);
@ -360,7 +360,7 @@ static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
initialization is done. */
GRPC_CHANNEL_STACK_REF(chand->channel_stack,
"max_age start_max_age_timer_after_init");
grpc_closure_sched(exec_ctx, &chand->start_max_age_timer_after_init,
GRPC_CLOSURE_SCHED(exec_ctx, &chand->start_max_age_timer_after_init,
GRPC_ERROR_NONE);
}
@ -371,7 +371,7 @@ static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
0) {
GRPC_CHANNEL_STACK_REF(chand->channel_stack,
"max_age start_max_idle_timer_after_init");
grpc_closure_sched(exec_ctx, &chand->start_max_idle_timer_after_init,
GRPC_CLOSURE_SCHED(exec_ctx, &chand->start_max_idle_timer_after_init,
GRPC_ERROR_NONE);
}
return GRPC_ERROR_NONE;

@ -110,7 +110,7 @@ static void recv_message_ready(grpc_exec_ctx* exec_ctx, void* user_data,
GRPC_ERROR_REF(error);
}
// Invoke the next callback.
grpc_closure_run(exec_ctx, calld->next_recv_message_ready, error);
GRPC_CLOSURE_RUN(exec_ctx, calld->next_recv_message_ready, error);
}
// Start transport stream op.
@ -152,7 +152,7 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
channel_data* chand = elem->channel_data;
call_data* calld = elem->call_data;
calld->next_recv_message_ready = NULL;
grpc_closure_init(&calld->recv_message_ready, recv_message_ready, elem,
GRPC_CLOSURE_INIT(&calld->recv_message_ready, recv_message_ready, elem,
grpc_schedule_on_exec_ctx);
// Get max sizes from channel data, then merge in per-method config values.
// Note: Per-method config is only available on the client, so we

@ -67,7 +67,7 @@ static void recv_initial_metadata_ready(grpc_exec_ctx* exec_ctx,
}
// Invoke the next callback.
grpc_closure_run(exec_ctx, calld->next_recv_initial_metadata_ready,
GRPC_CLOSURE_RUN(exec_ctx, calld->next_recv_initial_metadata_ready,
GRPC_ERROR_REF(error));
}
@ -106,7 +106,7 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
call_data* calld = elem->call_data;
calld->next_recv_initial_metadata_ready = NULL;
calld->workaround_active = false;
grpc_closure_init(&calld->recv_initial_metadata_ready,
GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready,
recv_initial_metadata_ready, elem,
grpc_schedule_on_exec_ctx);
return GRPC_ERROR_NONE;

@ -124,7 +124,7 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
}
grpc_closure *notify = c->notify;
c->notify = NULL;
grpc_closure_sched(exec_ctx, notify, error);
GRPC_CLOSURE_SCHED(exec_ctx, notify, error);
grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr);
c->handshake_mgr = NULL;
gpr_mu_unlock(&c->mu);
@ -156,7 +156,7 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
memset(c->result, 0, sizeof(*c->result));
grpc_closure *notify = c->notify;
c->notify = NULL;
grpc_closure_sched(exec_ctx, notify, error);
GRPC_CLOSURE_SCHED(exec_ctx, notify, error);
if (c->endpoint != NULL) {
grpc_endpoint_shutdown(exec_ctx, c->endpoint, GRPC_ERROR_REF(error));
}
@ -184,7 +184,7 @@ static void chttp2_connector_connect(grpc_exec_ctx *exec_ctx,
c->result = result;
GPR_ASSERT(c->endpoint == NULL);
chttp2_connector_ref(con); // Ref taken for callback.
grpc_closure_init(&c->connected, connected, c, grpc_schedule_on_exec_ctx);
GRPC_CLOSURE_INIT(&c->connected, connected, c, grpc_schedule_on_exec_ctx);
GPR_ASSERT(!c->connecting);
c->connecting = true;
grpc_tcp_client_connect(exec_ctx, &c->connected, &c->endpoint,

@ -54,11 +54,9 @@ static grpc_channel *client_channel_factory_create_channel(
return NULL;
}
// Add channel arg containing the server URI.
grpc_arg arg;
arg.type = GRPC_ARG_STRING;
arg.key = GRPC_ARG_SERVER_URI;
arg.value.string =
grpc_resolver_factory_add_default_prefix_if_needed(exec_ctx, target);
grpc_arg arg = grpc_channel_arg_string_create(
GRPC_ARG_SERVER_URI,
grpc_resolver_factory_add_default_prefix_if_needed(exec_ctx, target));
const char *to_remove[] = {GRPC_ARG_SERVER_URI};
grpc_channel_args *new_args =
grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1);

@ -41,10 +41,8 @@ grpc_channel *grpc_insecure_channel_create_from_fd(
GRPC_API_TRACE("grpc_insecure_channel_create(target=%p, fd=%d, args=%p)", 3,
(target, fd, args));
grpc_arg default_authority_arg;
default_authority_arg.type = GRPC_ARG_STRING;
default_authority_arg.key = GRPC_ARG_DEFAULT_AUTHORITY;
default_authority_arg.value.string = "test.authority";
grpc_arg default_authority_arg = grpc_channel_arg_string_create(
GRPC_ARG_DEFAULT_AUTHORITY, "test.authority");
grpc_channel_args *final_args =
grpc_channel_args_copy_and_add(args, &default_authority_arg, 1);

@ -163,11 +163,9 @@ static grpc_channel *client_channel_factory_create_channel(
return NULL;
}
// Add channel arg containing the server URI.
grpc_arg arg;
arg.type = GRPC_ARG_STRING;
arg.key = GRPC_ARG_SERVER_URI;
arg.value.string =
grpc_resolver_factory_add_default_prefix_if_needed(exec_ctx, target);
grpc_arg arg = grpc_channel_arg_string_create(
GRPC_ARG_SERVER_URI,
grpc_resolver_factory_add_default_prefix_if_needed(exec_ctx, target));
const char *to_remove[] = {GRPC_ARG_SERVER_URI};
grpc_channel_args *new_args =
grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1);

@ -209,7 +209,7 @@ grpc_error *grpc_chttp2_server_add_port(grpc_exec_ctx *exec_ctx,
goto error;
}
state = gpr_zalloc(sizeof(*state));
grpc_closure_init(&state->tcp_server_shutdown_complete,
GRPC_CLOSURE_INIT(&state->tcp_server_shutdown_complete,
tcp_server_shutdown_complete, state,
grpc_schedule_on_exec_ctx);
err = grpc_tcp_server_create(exec_ctx, &state->tcp_server_shutdown_complete,

@ -23,6 +23,9 @@
void grpc_chttp2_plugin_init(void) {
grpc_register_tracer("http", &grpc_http_trace);
grpc_register_tracer("flowctl", &grpc_flowctl_trace);
#ifndef NDEBUG
grpc_register_tracer("chttp2_refcount", &grpc_trace_chttp2_refcount);
#endif
}
void grpc_chttp2_plugin_shutdown(void) {}

@ -35,7 +35,6 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/iomgr/workqueue.h"
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
@ -53,7 +52,7 @@
#define DEFAULT_CONNECTION_WINDOW_TARGET (1024 * 1024)
#define MAX_WINDOW 0x7fffffffu
#define MAX_WRITE_BUFFER_SIZE (64 * 1024 * 1024)
#define DEFAULT_MAX_HEADER_LIST_SIZE (16 * 1024)
#define DEFAULT_MAX_HEADER_LIST_SIZE (8 * 1024)
#define DEFAULT_CLIENT_KEEPALIVE_TIME_MS INT_MAX
#define DEFAULT_CLIENT_KEEPALIVE_TIMEOUT_MS 20000 /* 20 seconds */
@ -77,6 +76,10 @@ static bool g_default_keepalive_permit_without_calls =
grpc_tracer_flag grpc_http_trace = GRPC_TRACER_INITIALIZER(false);
grpc_tracer_flag grpc_flowctl_trace = GRPC_TRACER_INITIALIZER(false);
#ifndef NDEBUG
grpc_tracer_flag grpc_trace_chttp2_refcount = GRPC_TRACER_INITIALIZER(false);
#endif
static const grpc_transport_vtable vtable;
/* forward declarations of various callbacks that we'll build closures around */
@ -92,8 +95,9 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *t,
static void complete_fetch_locked(grpc_exec_ctx *exec_ctx, void *gs,
grpc_error *error);
/** Set a transport level setting, and push it to our peer */
static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_chttp2_setting_id id, uint32_t value);
static void queue_setting_update(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t,
grpc_chttp2_setting_id id, uint32_t value);
static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_chttp2_stream *s, grpc_error *error);
@ -213,20 +217,26 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
gpr_free(t);
}
#ifdef GRPC_CHTTP2_REFCOUNTING_DEBUG
#ifndef NDEBUG
void grpc_chttp2_unref_transport(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t, const char *reason,
const char *file, int line) {
gpr_log(GPR_DEBUG, "chttp2:unref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]", t,
t->refs.count, t->refs.count - 1, reason, file, line);
if (GRPC_TRACER_ON(grpc_trace_chttp2_refcount)) {
gpr_atm val = gpr_atm_no_barrier_load(&t->refs.count);
gpr_log(GPR_DEBUG, "chttp2:unref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]",
t, val, val - 1, reason, file, line);
}
if (!gpr_unref(&t->refs)) return;
destruct_transport(exec_ctx, t);
}
void grpc_chttp2_ref_transport(grpc_chttp2_transport *t, const char *reason,
const char *file, int line) {
gpr_log(GPR_DEBUG, "chttp2: ref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]", t,
t->refs.count, t->refs.count + 1, reason, file, line);
if (GRPC_TRACER_ON(grpc_trace_chttp2_refcount)) {
gpr_atm val = gpr_atm_no_barrier_load(&t->refs.count);
gpr_log(GPR_DEBUG, "chttp2: ref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]",
t, val, val + 1, reason, file, line);
}
gpr_ref(&t->refs);
}
#else
@ -252,7 +262,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->ep = ep;
/* one ref is for destroy */
gpr_ref_init(&t->refs, 1);
t->combiner = grpc_combiner_create(grpc_endpoint_get_workqueue(ep));
t->combiner = grpc_combiner_create();
t->peer_string = grpc_endpoint_get_peer(ep);
t->endpoint_reading = 1;
t->next_stream_id = is_client ? 1 : 2;
@ -270,32 +280,32 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_slice_buffer_init(&t->outbuf);
grpc_chttp2_hpack_compressor_init(&t->hpack_compressor);
grpc_closure_init(&t->write_action, write_action, t,
GRPC_CLOSURE_INIT(&t->write_action, write_action, t,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&t->read_action_locked, read_action_locked, t,
grpc_combiner_scheduler(t->combiner, false));
grpc_closure_init(&t->benign_reclaimer_locked, benign_reclaimer_locked, t,
grpc_combiner_scheduler(t->combiner, false));
grpc_closure_init(&t->destructive_reclaimer_locked,
GRPC_CLOSURE_INIT(&t->read_action_locked, read_action_locked, t,
grpc_combiner_scheduler(t->combiner));
GRPC_CLOSURE_INIT(&t->benign_reclaimer_locked, benign_reclaimer_locked, t,
grpc_combiner_scheduler(t->combiner));
GRPC_CLOSURE_INIT(&t->destructive_reclaimer_locked,
destructive_reclaimer_locked, t,
grpc_combiner_scheduler(t->combiner, false));
grpc_closure_init(&t->retry_initiate_ping_locked, retry_initiate_ping_locked,
t, grpc_combiner_scheduler(t->combiner, false));
grpc_closure_init(&t->start_bdp_ping_locked, start_bdp_ping_locked, t,
grpc_combiner_scheduler(t->combiner, false));
grpc_closure_init(&t->finish_bdp_ping_locked, finish_bdp_ping_locked, t,
grpc_combiner_scheduler(t->combiner, false));
grpc_closure_init(&t->init_keepalive_ping_locked, init_keepalive_ping_locked,
t, grpc_combiner_scheduler(t->combiner, false));
grpc_closure_init(&t->start_keepalive_ping_locked,
grpc_combiner_scheduler(t->combiner));
GRPC_CLOSURE_INIT(&t->retry_initiate_ping_locked, retry_initiate_ping_locked,
t, grpc_combiner_scheduler(t->combiner));
GRPC_CLOSURE_INIT(&t->start_bdp_ping_locked, start_bdp_ping_locked, t,
grpc_combiner_scheduler(t->combiner));
GRPC_CLOSURE_INIT(&t->finish_bdp_ping_locked, finish_bdp_ping_locked, t,
grpc_combiner_scheduler(t->combiner));
GRPC_CLOSURE_INIT(&t->init_keepalive_ping_locked, init_keepalive_ping_locked,
t, grpc_combiner_scheduler(t->combiner));
GRPC_CLOSURE_INIT(&t->start_keepalive_ping_locked,
start_keepalive_ping_locked, t,
grpc_combiner_scheduler(t->combiner, false));
grpc_closure_init(&t->finish_keepalive_ping_locked,
grpc_combiner_scheduler(t->combiner));
GRPC_CLOSURE_INIT(&t->finish_keepalive_ping_locked,
finish_keepalive_ping_locked, t,
grpc_combiner_scheduler(t->combiner, false));
grpc_closure_init(&t->keepalive_watchdog_fired_locked,
grpc_combiner_scheduler(t->combiner));
GRPC_CLOSURE_INIT(&t->keepalive_watchdog_fired_locked,
keepalive_watchdog_fired_locked, t,
grpc_combiner_scheduler(t->combiner, false));
grpc_combiner_scheduler(t->combiner));
grpc_bdp_estimator_init(&t->bdp_estimator, t->peer_string);
t->last_pid_update = gpr_now(GPR_CLOCK_MONOTONIC);
@ -338,20 +348,21 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
if (is_client) {
grpc_slice_buffer_add(&t->outbuf, grpc_slice_from_copied_string(
GRPC_CHTTP2_CLIENT_CONNECT_STRING));
grpc_chttp2_initiate_write(exec_ctx, t, false, "initial_write");
grpc_chttp2_initiate_write(exec_ctx, t, "initial_write");
}
/* configure http2 the way we like it */
if (is_client) {
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_ENABLE_PUSH, 0);
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0);
queue_setting_update(exec_ctx, t, GRPC_CHTTP2_SETTINGS_ENABLE_PUSH, 0);
queue_setting_update(exec_ctx, t,
GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0);
}
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
DEFAULT_WINDOW);
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
DEFAULT_MAX_HEADER_LIST_SIZE);
push_setting(exec_ctx, t,
GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA, 1);
queue_setting_update(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
DEFAULT_WINDOW);
queue_setting_update(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
DEFAULT_MAX_HEADER_LIST_SIZE);
queue_setting_update(exec_ctx, t,
GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA, 1);
t->ping_policy = (grpc_chttp2_repeated_ping_policy){
.max_pings_without_data = DEFAULT_MAX_PINGS_BETWEEN_DATA,
@ -518,8 +529,8 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
int value = grpc_channel_arg_get_integer(
&channel_args->args[i], settings_map[j].integer_options);
if (value >= 0) {
push_setting(exec_ctx, t, settings_map[j].setting_id,
(uint32_t)value);
queue_setting_update(exec_ctx, t, settings_map[j].setting_id,
(uint32_t)value);
}
}
break;
@ -550,7 +561,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED;
}
grpc_chttp2_initiate_write(exec_ctx, t, false, "init");
grpc_chttp2_initiate_write(exec_ctx, t, "init");
post_benign_reclaimer(exec_ctx, t);
}
@ -568,9 +579,9 @@ static void destroy_transport_locked(grpc_exec_ctx *exec_ctx, void *tp,
static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {
grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
grpc_closure_sched(exec_ctx, grpc_closure_create(
destroy_transport_locked, t,
grpc_combiner_scheduler(t->combiner, false)),
GRPC_CLOSURE_SCHED(exec_ctx,
GRPC_CLOSURE_CREATE(destroy_transport_locked, t,
grpc_combiner_scheduler(t->combiner)),
GRPC_ERROR_NONE);
}
@ -621,7 +632,7 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
GRPC_ERROR_UNREF(error);
}
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
#ifndef NDEBUG
void grpc_chttp2_stream_ref(grpc_chttp2_stream *s, const char *reason) {
grpc_stream_ref(s->refcount, reason);
}
@ -657,13 +668,13 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
grpc_chttp2_data_parser_init(&s->data_parser);
grpc_slice_buffer_init(&s->flow_controlled_buffer);
s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
grpc_closure_init(&s->complete_fetch_locked, complete_fetch_locked, s,
GRPC_CLOSURE_INIT(&s->complete_fetch_locked, complete_fetch_locked, s,
grpc_schedule_on_exec_ctx);
grpc_slice_buffer_init(&s->unprocessed_incoming_frames_buffer);
grpc_slice_buffer_init(&s->frame_storage);
s->pending_byte_stream = false;
grpc_closure_init(&s->reset_byte_stream, reset_byte_stream, s,
grpc_combiner_scheduler(t->combiner, false));
GRPC_CLOSURE_INIT(&s->reset_byte_stream, reset_byte_stream, s,
grpc_combiner_scheduler(t->combiner));
GRPC_CHTTP2_REF_TRANSPORT(t, "stream");
@ -734,7 +745,7 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
GPR_TIMER_END("destroy_stream", 0);
grpc_closure_sched(exec_ctx, s->destroy_stream_arg, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, s->destroy_stream_arg, GRPC_ERROR_NONE);
}
static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
@ -745,9 +756,9 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs;
s->destroy_stream_arg = then_schedule_closure;
grpc_closure_sched(
exec_ctx, grpc_closure_init(&s->destroy_stream, destroy_stream_locked, s,
grpc_combiner_scheduler(t->combiner, false)),
GRPC_CLOSURE_SCHED(
exec_ctx, GRPC_CLOSURE_INIT(&s->destroy_stream, destroy_stream_locked, s,
grpc_combiner_scheduler(t->combiner)),
GRPC_ERROR_NONE);
GPR_TIMER_END("destroy_stream", 0);
}
@ -785,8 +796,6 @@ static const char *write_state_name(grpc_chttp2_write_state st) {
return "WRITING";
case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE:
return "WRITING+MORE";
case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER:
return "WRITING+MORE+COVERED";
}
GPR_UNREACHABLE_CODE(return "UNKNOWN");
}
@ -799,7 +808,7 @@ static void set_write_state(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
write_state_name(st), reason));
t->write_state = st;
if (st == GRPC_CHTTP2_WRITE_STATE_IDLE) {
grpc_closure_list_sched(exec_ctx, &t->run_after_write);
GRPC_CLOSURE_LIST_SCHED(exec_ctx, &t->run_after_write);
if (t->close_transport_on_writes_finished != NULL) {
grpc_error *err = t->close_transport_on_writes_finished;
t->close_transport_on_writes_finished = NULL;
@ -809,38 +818,25 @@ static void set_write_state(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
}
void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t,
bool covered_by_poller, const char *reason) {
grpc_chttp2_transport *t, const char *reason) {
GPR_TIMER_BEGIN("grpc_chttp2_initiate_write", 0);
switch (t->write_state) {
case GRPC_CHTTP2_WRITE_STATE_IDLE:
set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING, reason);
GRPC_CHTTP2_REF_TRANSPORT(t, "writing");
grpc_closure_sched(
GRPC_CLOSURE_SCHED(
exec_ctx,
grpc_closure_init(
&t->write_action_begin_locked, write_action_begin_locked, t,
grpc_combiner_finally_scheduler(t->combiner, covered_by_poller)),
GRPC_CLOSURE_INIT(&t->write_action_begin_locked,
write_action_begin_locked, t,
grpc_combiner_finally_scheduler(t->combiner)),
GRPC_ERROR_NONE);
break;
case GRPC_CHTTP2_WRITE_STATE_WRITING:
set_write_state(
exec_ctx, t,
covered_by_poller
? GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER
: GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE,
reason);
set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE,
reason);
break;
case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE:
if (covered_by_poller) {
set_write_state(
exec_ctx, t,
GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER,
reason);
}
break;
case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER:
break;
}
GPR_TIMER_END("grpc_chttp2_initiate_write", 0);
@ -856,10 +852,10 @@ void grpc_chttp2_become_writable(
case GRPC_CHTTP2_STREAM_WRITE_PIGGYBACK:
break;
case GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED:
grpc_chttp2_initiate_write(exec_ctx, t, true, reason);
grpc_chttp2_initiate_write(exec_ctx, t, reason);
break;
case GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED:
grpc_chttp2_initiate_write(exec_ctx, t, false, reason);
grpc_chttp2_initiate_write(exec_ctx, t, reason);
break;
}
}
@ -879,12 +875,12 @@ static void write_action_begin_locked(grpc_exec_ctx *exec_ctx, void *gt,
case GRPC_CHTTP2_PARTIAL_WRITE:
set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE,
"begin writing partial");
grpc_closure_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, &t->write_action, GRPC_ERROR_NONE);
break;
case GRPC_CHTTP2_FULL_WRITE:
set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING,
"begin writing");
grpc_closure_sched(exec_ctx, &t->write_action, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, &t->write_action, GRPC_ERROR_NONE);
break;
}
GPR_TIMER_END("write_action_begin_locked", 0);
@ -895,8 +891,8 @@ static void write_action(grpc_exec_ctx *exec_ctx, void *gt, grpc_error *error) {
GPR_TIMER_BEGIN("write_action", 0);
grpc_endpoint_write(
exec_ctx, t->ep, &t->outbuf,
grpc_closure_init(&t->write_action_end_locked, write_action_end_locked, t,
grpc_combiner_scheduler(t->combiner, false)));
GRPC_CLOSURE_INIT(&t->write_action_end_locked, write_action_end_locked, t,
grpc_combiner_scheduler(t->combiner)));
GPR_TIMER_END("write_action", 0);
}
@ -930,23 +926,11 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp,
set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING,
"continue writing [!covered]");
GRPC_CHTTP2_REF_TRANSPORT(t, "writing");
grpc_closure_run(
GRPC_CLOSURE_RUN(
exec_ctx,
grpc_closure_init(
&t->write_action_begin_locked, write_action_begin_locked, t,
grpc_combiner_finally_scheduler(t->combiner, false)),
GRPC_ERROR_NONE);
break;
case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER:
GPR_TIMER_MARK("state=writing_stale_with_poller", 0);
set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING,
"continue writing [covered]");
GRPC_CHTTP2_REF_TRANSPORT(t, "writing");
grpc_closure_run(
exec_ctx,
grpc_closure_init(&t->write_action_begin_locked,
GRPC_CLOSURE_INIT(&t->write_action_begin_locked,
write_action_begin_locked, t,
grpc_combiner_finally_scheduler(t->combiner, true)),
grpc_combiner_finally_scheduler(t->combiner)),
GRPC_ERROR_NONE);
break;
}
@ -957,8 +941,11 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp,
GPR_TIMER_END("terminate_writing_with_lock", 0);
}
static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_chttp2_setting_id id, uint32_t value) {
// Dirties an HTTP2 setting to be sent out next time a writing path occurs.
// If the change needs to occur immediately, manually initiate a write.
static void queue_setting_update(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t,
grpc_chttp2_setting_id id, uint32_t value) {
const grpc_chttp2_setting_parameters *sp =
&grpc_chttp2_settings_parameters[id];
uint32_t use_value = GPR_CLAMP(value, sp->min_value, sp->max_value);
@ -969,7 +956,6 @@ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
if (use_value != t->settings[GRPC_LOCAL_SETTINGS][id]) {
t->settings[GRPC_LOCAL_SETTINGS][id] = use_value;
t->dirtied_local_settings = 1;
grpc_chttp2_initiate_write(exec_ctx, t, false, "push_setting");
}
}
@ -1074,7 +1060,7 @@ static void null_then_run_closure(grpc_exec_ctx *exec_ctx,
grpc_closure **closure, grpc_error *error) {
grpc_closure *c = *closure;
*closure = NULL;
grpc_closure_run(exec_ctx, c, error);
GRPC_CLOSURE_RUN(exec_ctx, c, error);
}
void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx,
@ -1116,7 +1102,7 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx,
}
if ((t->write_state == GRPC_CHTTP2_WRITE_STATE_IDLE) ||
!(closure->next_data.scratch & CLOSURE_BARRIER_MAY_COVER_WRITE)) {
grpc_closure_run(exec_ctx, closure, closure->error_data.error);
GRPC_CLOSURE_RUN(exec_ctx, closure, closure->error_data.error);
} else {
grpc_closure_list_append(&t->run_after_write, closure,
closure->error_data.error);
@ -1252,7 +1238,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
grpc_closure *on_complete = op->on_complete;
if (on_complete == NULL) {
on_complete =
grpc_closure_create(do_nothing, NULL, grpc_schedule_on_exec_ctx);
GRPC_CLOSURE_CREATE(do_nothing, NULL, grpc_schedule_on_exec_ctx);
}
/* use final_data as a barrier until enqueue time; the inital counter is
@ -1365,7 +1351,6 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
s->next_message_end_offset = s->flow_controlled_bytes_written +
(int64_t)s->flow_controlled_buffer.length +
(int64_t)len;
s->complete_fetch_covered_by_poller = op->covered_by_poller;
if (flags & GRPC_WRITE_BUFFER_HINT) {
s->next_message_end_offset -= t->write_buffer_size;
s->write_buffering = true;
@ -1432,6 +1417,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
op_payload->recv_initial_metadata.recv_initial_metadata_ready;
s->recv_initial_metadata =
op_payload->recv_initial_metadata.recv_initial_metadata;
s->trailing_metadata_available =
op_payload->recv_initial_metadata.trailing_metadata_available;
grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s);
}
@ -1485,11 +1472,10 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
op->handler_private.extra_arg = gs;
GRPC_CHTTP2_STREAM_REF(s, "perform_stream_op");
grpc_closure_sched(
GRPC_CLOSURE_SCHED(
exec_ctx,
grpc_closure_init(
&op->handler_private.closure, perform_stream_op_locked, op,
grpc_combiner_scheduler(t->combiner, op->covered_by_poller)),
GRPC_CLOSURE_INIT(&op->handler_private.closure, perform_stream_op_locked,
op, grpc_combiner_scheduler(t->combiner)),
GRPC_ERROR_NONE);
GPR_TIMER_END("perform_stream_op", 0);
}
@ -1502,7 +1488,7 @@ static void cancel_pings(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_chttp2_ping_queue *pq = &t->ping_queues[i];
for (size_t j = 0; j < GRPC_CHTTP2_PCL_COUNT; j++) {
grpc_closure_list_fail_all(&pq->lists[j], GRPC_ERROR_REF(error));
grpc_closure_list_sched(exec_ctx, &pq->lists[j]);
GRPC_CLOSURE_LIST_SCHED(exec_ctx, &pq->lists[j]);
}
}
GRPC_ERROR_UNREF(error);
@ -1516,7 +1502,7 @@ static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
GRPC_ERROR_NONE);
if (grpc_closure_list_append(&pq->lists[GRPC_CHTTP2_PCL_NEXT], on_ack,
GRPC_ERROR_NONE)) {
grpc_chttp2_initiate_write(exec_ctx, t, false, "send_ping");
grpc_chttp2_initiate_write(exec_ctx, t, "send_ping");
}
}
@ -1524,7 +1510,7 @@ static void retry_initiate_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
grpc_error *error) {
grpc_chttp2_transport *t = tp;
t->ping_state.is_delayed_ping_timer_set = false;
grpc_chttp2_initiate_write(exec_ctx, t, false, "retry_send_ping");
grpc_chttp2_initiate_write(exec_ctx, t, "retry_send_ping");
}
void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
@ -1537,9 +1523,9 @@ void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
gpr_free(from);
return;
}
grpc_closure_list_sched(exec_ctx, &pq->lists[GRPC_CHTTP2_PCL_INFLIGHT]);
GRPC_CLOSURE_LIST_SCHED(exec_ctx, &pq->lists[GRPC_CHTTP2_PCL_INFLIGHT]);
if (!grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_NEXT])) {
grpc_chttp2_initiate_write(exec_ctx, t, false, "continue_pings");
grpc_chttp2_initiate_write(exec_ctx, t, "continue_pings");
}
}
@ -1552,7 +1538,7 @@ static void send_goaway(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
&slice, &http_error);
grpc_chttp2_goaway_append(t->last_new_stream_id, (uint32_t)http_error,
grpc_slice_ref_internal(slice), &t->qbuf);
grpc_chttp2_initiate_write(exec_ctx, t, false, "goaway_sent");
grpc_chttp2_initiate_write(exec_ctx, t, "goaway_sent");
GRPC_ERROR_UNREF(error);
}
@ -1578,12 +1564,6 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t = op->handler_private.extra_arg;
grpc_error *close_transport = op->disconnect_with_error;
if (op->on_connectivity_state_change != NULL) {
grpc_connectivity_state_notify_on_state_change(
exec_ctx, &t->channel_callback.state_tracker, op->connectivity_state,
op->on_connectivity_state_change);
}
if (op->goaway_error) {
send_goaway(exec_ctx, t, op->goaway_error);
}
@ -1607,11 +1587,17 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
op->send_ping);
}
if (op->on_connectivity_state_change != NULL) {
grpc_connectivity_state_notify_on_state_change(
exec_ctx, &t->channel_callback.state_tracker, op->connectivity_state,
op->on_connectivity_state_change);
}
if (close_transport != GRPC_ERROR_NONE) {
close_transport_locked(exec_ctx, t, close_transport);
}
grpc_closure_run(exec_ctx, op->on_consumed, GRPC_ERROR_NONE);
GRPC_CLOSURE_RUN(exec_ctx, op->on_consumed, GRPC_ERROR_NONE);
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "transport_op");
}
@ -1623,11 +1609,11 @@ static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
gpr_free(msg);
op->handler_private.extra_arg = gt;
GRPC_CHTTP2_REF_TRANSPORT(t, "transport_op");
grpc_closure_sched(
exec_ctx, grpc_closure_init(&op->handler_private.closure,
perform_transport_op_locked, op,
grpc_combiner_scheduler(t->combiner, false)),
GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx,
GRPC_CLOSURE_INIT(&op->handler_private.closure,
perform_transport_op_locked, op,
grpc_combiner_scheduler(t->combiner)),
GRPC_ERROR_NONE);
}
/*******************************************************************************
@ -1782,7 +1768,7 @@ void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx,
grpc_slice_buffer_add(
&t->qbuf, grpc_chttp2_rst_stream_create(s->id, (uint32_t)http_error,
&s->stats.outgoing));
grpc_chttp2_initiate_write(exec_ctx, t, false, "rst_stream");
grpc_chttp2_initiate_write(exec_ctx, t, "rst_stream");
}
}
if (due_to_error != GRPC_ERROR_NONE && !s->seen_error) {
@ -2095,7 +2081,7 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
&s->stats.outgoing));
grpc_chttp2_mark_stream_closed(exec_ctx, t, s, 1, 1, error);
grpc_chttp2_initiate_write(exec_ctx, t, false, "close_from_api");
grpc_chttp2_initiate_write(exec_ctx, t, "close_from_api");
}
typedef struct {
@ -2137,8 +2123,8 @@ static void update_bdp(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
gpr_log(GPR_DEBUG, "%s: update initial window size to %d", t->peer_string,
(int)bdp);
}
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
(uint32_t)bdp);
queue_setting_update(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
(uint32_t)bdp);
}
static void update_frame(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
@ -2157,8 +2143,8 @@ static void update_frame(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
gpr_log(GPR_DEBUG, "%s: update max_frame size to %d", t->peer_string,
(int)frame_size);
}
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE,
(uint32_t)frame_size);
queue_setting_update(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE,
(uint32_t)frame_size);
}
static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx,
@ -2502,7 +2488,7 @@ static void reset_byte_stream(grpc_exec_ctx *exec_ctx, void *arg,
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, s->t, s);
} else {
GPR_ASSERT(error != GRPC_ERROR_NONE);
grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error));
GRPC_CLOSURE_SCHED(exec_ctx, s->on_next, GRPC_ERROR_REF(error));
s->on_next = NULL;
GRPC_ERROR_UNREF(s->byte_stream_error);
s->byte_stream_error = GRPC_ERROR_NONE;
@ -2581,9 +2567,9 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx,
if (s->frame_storage.length > 0) {
grpc_slice_buffer_swap(&s->frame_storage,
&s->unprocessed_incoming_frames_buffer);
grpc_closure_sched(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE);
} else if (s->byte_stream_error != GRPC_ERROR_NONE) {
grpc_closure_sched(exec_ctx, bs->next_action.on_complete,
GRPC_CLOSURE_SCHED(exec_ctx, bs->next_action.on_complete,
GRPC_ERROR_REF(s->byte_stream_error));
if (s->data_parser.parsing_frame != NULL) {
incoming_byte_stream_unref(exec_ctx, s->data_parser.parsing_frame);
@ -2593,7 +2579,7 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx,
if (bs->remaining_bytes != 0) {
s->byte_stream_error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message");
grpc_closure_sched(exec_ctx, bs->next_action.on_complete,
GRPC_CLOSURE_SCHED(exec_ctx, bs->next_action.on_complete,
GRPC_ERROR_REF(s->byte_stream_error));
if (s->data_parser.parsing_frame != NULL) {
incoming_byte_stream_unref(exec_ctx, s->data_parser.parsing_frame);
@ -2624,11 +2610,11 @@ static bool incoming_byte_stream_next(grpc_exec_ctx *exec_ctx,
gpr_ref(&bs->refs);
bs->next_action.max_size_hint = max_size_hint;
bs->next_action.on_complete = on_complete;
grpc_closure_sched(
GRPC_CLOSURE_SCHED(
exec_ctx,
grpc_closure_init(
&bs->next_action.closure, incoming_byte_stream_next_locked, bs,
grpc_combiner_scheduler(bs->transport->combiner, false)),
GRPC_CLOSURE_INIT(&bs->next_action.closure,
incoming_byte_stream_next_locked, bs,
grpc_combiner_scheduler(bs->transport->combiner)),
GRPC_ERROR_NONE);
GPR_TIMER_END("incoming_byte_stream_next", 0);
return false;
@ -2653,7 +2639,7 @@ static grpc_error *incoming_byte_stream_pull(grpc_exec_ctx *exec_ctx,
} else {
grpc_error *error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message");
grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
GRPC_CLOSURE_SCHED(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
return error;
}
GPR_TIMER_END("incoming_byte_stream_pull", 0);
@ -2682,11 +2668,10 @@ static void incoming_byte_stream_destroy(grpc_exec_ctx *exec_ctx,
GPR_TIMER_BEGIN("incoming_byte_stream_destroy", 0);
grpc_chttp2_incoming_byte_stream *bs =
(grpc_chttp2_incoming_byte_stream *)byte_stream;
grpc_closure_sched(
exec_ctx,
grpc_closure_init(
&bs->destroy_action, incoming_byte_stream_destroy_locked, bs,
grpc_combiner_scheduler(bs->transport->combiner, false)),
GRPC_CLOSURE_SCHED(
exec_ctx, GRPC_CLOSURE_INIT(
&bs->destroy_action, incoming_byte_stream_destroy_locked,
bs, grpc_combiner_scheduler(bs->transport->combiner)),
GRPC_ERROR_NONE);
GPR_TIMER_END("incoming_byte_stream_destroy", 0);
}
@ -2697,7 +2682,7 @@ static void incoming_byte_stream_publish_error(
grpc_chttp2_stream *s = bs->stream;
GPR_ASSERT(error != GRPC_ERROR_NONE);
grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_REF(error));
GRPC_CLOSURE_SCHED(exec_ctx, s->on_next, GRPC_ERROR_REF(error));
s->on_next = NULL;
GRPC_ERROR_UNREF(s->byte_stream_error);
s->byte_stream_error = GRPC_ERROR_REF(error);
@ -2714,7 +2699,7 @@ grpc_error *grpc_chttp2_incoming_byte_stream_push(
grpc_error *error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many bytes in stream");
grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
GRPC_CLOSURE_SCHED(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
grpc_slice_unref_internal(exec_ctx, slice);
return error;
} else {
@ -2737,7 +2722,7 @@ grpc_error *grpc_chttp2_incoming_byte_stream_finished(
}
}
if (error != GRPC_ERROR_NONE && reset_on_error) {
grpc_closure_sched(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
GRPC_CLOSURE_SCHED(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error));
}
incoming_byte_stream_unref(exec_ctx, bs);
return error;
@ -2757,6 +2742,7 @@ grpc_chttp2_incoming_byte_stream *grpc_chttp2_incoming_byte_stream_create(
gpr_ref_init(&incoming_byte_stream->refs, 2);
incoming_byte_stream->transport = t;
incoming_byte_stream->stream = s;
GRPC_ERROR_UNREF(s->byte_stream_error);
s->byte_stream_error = GRPC_ERROR_NONE;
return incoming_byte_stream;
}
@ -2971,5 +2957,5 @@ void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx,
grpc_slice_buffer_move_into(read_buffer, &t->read_buffer);
gpr_free(read_buffer);
}
grpc_closure_sched(exec_ctx, &t->read_action_locked, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, &t->read_action_locked, GRPC_ERROR_NONE);
}

@ -26,6 +26,10 @@
extern grpc_tracer_flag grpc_http_trace;
extern grpc_tracer_flag grpc_flowctl_trace;
#ifndef NDEBUG
extern grpc_tracer_flag grpc_trace_chttp2_refcount;
#endif
grpc_transport *grpc_create_chttp2_transport(
grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args,
grpc_endpoint *ep, int is_client);

@ -128,6 +128,7 @@ grpc_error *grpc_deframe_unprocessed_incoming_frames(
grpc_slice_unref_internal(exec_ctx, slice);
return GRPC_ERROR_REF(p->error);
case GRPC_CHTTP2_DATA_FH_0:
s->stats.incoming.framing_bytes++;
p->frame_type = *cur;
switch (p->frame_type) {
case 0:
@ -159,6 +160,7 @@ grpc_error *grpc_deframe_unprocessed_incoming_frames(
}
/* fallthrough */
case GRPC_CHTTP2_DATA_FH_1:
s->stats.incoming.framing_bytes++;
p->frame_size = ((uint32_t)*cur) << 24;
if (++cur == end) {
p->state = GRPC_CHTTP2_DATA_FH_2;
@ -167,6 +169,7 @@ grpc_error *grpc_deframe_unprocessed_incoming_frames(
}
/* fallthrough */
case GRPC_CHTTP2_DATA_FH_2:
s->stats.incoming.framing_bytes++;
p->frame_size |= ((uint32_t)*cur) << 16;
if (++cur == end) {
p->state = GRPC_CHTTP2_DATA_FH_3;
@ -175,6 +178,7 @@ grpc_error *grpc_deframe_unprocessed_incoming_frames(
}
/* fallthrough */
case GRPC_CHTTP2_DATA_FH_3:
s->stats.incoming.framing_bytes++;
p->frame_size |= ((uint32_t)*cur) << 8;
if (++cur == end) {
p->state = GRPC_CHTTP2_DATA_FH_4;
@ -183,6 +187,7 @@ grpc_error *grpc_deframe_unprocessed_incoming_frames(
}
/* fallthrough */
case GRPC_CHTTP2_DATA_FH_4:
s->stats.incoming.framing_bytes++;
GPR_ASSERT(stream_out != NULL);
GPR_ASSERT(p->parsing_frame == NULL);
p->frame_size |= ((uint32_t)*cur);
@ -219,6 +224,7 @@ grpc_error *grpc_deframe_unprocessed_incoming_frames(
}
uint32_t remaining = (uint32_t)(end - cur);
if (remaining == p->frame_size) {
s->stats.incoming.data_bytes += remaining;
if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push(
exec_ctx, p->parsing_frame,
grpc_slice_sub(slice, (size_t)(cur - beg),
@ -238,6 +244,7 @@ grpc_error *grpc_deframe_unprocessed_incoming_frames(
grpc_slice_unref_internal(exec_ctx, slice);
return GRPC_ERROR_NONE;
} else if (remaining < p->frame_size) {
s->stats.incoming.data_bytes += remaining;
if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push(
exec_ctx, p->parsing_frame,
grpc_slice_sub(slice, (size_t)(cur - beg),
@ -250,6 +257,7 @@ grpc_error *grpc_deframe_unprocessed_incoming_frames(
return GRPC_ERROR_NONE;
} else {
GPR_ASSERT(remaining > p->frame_size);
s->stats.incoming.data_bytes += p->frame_size;
if (GRPC_ERROR_NONE !=
(grpc_chttp2_incoming_byte_stream_push(
exec_ctx, p->parsing_frame,
@ -286,7 +294,6 @@ grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser,
grpc_chttp2_stream *s,
grpc_slice slice, int is_last) {
/* grpc_error *error = parse_inner_buffer(exec_ctx, p, t, s, slice); */
s->stats.incoming.framing_bytes += GRPC_SLICE_LENGTH(slice);
if (!s->pending_byte_stream) {
grpc_slice_ref_internal(slice);
grpc_slice_buffer_add(&s->frame_storage, slice);
@ -295,7 +302,7 @@ grpc_error *grpc_chttp2_data_parser_parse(grpc_exec_ctx *exec_ctx, void *parser,
GPR_ASSERT(s->frame_storage.length == 0);
grpc_slice_ref_internal(slice);
grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, slice);
grpc_closure_sched(exec_ctx, s->on_next, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, s->on_next, GRPC_ERROR_NONE);
s->on_next = NULL;
} else {
grpc_slice_ref_internal(slice);

@ -117,7 +117,7 @@ grpc_error *grpc_chttp2_ping_parser_parse(grpc_exec_ctx *exec_ctx, void *parser,
t->ping_acks, t->ping_ack_capacity * sizeof(*t->ping_acks));
}
t->ping_acks[t->ping_ack_count++] = p->opaque_8bytes;
grpc_chttp2_initiate_write(exec_ctx, t, false, "ping response");
grpc_chttp2_initiate_write(exec_ctx, t, "ping response");
}
}
}

@ -93,7 +93,7 @@ grpc_error *grpc_chttp2_rst_stream_parser_parse(grpc_exec_ctx *exec_ctx,
(((uint32_t)p->reason_bytes[2]) << 8) |
(((uint32_t)p->reason_bytes[3]));
grpc_error *error = GRPC_ERROR_NONE;
if (reason != GRPC_HTTP2_NO_ERROR || s->header_frames_received < 2) {
if (reason != GRPC_HTTP2_NO_ERROR || s->metadata_buffer[1].size == 0) {
char *message;
gpr_asprintf(&message, "Received RST_STREAM with error code %d", reason);
error = grpc_error_set_int(

@ -109,8 +109,7 @@ grpc_error *grpc_chttp2_window_update_parser_parse(
received_update);
bool is_zero = t->outgoing_window <= 0;
if (was_zero && !is_zero) {
grpc_chttp2_initiate_write(exec_ctx, t, false,
"new_global_flow_control");
grpc_chttp2_initiate_write(exec_ctx, t, "new_global_flow_control");
}
}
}

@ -608,15 +608,14 @@ void grpc_chttp2_hpack_compressor_set_max_table_size(
void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx,
grpc_chttp2_hpack_compressor *c,
grpc_mdelem **extra_headers,
size_t extra_headers_size,
grpc_metadata_batch *metadata,
const grpc_encode_header_options *options,
grpc_slice_buffer *outbuf) {
framer_state st;
grpc_linked_mdelem *l;
gpr_timespec deadline;
GPR_ASSERT(options->stream_id != 0);
framer_state st;
st.seen_regular_header = 0;
st.stream_id = options->stream_id;
st.output = outbuf;
@ -633,11 +632,14 @@ void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx,
if (c->advertise_table_size_change != 0) {
emit_advertise_table_size_change(c, &st);
}
for (size_t i = 0; i < extra_headers_size; ++i) {
hpack_enc(exec_ctx, c, *extra_headers[i], &st);
}
grpc_metadata_batch_assert_ok(metadata);
for (l = metadata->list.head; l; l = l->next) {
for (grpc_linked_mdelem *l = metadata->list.head; l; l = l->next) {
hpack_enc(exec_ctx, c, l->md, &st);
}
deadline = metadata->deadline;
gpr_timespec deadline = metadata->deadline;
if (gpr_time_cmp(deadline, gpr_inf_future(deadline.clock_type)) != 0) {
deadline_enc(exec_ctx, c, deadline, &st);
}

@ -85,6 +85,8 @@ typedef struct {
void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx,
grpc_chttp2_hpack_compressor *c,
grpc_mdelem **extra_headers,
size_t extra_headers_size,
grpc_metadata_batch *metadata,
const grpc_encode_header_options *options,
grpc_slice_buffer *outbuf);

@ -1649,7 +1649,7 @@ static void force_client_rst_stream(grpc_exec_ctx *exec_ctx, void *sp,
grpc_slice_buffer_add(
&t->qbuf, grpc_chttp2_rst_stream_create(s->id, GRPC_HTTP2_NO_ERROR,
&s->stats.outgoing));
grpc_chttp2_initiate_write(exec_ctx, t, false, "force_rst_stream");
grpc_chttp2_initiate_write(exec_ctx, t, "force_rst_stream");
grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, true, GRPC_ERROR_NONE);
}
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "final_rst");
@ -1696,10 +1696,10 @@ grpc_error *grpc_chttp2_header_parser_parse(grpc_exec_ctx *exec_ctx,
however -- it might be that we receive a RST_STREAM following this
and can avoid the extra write */
GRPC_CHTTP2_STREAM_REF(s, "final_rst");
grpc_closure_sched(
exec_ctx, grpc_closure_create(force_client_rst_stream, s,
grpc_combiner_finally_scheduler(
t->combiner, false)),
GRPC_CLOSURE_SCHED(
exec_ctx,
GRPC_CLOSURE_CREATE(force_client_rst_stream, s,
grpc_combiner_finally_scheduler(t->combiner)),
GRPC_ERROR_NONE);
}
grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false,

@ -58,7 +58,6 @@ typedef enum {
GRPC_CHTTP2_WRITE_STATE_IDLE,
GRPC_CHTTP2_WRITE_STATE_WRITING,
GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE,
GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER,
} grpc_chttp2_write_state;
typedef enum {
@ -443,12 +442,12 @@ struct grpc_chttp2_stream {
grpc_slice fetching_slice;
int64_t next_message_end_offset;
int64_t flow_controlled_bytes_written;
bool complete_fetch_covered_by_poller;
grpc_closure complete_fetch_locked;
grpc_closure *fetching_send_message_finished;
grpc_metadata_batch *recv_initial_metadata;
grpc_closure *recv_initial_metadata_ready;
bool *trailing_metadata_available;
grpc_byte_stream **recv_message;
grpc_closure *recv_message_ready;
grpc_metadata_batch *recv_trailing_metadata;
@ -534,8 +533,7 @@ struct grpc_chttp2_stream {
The actual call chain is documented in the implementation of this function.
*/
void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t,
bool covered_by_poller, const char *reason);
grpc_chttp2_transport *t, const char *reason);
typedef enum {
GRPC_CHTTP2_NOTHING_TO_WRITE,
@ -751,7 +749,7 @@ void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx,
void grpc_chttp2_start_writing(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t);
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
#ifndef NDEBUG
#define GRPC_CHTTP2_STREAM_REF(stream, reason) \
grpc_chttp2_stream_ref(stream, reason)
#define GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream, reason) \
@ -767,8 +765,7 @@ void grpc_chttp2_stream_ref(grpc_chttp2_stream *s);
void grpc_chttp2_stream_unref(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *s);
#endif
//#define GRPC_CHTTP2_REFCOUNTING_DEBUG 1
#ifdef GRPC_CHTTP2_REFCOUNTING_DEBUG
#ifndef NDEBUG
#define GRPC_CHTTP2_REF_TRANSPORT(t, r) \
grpc_chttp2_ref_transport(t, r, __FILE__, __LINE__)
#define GRPC_CHTTP2_UNREF_TRANSPORT(cl, t, r) \

@ -418,7 +418,7 @@ static grpc_error *update_incoming_window(grpc_exec_ctx *exec_ctx,
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", t, incoming_window,
incoming_frame_size);
if (t->incoming_window <= target_incoming_window / 2) {
grpc_chttp2_initiate_write(exec_ctx, t, false, "flow_control");
grpc_chttp2_initiate_write(exec_ctx, t, "flow_control");
}
return GRPC_ERROR_NONE;
@ -681,9 +681,19 @@ static grpc_error *init_header_frame_parser(grpc_exec_ctx *exec_ctx,
t->parser_data = &t->hpack_parser;
switch (s->header_frames_received) {
case 0:
t->hpack_parser.on_header = on_initial_header;
if (t->is_client && t->header_eof) {
GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "parsing Trailers-Only"));
if (s->trailing_metadata_available != NULL) {
*s->trailing_metadata_available = true;
}
t->hpack_parser.on_header = on_trailing_header;
} else {
GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "parsing initial_metadata"));
t->hpack_parser.on_header = on_initial_header;
}
break;
case 1:
GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "parsing trailing_metadata"));
t->hpack_parser.on_header = on_trailing_header;
break;
case 2:

@ -111,7 +111,7 @@ static void maybe_initiate_ping(grpc_exec_ctx *exec_ctx,
}
pq->inflight_id = t->ping_ctr * GRPC_CHTTP2_PING_TYPE_COUNT + ping_type;
t->ping_ctr++;
grpc_closure_list_sched(exec_ctx, &pq->lists[GRPC_CHTTP2_PCL_INITIATE]);
GRPC_CLOSURE_LIST_SCHED(exec_ctx, &pq->lists[GRPC_CHTTP2_PCL_INITIATE]);
grpc_closure_list_move(&pq->lists[GRPC_CHTTP2_PCL_NEXT],
&pq->lists[GRPC_CHTTP2_PCL_INFLIGHT]);
grpc_slice_buffer_add(&t->outbuf,
@ -162,6 +162,20 @@ static uint32_t target_write_size(grpc_chttp2_transport *t) {
return 1024 * 1024;
}
// Returns true if initial_metadata contains only default headers.
//
// TODO(roth): The fact that we hard-code these particular headers here
// is fairly ugly. Need some better way to know which headers are
// default, maybe via a bit in the static metadata table?
static bool is_default_initial_metadata(grpc_metadata_batch *initial_metadata) {
int num_default_fields =
(initial_metadata->idx.named.status != NULL) +
(initial_metadata->idx.named.content_type != NULL) +
(initial_metadata->idx.named.grpc_encoding != NULL) +
(initial_metadata->idx.named.grpc_accept_encoding != NULL);
return (size_t)num_default_fields == initial_metadata->list.count;
}
grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) {
grpc_chttp2_stream *s;
@ -191,8 +205,7 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
while (grpc_chttp2_list_pop_stalled_by_transport(t, &s)) {
if (!t->closed && grpc_chttp2_list_add_writable_stream(t, s) &&
stream_ref_if_not_destroyed(&s->refcount->refs)) {
grpc_chttp2_initiate_write(exec_ctx, t, false,
"transport.read_flow_control");
grpc_chttp2_initiate_write(exec_ctx, t, "transport.read_flow_control");
}
}
}
@ -219,31 +232,59 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
t->is_client ? "CLIENT" : "SERVER", s->id, sent_initial_metadata,
s->send_initial_metadata != NULL, s->announce_window));
grpc_mdelem *extra_headers_for_trailing_metadata[2];
size_t num_extra_headers_for_trailing_metadata = 0;
/* send initial metadata if it's available */
if (!sent_initial_metadata && s->send_initial_metadata) {
grpc_encode_header_options hopt = {
.stream_id = s->id,
.is_eof = false,
.use_true_binary_metadata =
t->settings
[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA] != 0,
.max_frame_size = t->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
.stats = &s->stats.outgoing};
grpc_chttp2_encode_header(exec_ctx, &t->hpack_compressor,
s->send_initial_metadata, &hopt, &t->outbuf);
if (!sent_initial_metadata && s->send_initial_metadata != NULL) {
// We skip this on the server side if there is no custom initial
// metadata, there are no messages to send, and we are also sending
// trailing metadata. This results in a Trailers-Only response,
// which is required for retries, as per:
// https://github.com/grpc/proposal/blob/master/A6-client-retries.md#when-retries-are-valid
if (t->is_client || s->fetching_send_message != NULL ||
s->flow_controlled_buffer.length != 0 ||
s->send_trailing_metadata == NULL ||
!is_default_initial_metadata(s->send_initial_metadata)) {
grpc_encode_header_options hopt = {
.stream_id = s->id,
.is_eof = false,
.use_true_binary_metadata =
t->settings
[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA] != 0,
.max_frame_size = t->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
.stats = &s->stats.outgoing};
grpc_chttp2_encode_header(exec_ctx, &t->hpack_compressor, NULL, 0,
s->send_initial_metadata, &hopt, &t->outbuf);
now_writing = true;
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
if (!t->is_client) {
t->ping_recv_state.last_ping_recv_time =
gpr_inf_past(GPR_CLOCK_MONOTONIC);
t->ping_recv_state.ping_strikes = 0;
}
} else {
GRPC_CHTTP2_IF_TRACING(
gpr_log(GPR_INFO, "not sending initial_metadata (Trailers-Only)"));
// When sending Trailers-Only, we need to move the :status and
// content-type headers to the trailers.
if (s->send_initial_metadata->idx.named.status != NULL) {
extra_headers_for_trailing_metadata
[num_extra_headers_for_trailing_metadata++] =
&s->send_initial_metadata->idx.named.status->md;
}
if (s->send_initial_metadata->idx.named.content_type != NULL) {
extra_headers_for_trailing_metadata
[num_extra_headers_for_trailing_metadata++] =
&s->send_initial_metadata->idx.named.content_type->md;
}
}
s->send_initial_metadata = NULL;
s->sent_initial_metadata = true;
sent_initial_metadata = true;
now_writing = true;
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
if (!t->is_client) {
t->ping_recv_state.last_ping_recv_time =
gpr_inf_past(GPR_CLOCK_MONOTONIC);
t->ping_recv_state.ping_strikes = 0;
}
}
/* send any window updates */
if (s->announce_window > 0) {
@ -321,6 +362,7 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
if (s->send_trailing_metadata != NULL &&
s->fetching_send_message == NULL &&
s->flow_controlled_buffer.length == 0) {
GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "sending trailing_metadata"));
if (grpc_metadata_batch_is_empty(s->send_trailing_metadata)) {
grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, 0, true,
&s->stats.outgoing, &t->outbuf);
@ -338,6 +380,8 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
[GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
.stats = &s->stats.outgoing};
grpc_chttp2_encode_header(exec_ctx, &t->hpack_compressor,
extra_headers_for_trailing_metadata,
num_extra_headers_for_trailing_metadata,
s->send_trailing_metadata, &hopt,
&t->outbuf);
}

@ -766,20 +766,50 @@ static bool op_can_be_run(grpc_transport_stream_op_batch *curr_op,
bool is_canceled_or_failed = stream_state->state_op_done[OP_CANCEL_ERROR] ||
stream_state->state_callback_received[OP_FAILED];
if (is_canceled_or_failed) {
if (op_id == OP_SEND_INITIAL_METADATA) result = false;
if (op_id == OP_SEND_MESSAGE) result = false;
if (op_id == OP_SEND_TRAILING_METADATA) result = false;
if (op_id == OP_CANCEL_ERROR) result = false;
if (op_id == OP_SEND_INITIAL_METADATA) {
CRONET_LOG(GPR_DEBUG, "Because");
result = false;
}
if (op_id == OP_SEND_MESSAGE) {
CRONET_LOG(GPR_DEBUG, "Because");
result = false;
}
if (op_id == OP_SEND_TRAILING_METADATA) {
CRONET_LOG(GPR_DEBUG, "Because");
result = false;
}
if (op_id == OP_CANCEL_ERROR) {
CRONET_LOG(GPR_DEBUG, "Because");
result = false;
}
/* already executed */
if (op_id == OP_RECV_INITIAL_METADATA &&
stream_state->state_op_done[OP_RECV_INITIAL_METADATA])
stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) {
CRONET_LOG(GPR_DEBUG, "Because");
result = false;
if (op_id == OP_RECV_MESSAGE &&
stream_state->state_op_done[OP_RECV_MESSAGE])
}
if (op_id == OP_RECV_MESSAGE && op_state->state_op_done[OP_RECV_MESSAGE]) {
CRONET_LOG(GPR_DEBUG, "Because");
result = false;
}
if (op_id == OP_RECV_TRAILING_METADATA &&
stream_state->state_op_done[OP_RECV_TRAILING_METADATA])
stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) {
CRONET_LOG(GPR_DEBUG, "Because");
result = false;
}
/* ON_COMPLETE can be processed if one of the following conditions is met:
* 1. the stream failed
* 2. the stream is cancelled, and the callback is received
* 3. the stream succeeded before cancel is effective
* 4. the stream is cancelled, and the stream is never started */
if (op_id == OP_ON_COMPLETE &&
!(stream_state->state_callback_received[OP_FAILED] ||
stream_state->state_callback_received[OP_CANCELED] ||
stream_state->state_callback_received[OP_SUCCEEDED] ||
!stream_state->state_op_done[OP_SEND_INITIAL_METADATA])) {
CRONET_LOG(GPR_DEBUG, "Because");
result = false;
}
} else if (op_id == OP_SEND_INITIAL_METADATA) {
/* already executed */
if (stream_state->state_op_done[OP_SEND_INITIAL_METADATA]) result = false;
@ -868,7 +898,7 @@ static bool op_can_be_run(grpc_transport_stream_op_batch *curr_op,
CRONET_LOG(GPR_DEBUG, "Because");
result = false;
} else if (curr_op->recv_message &&
!stream_state->state_op_done[OP_RECV_MESSAGE]) {
!op_state->state_op_done[OP_RECV_MESSAGE]) {
CRONET_LOG(GPR_DEBUG, "Because");
result = false;
} else if (curr_op->cancel_stream &&
@ -1033,17 +1063,17 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
OP_RECV_INITIAL_METADATA)) {
CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_INITIAL_METADATA", oas);
if (stream_state->state_op_done[OP_CANCEL_ERROR]) {
grpc_closure_sched(
GRPC_CLOSURE_SCHED(
exec_ctx,
stream_op->payload->recv_initial_metadata.recv_initial_metadata_ready,
GRPC_ERROR_NONE);
} else if (stream_state->state_callback_received[OP_FAILED]) {
grpc_closure_sched(
GRPC_CLOSURE_SCHED(
exec_ctx,
stream_op->payload->recv_initial_metadata.recv_initial_metadata_ready,
GRPC_ERROR_NONE);
} else if (stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) {
grpc_closure_sched(
GRPC_CLOSURE_SCHED(
exec_ctx,
stream_op->payload->recv_initial_metadata.recv_initial_metadata_ready,
GRPC_ERROR_NONE);
@ -1051,7 +1081,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
grpc_chttp2_incoming_metadata_buffer_publish(
exec_ctx, &oas->s->state.rs.initial_metadata,
stream_op->payload->recv_initial_metadata.recv_initial_metadata);
grpc_closure_sched(
GRPC_CLOSURE_SCHED(
exec_ctx,
stream_op->payload->recv_initial_metadata.recv_initial_metadata_ready,
GRPC_ERROR_NONE);
@ -1063,22 +1093,24 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_MESSAGE", oas);
if (stream_state->state_op_done[OP_CANCEL_ERROR]) {
CRONET_LOG(GPR_DEBUG, "Stream is cancelled.");
grpc_closure_sched(exec_ctx,
GRPC_CLOSURE_SCHED(exec_ctx,
stream_op->payload->recv_message.recv_message_ready,
GRPC_ERROR_NONE);
stream_state->state_op_done[OP_RECV_MESSAGE] = true;
oas->state.state_op_done[OP_RECV_MESSAGE] = true;
result = ACTION_TAKEN_NO_CALLBACK;
} else if (stream_state->state_callback_received[OP_FAILED]) {
CRONET_LOG(GPR_DEBUG, "Stream failed.");
grpc_closure_sched(exec_ctx,
GRPC_CLOSURE_SCHED(exec_ctx,
stream_op->payload->recv_message.recv_message_ready,
GRPC_ERROR_NONE);
stream_state->state_op_done[OP_RECV_MESSAGE] = true;
oas->state.state_op_done[OP_RECV_MESSAGE] = true;
result = ACTION_TAKEN_NO_CALLBACK;
} else if (stream_state->rs.read_stream_closed == true) {
/* No more data will be received */
CRONET_LOG(GPR_DEBUG, "read stream closed");
grpc_closure_sched(exec_ctx,
GRPC_CLOSURE_SCHED(exec_ctx,
stream_op->payload->recv_message.recv_message_ready,
GRPC_ERROR_NONE);
stream_state->state_op_done[OP_RECV_MESSAGE] = true;
@ -1086,7 +1118,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
result = ACTION_TAKEN_NO_CALLBACK;
} else if (stream_state->flush_read) {
CRONET_LOG(GPR_DEBUG, "flush read");
grpc_closure_sched(exec_ctx,
GRPC_CLOSURE_SCHED(exec_ctx,
stream_op->payload->recv_message.recv_message_ready,
GRPC_ERROR_NONE);
stream_state->state_op_done[OP_RECV_MESSAGE] = true;
@ -1127,7 +1159,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
*((grpc_byte_buffer **)
stream_op->payload->recv_message.recv_message) =
(grpc_byte_buffer *)&stream_state->rs.sbs;
grpc_closure_sched(
GRPC_CLOSURE_SCHED(
exec_ctx, stream_op->payload->recv_message.recv_message_ready,
GRPC_ERROR_NONE);
stream_state->state_op_done[OP_RECV_MESSAGE] = true;
@ -1181,7 +1213,7 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
}
*((grpc_byte_buffer **)stream_op->payload->recv_message.recv_message) =
(grpc_byte_buffer *)&stream_state->rs.sbs;
grpc_closure_sched(exec_ctx,
GRPC_CLOSURE_SCHED(exec_ctx,
stream_op->payload->recv_message.recv_message_ready,
GRPC_ERROR_NONE);
stream_state->state_op_done[OP_RECV_MESSAGE] = true;
@ -1214,8 +1246,8 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
} else if (stream_op->cancel_stream &&
op_can_be_run(stream_op, s, &oas->state, OP_CANCEL_ERROR)) {
CRONET_LOG(GPR_DEBUG, "running: %p OP_CANCEL_ERROR", oas);
CRONET_LOG(GPR_DEBUG, "W: bidirectional_stream_cancel(%p)", s->cbs);
if (s->cbs) {
CRONET_LOG(GPR_DEBUG, "W: bidirectional_stream_cancel(%p)", s->cbs);
bidirectional_stream_cancel(s->cbs);
result = ACTION_TAKEN_WITH_CALLBACK;
} else {
@ -1230,17 +1262,17 @@ static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
op_can_be_run(stream_op, s, &oas->state, OP_ON_COMPLETE)) {
CRONET_LOG(GPR_DEBUG, "running: %p OP_ON_COMPLETE", oas);
if (stream_state->state_op_done[OP_CANCEL_ERROR]) {
grpc_closure_sched(exec_ctx, stream_op->on_complete,
GRPC_CLOSURE_SCHED(exec_ctx, stream_op->on_complete,
GRPC_ERROR_REF(stream_state->cancel_error));
} else if (stream_state->state_callback_received[OP_FAILED]) {
grpc_closure_sched(
GRPC_CLOSURE_SCHED(
exec_ctx, stream_op->on_complete,
make_error_with_desc(GRPC_STATUS_UNAVAILABLE, "Unavailable."));
} else {
/* All actions in this stream_op are complete. Call the on_complete
* callback
*/
grpc_closure_sched(exec_ctx, stream_op->on_complete, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, stream_op->on_complete, GRPC_ERROR_NONE);
}
oas->state.state_op_done[OP_ON_COMPLETE] = true;
oas->done = true;
@ -1312,16 +1344,16 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
/* Cronet does not support :authority header field. We cancel the call when
this field is present in metadata */
if (op->recv_initial_metadata) {
grpc_closure_sched(
GRPC_CLOSURE_SCHED(
exec_ctx,
op->payload->recv_initial_metadata.recv_initial_metadata_ready,
GRPC_ERROR_CANCELLED);
}
if (op->recv_message) {
grpc_closure_sched(exec_ctx, op->payload->recv_message.recv_message_ready,
GRPC_CLOSURE_SCHED(exec_ctx, op->payload->recv_message.recv_message_ready,
GRPC_ERROR_CANCELLED);
}
grpc_closure_sched(exec_ctx, op->on_complete, GRPC_ERROR_CANCELLED);
GRPC_CLOSURE_SCHED(exec_ctx, op->on_complete, GRPC_ERROR_CANCELLED);
return;
}
stream_obj *s = (stream_obj *)gs;
@ -1335,7 +1367,7 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
stream_obj *s = (stream_obj *)gs;
null_and_maybe_free_read_buffer(s);
GRPC_ERROR_UNREF(s->state.cancel_error);
grpc_closure_sched(exec_ctx, then_schedule_closure, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(exec_ctx, then_schedule_closure, GRPC_ERROR_NONE);
}
static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {}

@ -373,3 +373,29 @@ bool grpc_channel_args_want_minimal_stack(const grpc_channel_args *args) {
return grpc_channel_arg_get_bool(
grpc_channel_args_find(args, GRPC_ARG_MINIMAL_STACK), false);
}
grpc_arg grpc_channel_arg_string_create(char *name, char *value) {
grpc_arg arg;
arg.type = GRPC_ARG_STRING;
arg.key = name;
arg.value.string = value;
return arg;
}
grpc_arg grpc_channel_arg_integer_create(char *name, int value) {
grpc_arg arg;
arg.type = GRPC_ARG_INTEGER;
arg.key = name;
arg.value.integer = value;
return arg;
}
grpc_arg grpc_channel_arg_pointer_create(
char *name, void *value, const grpc_arg_pointer_vtable *vtable) {
grpc_arg arg;
arg.type = GRPC_ARG_POINTER;
arg.key = name;
arg.value.pointer.p = value;
arg.value.pointer.vtable = vtable;
return arg;
}

@ -112,4 +112,10 @@ int grpc_channel_arg_get_integer(const grpc_arg *arg,
bool grpc_channel_arg_get_bool(const grpc_arg *arg, bool default_value);
// Helpers for creating channel args.
grpc_arg grpc_channel_arg_string_create(char *name, char *value);
grpc_arg grpc_channel_arg_integer_create(char *name, int value);
grpc_arg grpc_channel_arg_pointer_create(char *name, void *value,
const grpc_arg_pointer_vtable *vtable);
#endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_ARGS_H */

@ -126,7 +126,7 @@ typedef struct {
/* Destroy per call data.
The filter does not need to do any chaining.
The bottom filter of a stack will be passed a non-NULL pointer to
\a then_schedule_closure that should be passed to grpc_closure_sched when
\a then_schedule_closure that should be passed to GRPC_CLOSURE_SCHED when
destruction is complete. \a final_info contains data about the completed
call, mainly for reporting purposes. */
void (*destroy_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
@ -234,7 +234,7 @@ void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
grpc_call_stack *call_stack,
grpc_polling_entity *pollent);
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
#ifndef NDEBUG
#define GRPC_CALL_STACK_REF(call_stack, reason) \
grpc_stream_ref(&(call_stack)->refcount, reason)
#define GRPC_CALL_STACK_UNREF(exec_ctx, call_stack, reason) \

@ -190,7 +190,7 @@ static bool call_next_handshaker_locked(grpc_exec_ctx* exec_ctx,
// Cancel deadline timer, since we're invoking the on_handshake_done
// callback now.
grpc_timer_cancel(exec_ctx, &mgr->deadline_timer);
grpc_closure_sched(exec_ctx, &mgr->on_handshake_done, error);
GRPC_CLOSURE_SCHED(exec_ctx, &mgr->on_handshake_done, error);
mgr->shutdown = true;
} else {
grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->index],
@ -245,13 +245,13 @@ void grpc_handshake_manager_do_handshake(
grpc_slice_buffer_init(mgr->args.read_buffer);
// Initialize state needed for calling handshakers.
mgr->acceptor = acceptor;
grpc_closure_init(&mgr->call_next_handshaker, call_next_handshaker, mgr,
GRPC_CLOSURE_INIT(&mgr->call_next_handshaker, call_next_handshaker, mgr,
grpc_schedule_on_exec_ctx);
grpc_closure_init(&mgr->on_handshake_done, on_handshake_done, &mgr->args,
GRPC_CLOSURE_INIT(&mgr->on_handshake_done, on_handshake_done, &mgr->args,
grpc_schedule_on_exec_ctx);
// Start deadline timer, which owns a ref.
gpr_ref(&mgr->refs);
grpc_closure_init(&mgr->on_timeout, on_timeout, mgr,
GRPC_CLOSURE_INIT(&mgr->on_timeout, on_timeout, mgr,
grpc_schedule_on_exec_ctx);
grpc_timer_init(exec_ctx, &mgr->deadline_timer,
gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),

@ -25,6 +25,7 @@
#include <grpc/support/string_util.h>
#include <grpc/support/useful.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/http/format_request.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/endpoint.h"
@ -90,7 +91,7 @@ static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
grpc_error *error) {
grpc_polling_entity_del_from_pollset_set(exec_ctx, req->pollent,
req->context->pollset_set);
grpc_closure_sched(exec_ctx, req->on_done, error);
GRPC_CLOSURE_SCHED(exec_ctx, req->on_done, error);
grpc_http_parser_destroy(&req->parser);
if (req->addresses != NULL) {
grpc_resolved_addresses_destroy(req->addresses);
@ -213,13 +214,11 @@ static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req,
return;
}
addr = &req->addresses->addrs[req->next_address++];
grpc_closure_init(&req->connected, on_connected, req,
GRPC_CLOSURE_INIT(&req->connected, on_connected, req,
grpc_schedule_on_exec_ctx);
grpc_arg arg;
arg.key = GRPC_ARG_RESOURCE_QUOTA;
arg.type = GRPC_ARG_POINTER;
arg.value.pointer.p = req->resource_quota;
arg.value.pointer.vtable = grpc_resource_quota_arg_vtable();
grpc_arg arg = grpc_channel_arg_pointer_create(
GRPC_ARG_RESOURCE_QUOTA, req->resource_quota,
grpc_resource_quota_arg_vtable());
grpc_channel_args args = {1, &arg};
grpc_tcp_client_connect(exec_ctx, &req->connected, &req->ep,
req->context->pollset_set, &args, addr,
@ -256,8 +255,8 @@ static void internal_request_begin(grpc_exec_ctx *exec_ctx,
req->pollent = pollent;
req->overall_error = GRPC_ERROR_NONE;
req->resource_quota = grpc_resource_quota_ref_internal(resource_quota);
grpc_closure_init(&req->on_read, on_read, req, grpc_schedule_on_exec_ctx);
grpc_closure_init(&req->done_write, done_write, req,
GRPC_CLOSURE_INIT(&req->on_read, on_read, req, grpc_schedule_on_exec_ctx);
GRPC_CLOSURE_INIT(&req->done_write, done_write, req,
grpc_schedule_on_exec_ctx);
grpc_slice_buffer_init(&req->incoming);
grpc_slice_buffer_init(&req->outgoing);
@ -271,7 +270,7 @@ static void internal_request_begin(grpc_exec_ctx *exec_ctx,
grpc_resolve_address(
exec_ctx, request->host, req->handshaker->default_port,
req->context->pollset_set,
grpc_closure_create(on_resolved, req, grpc_schedule_on_exec_ctx),
GRPC_CLOSURE_CREATE(on_resolved, req, grpc_schedule_on_exec_ctx),
&req->addresses);
}

@ -25,6 +25,7 @@
#include <grpc/support/string_util.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker_registry.h"
#include "src/core/lib/security/transport/security_handshaker.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/string.h"
@ -85,7 +86,7 @@ static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx,
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
}
grpc_closure_sched(exec_ctx, on_peer_checked, error);
GRPC_CLOSURE_SCHED(exec_ctx, on_peer_checked, error);
tsi_peer_destruct(&peer);
}
@ -157,7 +158,6 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
gpr_timespec deadline,
void (*on_done)(grpc_exec_ctx *exec_ctx, void *arg,
grpc_endpoint *endpoint)) {
grpc_channel_security_connector *sc = NULL;
on_done_closure *c = gpr_malloc(sizeof(*c));
const char *pem_root_certs = grpc_get_default_ssl_roots();
if (pem_root_certs == NULL) {
@ -168,11 +168,13 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
}
c->func = on_done;
c->arg = arg;
c->handshake_mgr = grpc_handshake_manager_create();
grpc_channel_security_connector *sc = NULL;
GPR_ASSERT(httpcli_ssl_channel_security_connector_create(
exec_ctx, pem_root_certs, host, &sc) == GRPC_SECURITY_OK);
grpc_channel_security_connector_add_handshakers(exec_ctx, sc,
c->handshake_mgr);
grpc_arg channel_arg = grpc_security_connector_to_arg(&sc->base);
grpc_channel_args args = {1, &channel_arg};
c->handshake_mgr = grpc_handshake_manager_create();
grpc_handshakers_add(exec_ctx, HANDSHAKER_CLIENT, &args, c->handshake_mgr);
grpc_handshake_manager_do_handshake(
exec_ctx, c->handshake_mgr, tcp, NULL /* channel_args */, deadline,
NULL /* acceptor */, on_handshake_done, c /* user_data */);

@ -24,14 +24,30 @@
#include "src/core/lib/profiling/timers.h"
#ifndef NDEBUG
grpc_tracer_flag grpc_trace_closure = GRPC_TRACER_INITIALIZER(false);
#endif
#ifndef NDEBUG
grpc_closure *grpc_closure_init(const char *file, int line,
grpc_closure *closure, grpc_iomgr_cb_func cb,
void *cb_arg,
grpc_closure_scheduler *scheduler) {
#else
grpc_closure *grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
void *cb_arg,
grpc_closure_scheduler *scheduler) {
#endif
closure->cb = cb;
closure->cb_arg = cb_arg;
closure->scheduler = scheduler;
#ifndef NDEBUG
closure->scheduled = false;
closure->file_initiated = NULL;
closure->line_initiated = 0;
closure->run = false;
closure->file_created = file;
closure->line_created = line;
#endif
return closure;
}
@ -100,19 +116,39 @@ static void closure_wrapper(grpc_exec_ctx *exec_ctx, void *arg,
cb(exec_ctx, cb_arg, error);
}
#ifndef NDEBUG
grpc_closure *grpc_closure_create(const char *file, int line,
grpc_iomgr_cb_func cb, void *cb_arg,
grpc_closure_scheduler *scheduler) {
#else
grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg,
grpc_closure_scheduler *scheduler) {
#endif
wrapped_closure *wc = gpr_malloc(sizeof(*wc));
wc->cb = cb;
wc->cb_arg = cb_arg;
#ifndef NDEBUG
grpc_closure_init(file, line, &wc->wrapper, closure_wrapper, wc, scheduler);
#else
grpc_closure_init(&wc->wrapper, closure_wrapper, wc, scheduler);
#endif
return &wc->wrapper;
}
#ifndef NDEBUG
void grpc_closure_run(const char *file, int line, grpc_exec_ctx *exec_ctx,
grpc_closure *c, grpc_error *error) {
#else
void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *c,
grpc_error *error) {
#endif
GPR_TIMER_BEGIN("grpc_closure_run", 0);
if (c != NULL) {
#ifndef NDEBUG
c->file_initiated = file;
c->line_initiated = line;
c->run = true;
#endif
assert(c->cb);
c->scheduler->vtable->run(exec_ctx, c, error);
} else {
@ -121,13 +157,21 @@ void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *c,
GPR_TIMER_END("grpc_closure_run", 0);
}
#ifndef NDEBUG
void grpc_closure_sched(const char *file, int line, grpc_exec_ctx *exec_ctx,
grpc_closure *c, grpc_error *error) {
#else
void grpc_closure_sched(grpc_exec_ctx *exec_ctx, grpc_closure *c,
grpc_error *error) {
#endif
GPR_TIMER_BEGIN("grpc_closure_sched", 0);
if (c != NULL) {
#ifndef NDEBUG
GPR_ASSERT(!c->scheduled);
c->scheduled = true;
c->file_initiated = file;
c->line_initiated = line;
c->run = false;
#endif
assert(c->cb);
c->scheduler->vtable->sched(exec_ctx, c, error);
@ -137,13 +181,21 @@ void grpc_closure_sched(grpc_exec_ctx *exec_ctx, grpc_closure *c,
GPR_TIMER_END("grpc_closure_sched", 0);
}
#ifndef NDEBUG
void grpc_closure_list_sched(const char *file, int line,
grpc_exec_ctx *exec_ctx, grpc_closure_list *list) {
#else
void grpc_closure_list_sched(grpc_exec_ctx *exec_ctx, grpc_closure_list *list) {
#endif
grpc_closure *c = list->head;
while (c != NULL) {
grpc_closure *next = c->next_data.next;
#ifndef NDEBUG
GPR_ASSERT(!c->scheduled);
c->scheduled = true;
c->file_initiated = file;
c->line_initiated = line;
c->run = false;
#endif
assert(c->cb);
c->scheduler->vtable->sched(exec_ctx, c, c->error_data.error);

@ -26,9 +26,17 @@
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/support/mpscq.h"
#ifdef __cplusplus
extern "C" {
#endif
struct grpc_closure;
typedef struct grpc_closure grpc_closure;
#ifndef NDEBUG
extern grpc_tracer_flag grpc_trace_closure;
#endif
typedef struct grpc_closure_list {
grpc_closure *head;
grpc_closure *tail;
@ -38,7 +46,9 @@ typedef struct grpc_closure_list {
*
* \param arg Arbitrary input.
* \param error GRPC_ERROR_NONE if no error occurred, otherwise some grpc_error
* describing what went wrong */
* describing what went wrong.
* Error contract: it is not the cb's job to unref this error;
* the closure scheduler will do that after the cb returns */
typedef void (*grpc_iomgr_cb_func)(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error);
@ -85,19 +95,47 @@ struct grpc_closure {
uintptr_t scratch;
} error_data;
// extra tracing and debugging for grpc_closure. This incurs a decent amount of
// overhead per closure, so it must be enabled at compile time.
#ifndef NDEBUG
bool scheduled;
bool run; // true = run, false = scheduled
const char *file_created;
int line_created;
const char *file_initiated;
int line_initiated;
#endif
};
/** Initializes \a closure with \a cb and \a cb_arg. Returns \a closure. */
#ifndef NDEBUG
grpc_closure *grpc_closure_init(const char *file, int line,
grpc_closure *closure, grpc_iomgr_cb_func cb,
void *cb_arg,
grpc_closure_scheduler *scheduler);
#define GRPC_CLOSURE_INIT(closure, cb, cb_arg, scheduler) \
grpc_closure_init(__FILE__, __LINE__, closure, cb, cb_arg, scheduler)
#else
grpc_closure *grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
void *cb_arg,
grpc_closure_scheduler *scheduler);
#define GRPC_CLOSURE_INIT(closure, cb, cb_arg, scheduler) \
grpc_closure_init(closure, cb, cb_arg, scheduler)
#endif
/* Create a heap allocated closure: try to avoid except for very rare events */
#ifndef NDEBUG
grpc_closure *grpc_closure_create(const char *file, int line,
grpc_iomgr_cb_func cb, void *cb_arg,
grpc_closure_scheduler *scheduler);
#define GRPC_CLOSURE_CREATE(cb, cb_arg, scheduler) \
grpc_closure_create(__FILE__, __LINE__, cb, cb_arg, scheduler)
#else
grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg,
grpc_closure_scheduler *scheduler);
#define GRPC_CLOSURE_CREATE(cb, cb_arg, scheduler) \
grpc_closure_create(cb, cb_arg, scheduler)
#endif
#define GRPC_CLOSURE_LIST_INIT \
{ NULL, NULL }
@ -123,16 +161,48 @@ bool grpc_closure_list_empty(grpc_closure_list list);
/** Run a closure directly. Caller ensures that no locks are being held above.
* Note that calling this at the end of a closure callback function itself is
* by definition safe. */
#ifndef NDEBUG
void grpc_closure_run(const char *file, int line, grpc_exec_ctx *exec_ctx,
grpc_closure *closure, grpc_error *error);
#define GRPC_CLOSURE_RUN(exec_ctx, closure, error) \
grpc_closure_run(__FILE__, __LINE__, exec_ctx, closure, error)
#else
void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
grpc_error *error);
#define GRPC_CLOSURE_RUN(exec_ctx, closure, error) \
grpc_closure_run(exec_ctx, closure, error)
#endif
/** Schedule a closure to be run. Does not need to be run from a safe point. */
#ifndef NDEBUG
void grpc_closure_sched(const char *file, int line, grpc_exec_ctx *exec_ctx,
grpc_closure *closure, grpc_error *error);
#define GRPC_CLOSURE_SCHED(exec_ctx, closure, error) \
grpc_closure_sched(__FILE__, __LINE__, exec_ctx, closure, error)
#else
void grpc_closure_sched(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
grpc_error *error);
#define GRPC_CLOSURE_SCHED(exec_ctx, closure, error) \
grpc_closure_sched(exec_ctx, closure, error)
#endif
/** Schedule all closures in a list to be run. Does not need to be run from a
* safe point. */
#ifndef NDEBUG
void grpc_closure_list_sched(const char *file, int line,
grpc_exec_ctx *exec_ctx,
grpc_closure_list *closure_list);
#define GRPC_CLOSURE_LIST_SCHED(exec_ctx, closure_list) \
grpc_closure_list_sched(__FILE__, __LINE__, exec_ctx, closure_list)
#else
void grpc_closure_list_sched(grpc_exec_ctx *exec_ctx,
grpc_closure_list *closure_list);
#define GRPC_CLOSURE_LIST_SCHED(exec_ctx, closure_list) \
grpc_closure_list_sched(exec_ctx, closure_list)
#endif
#ifdef __cplusplus
}
#endif
#endif /* GRPC_CORE_LIB_IOMGR_CLOSURE_H */

@ -24,7 +24,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/iomgr/workqueue.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/profiling/timers.h"
grpc_tracer_flag grpc_combiner_trace = GRPC_TRACER_INITIALIZER(false);
@ -41,93 +41,47 @@ grpc_tracer_flag grpc_combiner_trace = GRPC_TRACER_INITIALIZER(false);
struct grpc_combiner {
grpc_combiner *next_combiner_on_this_exec_ctx;
grpc_workqueue *optional_workqueue;
grpc_closure_scheduler uncovered_scheduler;
grpc_closure_scheduler covered_scheduler;
grpc_closure_scheduler uncovered_finally_scheduler;
grpc_closure_scheduler covered_finally_scheduler;
grpc_closure_scheduler scheduler;
grpc_closure_scheduler finally_scheduler;
gpr_mpscq queue;
// either:
// a pointer to the initiating exec ctx if that is the only exec_ctx that has
// ever queued to this combiner, or NULL. If this is non-null, it's not
// dereferencable (since the initiating exec_ctx may have gone out of scope)
gpr_atm initiating_exec_ctx_or_null;
// state is:
// lower bit - zero if orphaned (STATE_UNORPHANED)
// other bits - number of items queued on the lock (STATE_ELEM_COUNT_LOW_BIT)
gpr_atm state;
// number of elements in the list that are covered by a poller: if >0, we can
// offload safely
gpr_atm elements_covered_by_poller;
bool time_to_execute_final_list;
bool final_list_covered_by_poller;
grpc_closure_list final_list;
grpc_closure offload;
gpr_refcount refs;
};
static void combiner_exec_uncovered(grpc_exec_ctx *exec_ctx,
grpc_closure *closure, grpc_error *error);
static void combiner_exec_covered(grpc_exec_ctx *exec_ctx,
static void combiner_exec(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
grpc_error *error);
static void combiner_finally_exec(grpc_exec_ctx *exec_ctx,
grpc_closure *closure, grpc_error *error);
static void combiner_finally_exec_uncovered(grpc_exec_ctx *exec_ctx,
grpc_closure *closure,
grpc_error *error);
static void combiner_finally_exec_covered(grpc_exec_ctx *exec_ctx,
grpc_closure *closure,
grpc_error *error);
static const grpc_closure_scheduler_vtable scheduler_uncovered = {
combiner_exec_uncovered, combiner_exec_uncovered,
"combiner:immediately:uncovered"};
static const grpc_closure_scheduler_vtable scheduler_covered = {
combiner_exec_covered, combiner_exec_covered,
"combiner:immediately:covered"};
static const grpc_closure_scheduler_vtable finally_scheduler_uncovered = {
combiner_finally_exec_uncovered, combiner_finally_exec_uncovered,
"combiner:finally:uncovered"};
static const grpc_closure_scheduler_vtable finally_scheduler_covered = {
combiner_finally_exec_covered, combiner_finally_exec_covered,
"combiner:finally:covered"};
static void offload(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
typedef struct {
grpc_error *error;
bool covered_by_poller;
} error_data;
static uintptr_t pack_error_data(error_data d) {
return ((uintptr_t)d.error) | (d.covered_by_poller ? 1 : 0);
}
static error_data unpack_error_data(uintptr_t p) {
return (error_data){(grpc_error *)(p & ~(uintptr_t)1), p & 1};
}
static const grpc_closure_scheduler_vtable scheduler = {
combiner_exec, combiner_exec, "combiner:immediately"};
static const grpc_closure_scheduler_vtable finally_scheduler = {
combiner_finally_exec, combiner_finally_exec, "combiner:finally"};
static bool is_covered_by_poller(grpc_combiner *lock) {
return lock->final_list_covered_by_poller ||
gpr_atm_acq_load(&lock->elements_covered_by_poller) > 0;
}
#define IS_COVERED_BY_POLLER_FMT "(final=%d elems=%" PRIdPTR ")->%d"
#define IS_COVERED_BY_POLLER_ARGS(lock) \
(lock)->final_list_covered_by_poller, \
gpr_atm_acq_load(&(lock)->elements_covered_by_poller), \
is_covered_by_poller((lock))
static void offload(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue) {
grpc_combiner *grpc_combiner_create(void) {
grpc_combiner *lock = gpr_malloc(sizeof(*lock));
gpr_ref_init(&lock->refs, 1);
lock->next_combiner_on_this_exec_ctx = NULL;
lock->time_to_execute_final_list = false;
lock->optional_workqueue = optional_workqueue;
lock->final_list_covered_by_poller = false;
lock->uncovered_scheduler.vtable = &scheduler_uncovered;
lock->covered_scheduler.vtable = &scheduler_covered;
lock->uncovered_finally_scheduler.vtable = &finally_scheduler_uncovered;
lock->covered_finally_scheduler.vtable = &finally_scheduler_covered;
lock->scheduler.vtable = &scheduler;
lock->finally_scheduler.vtable = &finally_scheduler;
gpr_atm_no_barrier_store(&lock->state, STATE_UNORPHANED);
gpr_atm_no_barrier_store(&lock->elements_covered_by_poller, 0);
gpr_mpscq_init(&lock->queue);
grpc_closure_list_init(&lock->final_list);
grpc_closure_init(&lock->offload, offload, lock,
grpc_workqueue_scheduler(lock->optional_workqueue));
GRPC_CLOSURE_INIT(&lock->offload, offload, lock, grpc_executor_scheduler);
GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p create", lock));
return lock;
}
@ -136,7 +90,6 @@ static void really_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) {
GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p really_destroy", lock));
GPR_ASSERT(gpr_atm_no_barrier_load(&lock->state) == 0);
gpr_mpscq_destroy(&lock->queue);
GRPC_WORKQUEUE_UNREF(exec_ctx, lock->optional_workqueue, "combiner");
gpr_free(lock);
}
@ -149,12 +102,14 @@ static void start_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) {
}
}
#ifdef GRPC_COMBINER_REFCOUNT_DEBUG
#define GRPC_COMBINER_DEBUG_SPAM(op, delta) \
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, \
"combiner[%p] %s %" PRIdPTR " --> %" PRIdPTR " %s", lock, (op), \
gpr_atm_no_barrier_load(&lock->refs.count), \
gpr_atm_no_barrier_load(&lock->refs.count) + (delta), reason);
#ifndef NDEBUG
#define GRPC_COMBINER_DEBUG_SPAM(op, delta) \
if (GRPC_TRACER_ON(grpc_combiner_trace)) { \
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, \
"C:%p %s %" PRIdPTR " --> %" PRIdPTR " %s", lock, (op), \
gpr_atm_no_barrier_load(&lock->refs.count), \
gpr_atm_no_barrier_load(&lock->refs.count) + (delta), reason); \
}
#else
#define GRPC_COMBINER_DEBUG_SPAM(op, delta)
#endif
@ -193,48 +148,40 @@ static void push_first_on_exec_ctx(grpc_exec_ctx *exec_ctx,
}
}
static void combiner_exec(grpc_exec_ctx *exec_ctx, grpc_combiner *lock,
grpc_closure *cl, grpc_error *error,
bool covered_by_poller) {
#define COMBINER_FROM_CLOSURE_SCHEDULER(closure, scheduler_name) \
((grpc_combiner *)(((char *)((closure)->scheduler)) - \
offsetof(grpc_combiner, scheduler_name)))
static void combiner_exec(grpc_exec_ctx *exec_ctx, grpc_closure *cl,
grpc_error *error) {
GPR_TIMER_BEGIN("combiner.execute", 0);
grpc_combiner *lock = COMBINER_FROM_CLOSURE_SCHEDULER(cl, scheduler);
gpr_atm last = gpr_atm_full_fetch_add(&lock->state, STATE_ELEM_COUNT_LOW_BIT);
GRPC_COMBINER_TRACE(gpr_log(
GPR_DEBUG, "C:%p grpc_combiner_execute c=%p cov=%d last=%" PRIdPTR, lock,
cl, covered_by_poller, last));
GPR_ASSERT(last & STATE_UNORPHANED); // ensure lock has not been destroyed
assert(cl->cb);
cl->error_data.scratch =
pack_error_data((error_data){error, covered_by_poller});
if (covered_by_poller) {
gpr_atm_no_barrier_fetch_add(&lock->elements_covered_by_poller, 1);
}
gpr_mpscq_push(&lock->queue, &cl->next_data.atm_next);
GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG,
"C:%p grpc_combiner_execute c=%p last=%" PRIdPTR,
lock, cl, last));
if (last == 1) {
gpr_atm_no_barrier_store(&lock->initiating_exec_ctx_or_null,
(gpr_atm)exec_ctx);
// first element on this list: add it to the list of combiner locks
// executing within this exec_ctx
push_last_on_exec_ctx(exec_ctx, lock);
} else {
// there may be a race with setting here: if that happens, we may delay
// offload for one or two actions, and that's fine
gpr_atm initiator =
gpr_atm_no_barrier_load(&lock->initiating_exec_ctx_or_null);
if (initiator != 0 && initiator != (gpr_atm)exec_ctx) {
gpr_atm_no_barrier_store(&lock->initiating_exec_ctx_or_null, 0);
}
}
GPR_ASSERT(last & STATE_UNORPHANED); // ensure lock has not been destroyed
assert(cl->cb);
cl->error_data.error = error;
gpr_mpscq_push(&lock->queue, &cl->next_data.atm_next);
GPR_TIMER_END("combiner.execute", 0);
}
#define COMBINER_FROM_CLOSURE_SCHEDULER(closure, scheduler_name) \
((grpc_combiner *)(((char *)((closure)->scheduler)) - \
offsetof(grpc_combiner, scheduler_name)))
static void combiner_exec_uncovered(grpc_exec_ctx *exec_ctx, grpc_closure *cl,
grpc_error *error) {
combiner_exec(exec_ctx,
COMBINER_FROM_CLOSURE_SCHEDULER(cl, uncovered_scheduler), cl,
error, false);
}
static void combiner_exec_covered(grpc_exec_ctx *exec_ctx, grpc_closure *cl,
grpc_error *error) {
combiner_exec(exec_ctx,
COMBINER_FROM_CLOSURE_SCHEDULER(cl, covered_scheduler), cl,
error, true);
}
static void move_next(grpc_exec_ctx *exec_ctx) {
exec_ctx->active_combiner =
exec_ctx->active_combiner->next_combiner_on_this_exec_ctx;
@ -250,9 +197,8 @@ static void offload(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
static void queue_offload(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) {
move_next(exec_ctx);
GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p queue_offload --> %p", lock,
lock->optional_workqueue));
grpc_closure_sched(exec_ctx, &lock->offload, GRPC_ERROR_NONE);
GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p queue_offload", lock));
GRPC_CLOSURE_SCHED(exec_ctx, &lock->offload, GRPC_ERROR_NONE);
}
bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
@ -263,22 +209,23 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
return false;
}
GRPC_COMBINER_TRACE(
gpr_log(GPR_DEBUG,
"C:%p grpc_combiner_continue_exec_ctx workqueue=%p "
"is_covered_by_poller=" IS_COVERED_BY_POLLER_FMT
" exec_ctx_ready_to_finish=%d "
"time_to_execute_final_list=%d",
lock, lock->optional_workqueue, IS_COVERED_BY_POLLER_ARGS(lock),
grpc_exec_ctx_ready_to_finish(exec_ctx),
lock->time_to_execute_final_list));
if (lock->optional_workqueue != NULL && is_covered_by_poller(lock) &&
grpc_exec_ctx_ready_to_finish(exec_ctx)) {
bool contended =
gpr_atm_no_barrier_load(&lock->initiating_exec_ctx_or_null) == 0;
GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG,
"C:%p grpc_combiner_continue_exec_ctx "
"contended=%d "
"exec_ctx_ready_to_finish=%d "
"time_to_execute_final_list=%d",
lock, contended,
grpc_exec_ctx_ready_to_finish(exec_ctx),
lock->time_to_execute_final_list));
if (contended && grpc_exec_ctx_ready_to_finish(exec_ctx) &&
grpc_executor_is_threaded()) {
GPR_TIMER_MARK("offload_from_finished_exec_ctx", 0);
// this execution context wants to move on, and we have a workqueue (and
// so can help the execution context out): schedule remaining work to be
// picked up on the workqueue
// this execution context wants to move on: schedule remaining work to be
// picked up on the executor
queue_offload(exec_ctx, lock);
GPR_TIMER_END("combiner.continue_exec_ctx", 0);
return true;
@ -295,29 +242,23 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
// queue is in an inconsistent state: use this as a cue that we should
// go off and do something else for a while (and come back later)
GPR_TIMER_MARK("delay_busy", 0);
if (lock->optional_workqueue != NULL && is_covered_by_poller(lock)) {
queue_offload(exec_ctx, lock);
}
queue_offload(exec_ctx, lock);
GPR_TIMER_END("combiner.continue_exec_ctx", 0);
return true;
}
GPR_TIMER_BEGIN("combiner.exec1", 0);
grpc_closure *cl = (grpc_closure *)n;
error_data err = unpack_error_data(cl->error_data.scratch);
grpc_error *cl_err = cl->error_data.error;
#ifndef NDEBUG
cl->scheduled = false;
#endif
cl->cb(exec_ctx, cl->cb_arg, err.error);
if (err.covered_by_poller) {
gpr_atm_no_barrier_fetch_add(&lock->elements_covered_by_poller, -1);
}
GRPC_ERROR_UNREF(err.error);
cl->cb(exec_ctx, cl->cb_arg, cl_err);
GRPC_ERROR_UNREF(cl_err);
GPR_TIMER_END("combiner.exec1", 0);
} else {
grpc_closure *c = lock->final_list.head;
GPR_ASSERT(c != NULL);
grpc_closure_list_init(&lock->final_list);
lock->final_list_covered_by_poller = false;
int loops = 0;
while (c != NULL) {
GPR_TIMER_BEGIN("combiner.exec_1final", 0);
@ -383,20 +324,20 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
static void enqueue_finally(grpc_exec_ctx *exec_ctx, void *closure,
grpc_error *error);
static void combiner_execute_finally(grpc_exec_ctx *exec_ctx,
grpc_combiner *lock, grpc_closure *closure,
grpc_error *error,
bool covered_by_poller) {
GRPC_COMBINER_TRACE(gpr_log(
GPR_DEBUG, "C:%p grpc_combiner_execute_finally c=%p; ac=%p; cov=%d", lock,
closure, exec_ctx->active_combiner, covered_by_poller));
static void combiner_finally_exec(grpc_exec_ctx *exec_ctx,
grpc_closure *closure, grpc_error *error) {
grpc_combiner *lock =
COMBINER_FROM_CLOSURE_SCHEDULER(closure, finally_scheduler);
GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG,
"C:%p grpc_combiner_execute_finally c=%p; ac=%p",
lock, closure, exec_ctx->active_combiner));
GPR_TIMER_BEGIN("combiner.execute_finally", 0);
if (exec_ctx->active_combiner != lock) {
GPR_TIMER_MARK("slowpath", 0);
grpc_closure_sched(
exec_ctx, grpc_closure_create(enqueue_finally, closure,
grpc_combiner_scheduler(lock, false)),
error);
GRPC_CLOSURE_SCHED(exec_ctx,
GRPC_CLOSURE_CREATE(enqueue_finally, closure,
grpc_combiner_scheduler(lock)),
error);
GPR_TIMER_END("combiner.execute_finally", 0);
return;
}
@ -404,42 +345,20 @@ static void combiner_execute_finally(grpc_exec_ctx *exec_ctx,
if (grpc_closure_list_empty(lock->final_list)) {
gpr_atm_full_fetch_add(&lock->state, STATE_ELEM_COUNT_LOW_BIT);
}
if (covered_by_poller) {
lock->final_list_covered_by_poller = true;
}
grpc_closure_list_append(&lock->final_list, closure, error);
GPR_TIMER_END("combiner.execute_finally", 0);
}
static void enqueue_finally(grpc_exec_ctx *exec_ctx, void *closure,
grpc_error *error) {
combiner_execute_finally(exec_ctx, exec_ctx->active_combiner, closure,
GRPC_ERROR_REF(error), false);
}
static void combiner_finally_exec_uncovered(grpc_exec_ctx *exec_ctx,
grpc_closure *cl,
grpc_error *error) {
combiner_execute_finally(exec_ctx, COMBINER_FROM_CLOSURE_SCHEDULER(
cl, uncovered_finally_scheduler),
cl, error, false);
}
static void combiner_finally_exec_covered(grpc_exec_ctx *exec_ctx,
grpc_closure *cl, grpc_error *error) {
combiner_execute_finally(
exec_ctx, COMBINER_FROM_CLOSURE_SCHEDULER(cl, covered_finally_scheduler),
cl, error, true);
combiner_finally_exec(exec_ctx, closure, GRPC_ERROR_REF(error));
}
grpc_closure_scheduler *grpc_combiner_scheduler(grpc_combiner *combiner,
bool covered_by_poller) {
return covered_by_poller ? &combiner->covered_scheduler
: &combiner->uncovered_scheduler;
grpc_closure_scheduler *grpc_combiner_scheduler(grpc_combiner *combiner) {
return &combiner->scheduler;
}
grpc_closure_scheduler *grpc_combiner_finally_scheduler(
grpc_combiner *combiner, bool covered_by_poller) {
return covered_by_poller ? &combiner->covered_finally_scheduler
: &combiner->uncovered_finally_scheduler;
grpc_combiner *combiner) {
return &combiner->finally_scheduler;
}

@ -33,10 +33,9 @@
// Initialize the lock, with an optional workqueue to shift load to when
// necessary
grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue);
grpc_combiner *grpc_combiner_create(void);
//#define GRPC_COMBINER_REFCOUNT_DEBUG
#ifdef GRPC_COMBINER_REFCOUNT_DEBUG
#ifndef NDEBUG
#define GRPC_COMBINER_DEBUG_ARGS \
, const char *file, int line, const char *reason
#define GRPC_COMBINER_REF(combiner, reason) \
@ -56,11 +55,9 @@ grpc_combiner *grpc_combiner_ref(grpc_combiner *lock GRPC_COMBINER_DEBUG_ARGS);
void grpc_combiner_unref(grpc_exec_ctx *exec_ctx,
grpc_combiner *lock GRPC_COMBINER_DEBUG_ARGS);
// Fetch a scheduler to schedule closures against
grpc_closure_scheduler *grpc_combiner_scheduler(grpc_combiner *lock,
bool covered_by_poller);
grpc_closure_scheduler *grpc_combiner_scheduler(grpc_combiner *lock);
// Scheduler to execute \a action within the lock just prior to unlocking.
grpc_closure_scheduler *grpc_combiner_finally_scheduler(grpc_combiner *lock,
bool covered_by_poller);
grpc_closure_scheduler *grpc_combiner_finally_scheduler(grpc_combiner *lock);
bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx);

@ -54,10 +54,6 @@ char* grpc_endpoint_get_peer(grpc_endpoint* ep) {
int grpc_endpoint_get_fd(grpc_endpoint* ep) { return ep->vtable->get_fd(ep); }
grpc_workqueue* grpc_endpoint_get_workqueue(grpc_endpoint* ep) {
return ep->vtable->get_workqueue(ep);
}
grpc_resource_user* grpc_endpoint_get_resource_user(grpc_endpoint* ep) {
return ep->vtable->get_resource_user(ep);
}

@ -37,7 +37,6 @@ struct grpc_endpoint_vtable {
grpc_slice_buffer *slices, grpc_closure *cb);
void (*write)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
grpc_slice_buffer *slices, grpc_closure *cb);
grpc_workqueue *(*get_workqueue)(grpc_endpoint *ep);
void (*add_to_pollset)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
grpc_pollset *pollset);
void (*add_to_pollset_set)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
@ -63,9 +62,6 @@ char *grpc_endpoint_get_peer(grpc_endpoint *ep);
*/
int grpc_endpoint_get_fd(grpc_endpoint *ep);
/* Retrieve a reference to the workqueue associated with this endpoint */
grpc_workqueue *grpc_endpoint_get_workqueue(grpc_endpoint *ep);
/* Write slices out to the socket.
If the connection is ready for more data after the end of the call, it

@ -30,10 +30,15 @@
#include <grpc/support/log_windows.h>
#endif
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/error_internal.h"
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/slice_internal.h"
#ifndef NDEBUG
grpc_tracer_flag grpc_trace_error_refcount = GRPC_TRACER_INITIALIZER(false);
#endif
static const char *error_int_name(grpc_error_ints key) {
switch (key) {
case GRPC_ERROR_INT_ERRNO:
@ -119,14 +124,14 @@ bool grpc_error_is_special(grpc_error *err) {
err == GRPC_ERROR_CANCELLED;
}
#ifdef GRPC_ERROR_REFCOUNT_DEBUG
grpc_error *grpc_error_ref(grpc_error *err, const char *file, int line,
const char *func) {
#ifndef NDEBUG
grpc_error *grpc_error_ref(grpc_error *err, const char *file, int line) {
if (grpc_error_is_special(err)) return err;
gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err,
gpr_atm_no_barrier_load(&err->atomics.refs.count),
gpr_atm_no_barrier_load(&err->atomics.refs.count) + 1, file, line,
func);
if (GRPC_TRACER_ON(grpc_trace_error_refcount)) {
gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d]", err,
gpr_atm_no_barrier_load(&err->atomics.refs.count),
gpr_atm_no_barrier_load(&err->atomics.refs.count) + 1, file, line);
}
gpr_ref(&err->atomics.refs);
return err;
}
@ -172,14 +177,14 @@ static void error_destroy(grpc_error *err) {
gpr_free(err);
}
#ifdef GRPC_ERROR_REFCOUNT_DEBUG
void grpc_error_unref(grpc_error *err, const char *file, int line,
const char *func) {
#ifndef NDEBUG
void grpc_error_unref(grpc_error *err, const char *file, int line) {
if (grpc_error_is_special(err)) return;
gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err,
gpr_atm_no_barrier_load(&err->atomics.refs.count),
gpr_atm_no_barrier_load(&err->atomics.refs.count) - 1, file, line,
func);
if (GRPC_TRACER_ON(grpc_trace_error_refcount)) {
gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d]", err,
gpr_atm_no_barrier_load(&err->atomics.refs.count),
gpr_atm_no_barrier_load(&err->atomics.refs.count) - 1, file, line);
}
if (gpr_unref(&err->atomics.refs)) {
error_destroy(err);
}
@ -202,13 +207,17 @@ static uint8_t get_placement(grpc_error **err, size_t size) {
if ((*err)->arena_size + slots > (*err)->arena_capacity) {
return UINT8_MAX;
}
#ifdef GRPC_ERROR_REFCOUNT_DEBUG
#ifndef NDEBUG
grpc_error *orig = *err;
#endif
*err = gpr_realloc(
*err, sizeof(grpc_error) + (*err)->arena_capacity * sizeof(intptr_t));
#ifdef GRPC_ERROR_REFCOUNT_DEBUG
if (*err != orig) gpr_log(GPR_DEBUG, "realloc %p -> %p", orig, *err);
#ifndef NDEBUG
if (GRPC_TRACER_ON(grpc_trace_error_refcount)) {
if (*err != orig) {
gpr_log(GPR_DEBUG, "realloc %p -> %p", orig, *err);
}
}
#endif
}
uint8_t placement = (*err)->arena_size;
@ -316,8 +325,10 @@ grpc_error *grpc_error_create(const char *file, int line, grpc_slice desc,
if (err == NULL) { // TODO(ctiller): make gpr_malloc return NULL
return GRPC_ERROR_OOM;
}
#ifdef GRPC_ERROR_REFCOUNT_DEBUG
gpr_log(GPR_DEBUG, "%p create [%s:%d]", err, file, line);
#ifndef NDEBUG
if (GRPC_TRACER_ON(grpc_trace_error_refcount)) {
gpr_log(GPR_DEBUG, "%p create [%s:%d]", err, file, line);
}
#endif
err->arena_size = 0;
@ -395,8 +406,10 @@ static grpc_error *copy_error_and_unref(grpc_error *in) {
new_arena_capacity = (uint8_t)(3 * new_arena_capacity / 2);
}
out = gpr_malloc(sizeof(*in) + new_arena_capacity * sizeof(intptr_t));
#ifdef GRPC_ERROR_REFCOUNT_DEBUG
gpr_log(GPR_DEBUG, "%p create copying %p", out, in);
#ifndef NDEBUG
if (GRPC_TRACER_ON(grpc_trace_error_refcount)) {
gpr_log(GPR_DEBUG, "%p create copying %p", out, in);
}
#endif
// bulk memcpy of the rest of the struct.
size_t skip = sizeof(&out->atomics);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save