aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Nicolas "Pixel" Noble <pixel@nobis-crew.org>2015-04-10 22:39:44 +0200
committerGravatar Nicolas "Pixel" Noble <pixel@nobis-crew.org>2015-04-10 22:39:44 +0200
commit7a6d8fde095501016dc98f43299be2facc79f17e (patch)
treef88972d1f17e78920ee1228dee061878562dd27b
parentf0863b02270f1b95d5c8b9f3f962959e4cbbdd42 (diff)
parent046c6656c961bb65508d725edb9adc60f63e3424 (diff)
Merge branch 'master' of github.com:grpc/grpc into freebsd
-rw-r--r--.gitmodules2
-rw-r--r--.travis.yml3
-rw-r--r--BUILD813
-rw-r--r--Makefile474
-rw-r--r--README.md8
-rw-r--r--build.json154
-rw-r--r--doc/interop-test-descriptions.md685
-rw-r--r--examples/pubsub/main.cc44
-rw-r--r--examples/pubsub/publisher.cc7
-rw-r--r--examples/pubsub/publisher.h2
-rw-r--r--examples/pubsub/publisher_test.cc31
-rw-r--r--examples/pubsub/subscriber.cc7
-rw-r--r--examples/pubsub/subscriber.h2
-rw-r--r--examples/pubsub/subscriber_test.cc19
-rw-r--r--include/grpc++/completion_queue.h7
-rw-r--r--include/grpc++/config.h53
-rw-r--r--include/grpc++/generic_stub.h4
-rw-r--r--include/grpc++/impl/call.h4
-rw-r--r--[-rwxr-xr-x]include/grpc++/impl/sync.h (renamed from src/php/ext/grpc/event.h)24
-rw-r--r--[-rwxr-xr-x]include/grpc++/impl/sync_cxx11.h (renamed from src/php/lib/autoload.php)26
-rw-r--r--include/grpc++/impl/sync_no_cxx11.h101
-rw-r--r--[-rwxr-xr-x]include/grpc++/impl/thd.h (renamed from src/php/tests/unit_tests/CompletionQueueTest.php)25
-rw-r--r--include/grpc++/impl/thd_cxx11.h45
-rw-r--r--include/grpc++/impl/thd_no_cxx11.h89
-rw-r--r--include/grpc++/server.h7
-rw-r--r--include/grpc/support/port_platform.h2
-rw-r--r--include/grpc/support/thd.h19
-rw-r--r--src/compiler/cpp_generator.cc273
-rw-r--r--src/compiler/cpp_generator.h34
-rw-r--r--src/compiler/cpp_plugin.cc50
-rw-r--r--src/compiler/generator_helpers.h41
-rw-r--r--src/compiler/objective_c_generator.cc236
-rw-r--r--src/compiler/objective_c_generator.h48
-rw-r--r--src/compiler/objective_c_generator_helpers.h58
-rw-r--r--src/compiler/objective_c_plugin.cc98
-rw-r--r--src/compiler/python_generator.cc193
-rw-r--r--src/compiler/python_generator.h30
-rw-r--r--src/compiler/python_plugin.cc58
-rw-r--r--src/compiler/ruby_generator.cc48
-rw-r--r--src/compiler/ruby_generator.h10
-rw-r--r--src/compiler/ruby_generator_helpers-inl.h12
-rw-r--r--src/compiler/ruby_generator_map-inl.h13
-rw-r--r--src/compiler/ruby_generator_string-inl.h43
-rw-r--r--src/compiler/ruby_plugin.cc30
-rw-r--r--src/core/channel/http_server_filter.c3
-rw-r--r--src/core/httpcli/parser.c2
-rw-r--r--src/core/iomgr/iocp_windows.c34
-rw-r--r--src/core/iomgr/iocp_windows.h1
-rw-r--r--src/core/iomgr/iomgr.c11
-rw-r--r--src/core/iomgr/socket_windows.c7
-rw-r--r--src/core/iomgr/socket_windows.h6
-rw-r--r--src/core/iomgr/tcp_server.h6
-rw-r--r--src/core/iomgr/tcp_server_posix.c60
-rw-r--r--src/core/iomgr/tcp_server_windows.c36
-rw-r--r--src/core/security/server_secure_chttp2.c19
-rw-r--r--src/core/support/thd.c66
-rw-r--r--src/core/support/thd_posix.c16
-rw-r--r--src/core/support/thd_win32.c72
-rw-r--r--src/core/surface/call.c2
-rw-r--r--src/core/surface/call.h9
-rw-r--r--src/core/surface/call_log_batch.c121
-rw-r--r--src/core/surface/completion_queue.c8
-rw-r--r--src/core/surface/completion_queue.h4
-rw-r--r--src/core/surface/init.c3
-rw-r--r--src/core/surface/server.c55
-rw-r--r--src/core/surface/server.h7
-rw-r--r--src/core/surface/server_chttp2.c7
-rw-r--r--src/core/transport/chttp2_transport.c2
-rw-r--r--src/core/transport/metadata.c8
-rw-r--r--src/core/tsi/ssl_transport_security.c4
-rw-r--r--src/cpp/client/generic_stub.cc51
-rw-r--r--src/cpp/client/insecure_credentials.cc2
-rw-r--r--src/cpp/client/secure_credentials.cc37
-rw-r--r--src/cpp/client/secure_credentials.h61
-rw-r--r--src/cpp/common/call.cc21
-rw-r--r--src/cpp/common/completion_queue.cc17
-rw-r--r--src/cpp/server/secure_server_credentials.cc34
-rw-r--r--src/cpp/server/secure_server_credentials.h60
-rw-r--r--src/cpp/server/server.cc16
-rw-r--r--src/cpp/server/server_builder.cc18
-rw-r--r--src/cpp/server/server_context.cc11
-rw-r--r--src/cpp/server/thread_pool.cc52
-rw-r--r--src/cpp/server/thread_pool.h14
-rw-r--r--src/cpp/util/time.cc6
-rw-r--r--src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs2
-rw-r--r--src/csharp/Grpc.Core/Grpc.Core.nuspec2
-rw-r--r--src/csharp/Grpc.Core/Properties/AssemblyInfo.cs2
-rw-r--r--src/csharp/Grpc.Examples.MathClient/MathClient.cs10
-rw-r--r--src/csharp/Grpc.Examples.MathClient/Properties/AssemblyInfo.cs2
-rw-r--r--src/csharp/Grpc.Examples.MathServer/.gitignore2
-rw-r--r--src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj52
-rw-r--r--src/csharp/Grpc.Examples.MathServer/MathServer.cs61
-rw-r--r--src/csharp/Grpc.Examples.MathServer/Properties/AssemblyInfo.cs12
-rw-r--r--src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj12
-rw-r--r--src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs21
-rw-r--r--src/csharp/Grpc.Examples.Tests/Properties/AssemblyInfo.cs2
-rw-r--r--src/csharp/Grpc.Examples.Tests/packages.config13
-rw-r--r--src/csharp/Grpc.Examples/MathExamples.cs67
-rw-r--r--src/csharp/Grpc.Examples/Properties/AssemblyInfo.cs2
-rw-r--r--src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs2
-rw-r--r--src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs2
-rw-r--r--src/csharp/Grpc.IntegrationTesting/Properties/AssemblyInfo.cs2
-rw-r--r--src/csharp/Grpc.nuspec4
-rw-r--r--src/csharp/Grpc.sln6
-rw-r--r--src/csharp/ext/grpc_csharp_ext.c4
-rw-r--r--src/node/binding.gyp21
-rw-r--r--src/node/examples/qps_test.js136
-rw-r--r--src/node/ext/byte_buffer.cc1
-rw-r--r--src/node/ext/channel.cc2
-rw-r--r--src/node/ext/server.cc2
-rw-r--r--src/node/index.js8
-rw-r--r--src/node/interop/interop_client.js12
-rw-r--r--src/node/src/client.js57
-rw-r--r--src/node/src/common.js23
-rw-r--r--src/node/src/server.js142
-rw-r--r--src/node/test/surface_test.js214
-rw-r--r--src/node/test/test_service.proto52
-rwxr-xr-xsrc/php/bin/generate_proto_php.sh40
-rwxr-xr-xsrc/php/bin/interop_client.sh5
-rwxr-xr-xsrc/php/bin/run_tests.sh6
-rw-r--r--src/php/composer.json15
-rw-r--r--src/php/composer.lock19
-rw-r--r--src/php/ext/grpc/byte_buffer.c17
-rw-r--r--src/php/ext/grpc/byte_buffer.h2
-rw-r--r--src/php/ext/grpc/call.c553
-rw-r--r--src/php/ext/grpc/call.h25
-rw-r--r--src/php/ext/grpc/channel.c40
-rwxr-xr-xsrc/php/ext/grpc/channel.h8
-rw-r--r--src/php/ext/grpc/completion_queue.c170
-rwxr-xr-xsrc/php/ext/grpc/config.m42
-rw-r--r--src/php/ext/grpc/credentials.c16
-rw-r--r--src/php/ext/grpc/event.c150
-rw-r--r--src/php/ext/grpc/php_grpc.c42
-rw-r--r--src/php/ext/grpc/server.c104
-rwxr-xr-xsrc/php/ext/grpc/server.h9
-rw-r--r--src/php/ext/grpc/server_credentials.c16
-rwxr-xr-xsrc/php/ext/grpc/server_credentials.h10
-rw-r--r--src/php/ext/grpc/timeval.c26
-rwxr-xr-xsrc/php/ext/grpc/timeval.h10
-rw-r--r--[-rwxr-xr-x]src/php/lib/Grpc/AbstractCall.php (renamed from src/php/lib/Grpc/BidiStreamingSurfaceActiveCall.php)51
-rwxr-xr-xsrc/php/lib/Grpc/ActiveCall.php123
-rwxr-xr-xsrc/php/lib/Grpc/BaseStub.php32
-rw-r--r--[-rwxr-xr-x]src/php/lib/Grpc/BidiStreamingCall.php (renamed from src/php/lib/Grpc/AbstractSurfaceActiveCall.php)84
-rw-r--r--[-rwxr-xr-x]src/php/lib/Grpc/ClientStreamingCall.php (renamed from src/php/lib/Grpc/ClientStreamingSurfaceActiveCall.php)31
-rw-r--r--[-rwxr-xr-x]src/php/lib/Grpc/ServerStreamingCall.php (renamed from src/php/lib/Grpc/ServerStreamingSurfaceActiveCall.php)43
-rw-r--r--[-rwxr-xr-x]src/php/lib/Grpc/UnaryCall.php (renamed from src/php/lib/Grpc/SimpleSurfaceActiveCall.php)34
-rwxr-xr-xsrc/php/tests/generated_code/GeneratedCodeTest.php5
-rwxr-xr-xsrc/php/tests/generated_code/math.php479
-rw-r--r--src/php/tests/generated_code/math.proto80
-rwxr-xr-xsrc/php/tests/interop/empty.php25
-rw-r--r--src/php/tests/interop/empty.proto43
-rwxr-xr-xsrc/php/tests/interop/interop_client.php10
-rwxr-xr-xsrc/php/tests/interop/messages.php1074
-rw-r--r--src/php/tests/interop/messages.proto132
-rwxr-xr-xsrc/php/tests/interop/test.php52
-rw-r--r--src/php/tests/interop/test.proto72
-rwxr-xr-xsrc/php/tests/unit_tests/CallTest.php66
-rwxr-xr-xsrc/php/tests/unit_tests/EndToEndTest.php192
-rwxr-xr-xsrc/php/tests/unit_tests/SecureEndToEndTest.php205
-rwxr-xr-xsrc/php/tests/unit_tests/TimevalTest.php6
-rw-r--r--src/python/README.md22
-rw-r--r--src/python/interop/interop/_insecure_interop_test.py4
-rw-r--r--src/python/interop/interop/_interop_test_case.py10
-rw-r--r--src/python/interop/interop/_secure_interop_test.py9
-rw-r--r--src/python/interop/interop/client.py30
-rw-r--r--src/python/interop/interop/empty_pb2.py5
-rw-r--r--src/python/interop/interop/messages_pb2.py5
-rw-r--r--src/python/interop/interop/methods.py60
-rw-r--r--src/python/interop/interop/server.py8
-rw-r--r--src/python/interop/interop/test_pb2.py223
-rw-r--r--src/python/interop/setup.py16
-rw-r--r--src/python/src/.gitignore3
-rw-r--r--src/python/src/MANIFEST.in1
-rw-r--r--src/python/src/README.rst27
-rw-r--r--src/python/src/grpc/_adapter/_call.c21
-rw-r--r--src/python/src/grpc/_adapter/_call.h5
-rw-r--r--src/python/src/grpc/_adapter/_channel.h5
-rw-r--r--src/python/src/grpc/_adapter/_client_credentials.h3
-rw-r--r--src/python/src/grpc/_adapter/_completion_queue.c76
-rw-r--r--src/python/src/grpc/_adapter/_completion_queue.h3
-rw-r--r--src/python/src/grpc/_adapter/_datatypes.py2
-rw-r--r--src/python/src/grpc/_adapter/_links_test.py11
-rw-r--r--src/python/src/grpc/_adapter/_low_test.py45
-rw-r--r--src/python/src/grpc/_adapter/_server.h5
-rw-r--r--src/python/src/grpc/_adapter/_server_credentials.h3
-rw-r--r--src/python/src/grpc/_adapter/rear.py10
-rw-r--r--src/python/src/grpc/early_adopter/implementations.py88
-rw-r--r--src/python/src/grpc/early_adopter/implementations_test.py4
-rw-r--r--src/python/src/setup.py21
-rwxr-xr-xsrc/ruby/Rakefile53
-rw-r--r--src/ruby/lib/grpc/generic/service.rb17
-rw-r--r--src/ruby/lib/grpc/version.rb2
-rw-r--r--src/ruby/spec/generic/active_call_spec.rb4
-rw-r--r--src/ruby/spec/generic/client_stub_spec.rb8
-rw-r--r--src/ruby/spec/generic/rpc_server_spec.rb42
-rw-r--r--templates/BUILD.template110
-rw-r--r--templates/Makefile.template31
-rw-r--r--templates/vsprojects/vs2010/Grpc.mak.template107
-rw-r--r--templates/vsprojects/vs2010/gpr.vcxproj.filters.template (renamed from templates/vsprojects/vs2013/gpr_shared.vcxproj.filters.template)0
-rw-r--r--templates/vsprojects/vs2010/gpr.vcxproj.template2
-rw-r--r--templates/vsprojects/vs2010/gpr_test_util.vcxproj.template2
-rw-r--r--templates/vsprojects/vs2010/grpc++.vcxproj.filters.template2
-rw-r--r--templates/vsprojects/vs2010/grpc++.vcxproj.template2
-rw-r--r--templates/vsprojects/vs2010/grpc.sln.template59
-rw-r--r--templates/vsprojects/vs2010/grpc.vcxproj.filters.template (renamed from templates/vsprojects/vs2013/grpc_shared.vcxproj.filters.template)0
-rw-r--r--templates/vsprojects/vs2010/grpc.vcxproj.template2
-rw-r--r--templates/vsprojects/vs2010/grpc_csharp_ext.vcxproj.template2
-rw-r--r--templates/vsprojects/vs2010/grpc_csharp_ext_shared.vcxproj.template2
-rw-r--r--templates/vsprojects/vs2010/grpc_test_util.vcxproj.template2
-rw-r--r--templates/vsprojects/vs2010/grpc_unsecure.vcxproj.filters.template2
-rw-r--r--templates/vsprojects/vs2010/grpc_unsecure.vcxproj.template2
-rw-r--r--templates/vsprojects/vs2010/vcxproj.filters_defs.include64
-rw-r--r--templates/vsprojects/vs2010/vcxproj_defs.include131
-rw-r--r--templates/vsprojects/vs2013/gpr_shared.vcxproj.template2
-rw-r--r--templates/vsprojects/vs2013/grpc.sln.template4
-rw-r--r--templates/vsprojects/vs2013/grpc_shared.vcxproj.template2
-rw-r--r--test/compiler/python_plugin_test.py2
-rw-r--r--test/core/end2end/tests/cancel_after_invoke.c6
-rw-r--r--test/core/end2end/tests/cancel_test_helpers.h9
-rw-r--r--test/core/iomgr/tcp_server_posix_test.c10
-rw-r--r--test/core/support/thd_test.c11
-rw-r--r--test/core/tsi/transport_security_test.c10
-rw-r--r--test/core/util/port_posix.c7
-rw-r--r--test/core/util/test_config.h4
-rw-r--r--test/cpp/end2end/async_end2end_test.cc15
-rw-r--r--test/cpp/end2end/end2end_test.cc75
-rw-r--r--test/cpp/end2end/generic_end2end_test.cc89
-rw-r--r--test/cpp/interop/client.cc6
-rw-r--r--test/cpp/interop/server.cc13
-rw-r--r--test/cpp/qps/client.h42
-rw-r--r--test/cpp/qps/client_async.cc206
-rw-r--r--test/cpp/qps/client_sync.cc74
-rw-r--r--test/cpp/qps/driver.cc52
-rw-r--r--test/cpp/qps/driver.h7
-rw-r--r--test/cpp/qps/histogram.h6
-rwxr-xr-xtest/cpp/qps/qps-sweep.sh25
-rw-r--r--test/cpp/qps/qps_driver.cc53
-rw-r--r--test/cpp/qps/qpstest.proto78
-rw-r--r--test/cpp/qps/report.cc94
-rw-r--r--[-rwxr-xr-x]test/cpp/qps/report.h (renamed from src/php/ext/grpc/completion_queue.h)43
-rw-r--r--test/cpp/qps/server.cc172
-rw-r--r--test/cpp/qps/server.h2
-rw-r--r--test/cpp/qps/server_async.cc145
-rw-r--r--test/cpp/qps/server_sync.cc22
-rw-r--r--test/cpp/qps/smoke_test.cc149
-rwxr-xr-xtest/cpp/qps/smoke_test.sh28
-rw-r--r--test/cpp/qps/stats.h4
-rw-r--r--test/cpp/qps/timer.cc1
-rw-r--r--test/cpp/qps/worker.cc109
-rw-r--r--test/cpp/util/cli_call.cc106
-rw-r--r--test/cpp/util/cli_call.h53
-rw-r--r--test/cpp/util/cli_call_test.cc131
-rw-r--r--test/cpp/util/grpc_cli.cc139
-rw-r--r--test/cpp/util/messages.proto2
-rw-r--r--test/cpp/util/time_test.cc15
m---------third_party/openssl0
-rwxr-xr-xtools/distpackages/build_deb_packages.sh33
-rw-r--r--tools/distpackages/templates/libgrpc/DEBIAN/control3
-rwxr-xr-xtools/distrib/python/submit.py54
-rw-r--r--tools/dockerfile/grpc_build_deb/Dockerfile13
-rw-r--r--tools/dockerfile/grpc_build_deb/version.txt1
-rw-r--r--tools/dockerfile/grpc_dist_proto/version.txt2
-rw-r--r--tools/dockerfile/grpc_java_base/Dockerfile2
-rw-r--r--tools/dockerfile/grpc_php/Dockerfile6
-rw-r--r--tools/dockerfile/grpc_php_base/Dockerfile26
-rw-r--r--tools/dockerfile/grpc_scan_build/Dockerfile47
-rwxr-xr-xtools/gce_setup/grpc_docker.sh94
-rwxr-xr-xtools/gce_setup/interop_test_runner.sh2
-rwxr-xr-xtools/gce_setup/shared_startup_funcs.sh6
-rwxr-xr-xtools/run_tests/run_tests.py21
-rw-r--r--tools/run_tests/tests.json10
-rw-r--r--vsprojects/vs2010/Grpc.mak712
-rw-r--r--vsprojects/vs2010/build_openssl_x86.bat8
-rw-r--r--vsprojects/vs2010/global.props14
-rw-r--r--vsprojects/vs2010/gpr.vcxproj (renamed from vsprojects/vs2013/gpr_shared.vcxproj)15
-rw-r--r--vsprojects/vs2010/gpr.vcxproj.filters (renamed from vsprojects/vs2013/gpr_shared.vcxproj.filters)9
-rw-r--r--vsprojects/vs2010/gpr_test_util.vcxproj93
-rw-r--r--vsprojects/vs2010/grpc++.vcxproj185
-rw-r--r--vsprojects/vs2010/grpc++.vcxproj.filters235
-rw-r--r--vsprojects/vs2010/grpc.sln97
-rw-r--r--vsprojects/vs2010/grpc.vcxproj (renamed from vsprojects/vs2013/grpc_shared.vcxproj)23
-rw-r--r--vsprojects/vs2010/grpc.vcxproj.filters (renamed from vsprojects/vs2013/grpc_shared.vcxproj.filters)12
-rw-r--r--vsprojects/vs2010/grpc_csharp_ext.vcxproj94
-rw-r--r--vsprojects/vs2010/grpc_csharp_ext_shared.vcxproj98
-rw-r--r--vsprojects/vs2010/grpc_test_util.vcxproj116
-rw-r--r--vsprojects/vs2010/grpc_unsecure.vcxproj378
-rw-r--r--vsprojects/vs2010/grpc_unsecure.vcxproj.filters619
-rw-r--r--vsprojects/vs2010/ssl.props13
-rw-r--r--vsprojects/vs2010/third_party/zlibvc.vcxproj188
-rw-r--r--vsprojects/vs2010/winsock.props12
-rw-r--r--vsprojects/vs2013/gpr.vcxproj5
-rw-r--r--vsprojects/vs2013/gpr.vcxproj.filters9
-rw-r--r--vsprojects/vs2013/gpr_test_util.vcxproj3
-rw-r--r--vsprojects/vs2013/grpc++.vcxproj20
-rw-r--r--vsprojects/vs2013/grpc++.vcxproj.filters48
-rw-r--r--vsprojects/vs2013/grpc.sln5
-rw-r--r--vsprojects/vs2013/grpc.vcxproj5
-rw-r--r--vsprojects/vs2013/grpc.vcxproj.filters12
-rw-r--r--vsprojects/vs2013/grpc_test_util.vcxproj3
-rw-r--r--vsprojects/vs2013/grpc_unsecure.vcxproj4
-rw-r--r--vsprojects/vs2013/grpc_unsecure.vcxproj.filters9
301 files changed, 12075 insertions, 4662 deletions
diff --git a/.gitmodules b/.gitmodules
index 97b7197be3..557321001f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -11,4 +11,4 @@
branch = v3.0.0-alpha-1
[submodule "third_party/gflags"]
path = third_party/gflags
- url = https://code.google.com/p/gflags
+ url = https://github.com/gflags/gflags.git
diff --git a/.travis.yml b/.travis.yml
index e43a89e453..165f8923c0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,9 +19,12 @@ env:
- CONFIG=opt TEST=python
- CONFIG=gcov TEST=c
- CONFIG=gcov TEST=c++
+ - USE_GCC=4.4 CONFIG=opt TEST=build
+ - USE_GCC=4.5 CONFIG=opt TEST=build
script:
- rvm use $RUBY_VERSION
- gem install bundler
+ - if [ ! -z "$USE_GCC" ] ; then export CC=gcc-$USE_GCC ; export CXX=g++-$USE_GCC ; fi
- ./tools/run_tests/run_tests.py -l $TEST -t -j 16 -c $CONFIG -s 4.0
after_success:
- if [ "$CONFIG" = "gcov" ] ; then coveralls --exclude third_party --exclude gens -b. --gcov-options '\-p' ; fi
diff --git a/BUILD b/BUILD
new file mode 100644
index 0000000000..233cf65045
--- /dev/null
+++ b/BUILD
@@ -0,0 +1,813 @@
+# GRPC Bazel BUILD file.
+# This currently builds C and C++ code.
+
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+licenses(["notice"]) # 3-clause BSD
+
+package(default_visibility = ["//visibility:public"])
+
+
+
+
+cc_library(
+ name = "gpr",
+ srcs = [
+ "src/core/support/env.h",
+ "src/core/support/file.h",
+ "src/core/support/murmur_hash.h",
+ "src/core/support/string.h",
+ "src/core/support/string_win32.h",
+ "src/core/support/thd_internal.h",
+ "src/core/support/alloc.c",
+ "src/core/support/cancellable.c",
+ "src/core/support/cmdline.c",
+ "src/core/support/cpu_iphone.c",
+ "src/core/support/cpu_linux.c",
+ "src/core/support/cpu_posix.c",
+ "src/core/support/cpu_windows.c",
+ "src/core/support/env_linux.c",
+ "src/core/support/env_posix.c",
+ "src/core/support/env_win32.c",
+ "src/core/support/file.c",
+ "src/core/support/file_posix.c",
+ "src/core/support/file_win32.c",
+ "src/core/support/histogram.c",
+ "src/core/support/host_port.c",
+ "src/core/support/log.c",
+ "src/core/support/log_android.c",
+ "src/core/support/log_linux.c",
+ "src/core/support/log_posix.c",
+ "src/core/support/log_win32.c",
+ "src/core/support/murmur_hash.c",
+ "src/core/support/slice.c",
+ "src/core/support/slice_buffer.c",
+ "src/core/support/string.c",
+ "src/core/support/string_posix.c",
+ "src/core/support/string_win32.c",
+ "src/core/support/sync.c",
+ "src/core/support/sync_posix.c",
+ "src/core/support/sync_win32.c",
+ "src/core/support/thd.c",
+ "src/core/support/thd_posix.c",
+ "src/core/support/thd_win32.c",
+ "src/core/support/time.c",
+ "src/core/support/time_posix.c",
+ "src/core/support/time_win32.c",
+ ],
+ hdrs = [
+ "include/grpc/support/alloc.h",
+ "include/grpc/support/atm.h",
+ "include/grpc/support/atm_gcc_atomic.h",
+ "include/grpc/support/atm_gcc_sync.h",
+ "include/grpc/support/atm_win32.h",
+ "include/grpc/support/cancellable_platform.h",
+ "include/grpc/support/cmdline.h",
+ "include/grpc/support/cpu.h",
+ "include/grpc/support/histogram.h",
+ "include/grpc/support/host_port.h",
+ "include/grpc/support/log.h",
+ "include/grpc/support/log_win32.h",
+ "include/grpc/support/port_platform.h",
+ "include/grpc/support/slice.h",
+ "include/grpc/support/slice_buffer.h",
+ "include/grpc/support/sync.h",
+ "include/grpc/support/sync_generic.h",
+ "include/grpc/support/sync_posix.h",
+ "include/grpc/support/sync_win32.h",
+ "include/grpc/support/thd.h",
+ "include/grpc/support/time.h",
+ "include/grpc/support/useful.h",
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+ ],
+)
+
+
+cc_library(
+ name = "grpc",
+ srcs = [
+ "src/core/httpcli/format_request.h",
+ "src/core/httpcli/httpcli.h",
+ "src/core/httpcli/httpcli_security_context.h",
+ "src/core/httpcli/parser.h",
+ "src/core/security/auth.h",
+ "src/core/security/base64.h",
+ "src/core/security/credentials.h",
+ "src/core/security/json_token.h",
+ "src/core/security/secure_endpoint.h",
+ "src/core/security/secure_transport_setup.h",
+ "src/core/security/security_context.h",
+ "src/core/tsi/fake_transport_security.h",
+ "src/core/tsi/ssl_transport_security.h",
+ "src/core/tsi/transport_security.h",
+ "src/core/tsi/transport_security_interface.h",
+ "src/core/channel/census_filter.h",
+ "src/core/channel/channel_args.h",
+ "src/core/channel/channel_stack.h",
+ "src/core/channel/child_channel.h",
+ "src/core/channel/client_channel.h",
+ "src/core/channel/client_setup.h",
+ "src/core/channel/connected_channel.h",
+ "src/core/channel/http_client_filter.h",
+ "src/core/channel/http_filter.h",
+ "src/core/channel/http_server_filter.h",
+ "src/core/channel/metadata_buffer.h",
+ "src/core/channel/noop_filter.h",
+ "src/core/compression/algorithm.h",
+ "src/core/compression/message_compress.h",
+ "src/core/debug/trace.h",
+ "src/core/iomgr/alarm.h",
+ "src/core/iomgr/alarm_heap.h",
+ "src/core/iomgr/alarm_internal.h",
+ "src/core/iomgr/endpoint.h",
+ "src/core/iomgr/endpoint_pair.h",
+ "src/core/iomgr/fd_posix.h",
+ "src/core/iomgr/iocp_windows.h",
+ "src/core/iomgr/iomgr.h",
+ "src/core/iomgr/iomgr_internal.h",
+ "src/core/iomgr/iomgr_posix.h",
+ "src/core/iomgr/pollset.h",
+ "src/core/iomgr/pollset_kick.h",
+ "src/core/iomgr/pollset_kick_posix.h",
+ "src/core/iomgr/pollset_kick_windows.h",
+ "src/core/iomgr/pollset_posix.h",
+ "src/core/iomgr/pollset_windows.h",
+ "src/core/iomgr/resolve_address.h",
+ "src/core/iomgr/sockaddr.h",
+ "src/core/iomgr/sockaddr_posix.h",
+ "src/core/iomgr/sockaddr_utils.h",
+ "src/core/iomgr/sockaddr_win32.h",
+ "src/core/iomgr/socket_utils_posix.h",
+ "src/core/iomgr/socket_windows.h",
+ "src/core/iomgr/tcp_client.h",
+ "src/core/iomgr/tcp_posix.h",
+ "src/core/iomgr/tcp_server.h",
+ "src/core/iomgr/tcp_windows.h",
+ "src/core/iomgr/time_averaged_stats.h",
+ "src/core/iomgr/wakeup_fd_pipe.h",
+ "src/core/iomgr/wakeup_fd_posix.h",
+ "src/core/json/json.h",
+ "src/core/json/json_common.h",
+ "src/core/json/json_reader.h",
+ "src/core/json/json_writer.h",
+ "src/core/statistics/census_interface.h",
+ "src/core/statistics/census_log.h",
+ "src/core/statistics/census_rpc_stats.h",
+ "src/core/statistics/census_tracing.h",
+ "src/core/statistics/hash_table.h",
+ "src/core/statistics/window_stats.h",
+ "src/core/surface/byte_buffer_queue.h",
+ "src/core/surface/call.h",
+ "src/core/surface/channel.h",
+ "src/core/surface/client.h",
+ "src/core/surface/completion_queue.h",
+ "src/core/surface/event_string.h",
+ "src/core/surface/init.h",
+ "src/core/surface/server.h",
+ "src/core/surface/surface_trace.h",
+ "src/core/transport/chttp2/alpn.h",
+ "src/core/transport/chttp2/bin_encoder.h",
+ "src/core/transport/chttp2/frame.h",
+ "src/core/transport/chttp2/frame_data.h",
+ "src/core/transport/chttp2/frame_goaway.h",
+ "src/core/transport/chttp2/frame_ping.h",
+ "src/core/transport/chttp2/frame_rst_stream.h",
+ "src/core/transport/chttp2/frame_settings.h",
+ "src/core/transport/chttp2/frame_window_update.h",
+ "src/core/transport/chttp2/hpack_parser.h",
+ "src/core/transport/chttp2/hpack_table.h",
+ "src/core/transport/chttp2/http2_errors.h",
+ "src/core/transport/chttp2/huffsyms.h",
+ "src/core/transport/chttp2/status_conversion.h",
+ "src/core/transport/chttp2/stream_encoder.h",
+ "src/core/transport/chttp2/stream_map.h",
+ "src/core/transport/chttp2/timeout_encoding.h",
+ "src/core/transport/chttp2/varint.h",
+ "src/core/transport/chttp2_transport.h",
+ "src/core/transport/metadata.h",
+ "src/core/transport/stream_op.h",
+ "src/core/transport/transport.h",
+ "src/core/transport/transport_impl.h",
+ "src/core/httpcli/format_request.c",
+ "src/core/httpcli/httpcli.c",
+ "src/core/httpcli/httpcli_security_context.c",
+ "src/core/httpcli/parser.c",
+ "src/core/security/auth.c",
+ "src/core/security/base64.c",
+ "src/core/security/credentials.c",
+ "src/core/security/credentials_posix.c",
+ "src/core/security/credentials_win32.c",
+ "src/core/security/factories.c",
+ "src/core/security/google_default_credentials.c",
+ "src/core/security/json_token.c",
+ "src/core/security/secure_endpoint.c",
+ "src/core/security/secure_transport_setup.c",
+ "src/core/security/security_context.c",
+ "src/core/security/server_secure_chttp2.c",
+ "src/core/surface/init_secure.c",
+ "src/core/surface/secure_channel_create.c",
+ "src/core/tsi/fake_transport_security.c",
+ "src/core/tsi/ssl_transport_security.c",
+ "src/core/tsi/transport_security.c",
+ "src/core/channel/call_op_string.c",
+ "src/core/channel/census_filter.c",
+ "src/core/channel/channel_args.c",
+ "src/core/channel/channel_stack.c",
+ "src/core/channel/child_channel.c",
+ "src/core/channel/client_channel.c",
+ "src/core/channel/client_setup.c",
+ "src/core/channel/connected_channel.c",
+ "src/core/channel/http_client_filter.c",
+ "src/core/channel/http_filter.c",
+ "src/core/channel/http_server_filter.c",
+ "src/core/channel/metadata_buffer.c",
+ "src/core/channel/noop_filter.c",
+ "src/core/compression/algorithm.c",
+ "src/core/compression/message_compress.c",
+ "src/core/debug/trace.c",
+ "src/core/iomgr/alarm.c",
+ "src/core/iomgr/alarm_heap.c",
+ "src/core/iomgr/endpoint.c",
+ "src/core/iomgr/endpoint_pair_posix.c",
+ "src/core/iomgr/fd_posix.c",
+ "src/core/iomgr/iocp_windows.c",
+ "src/core/iomgr/iomgr.c",
+ "src/core/iomgr/iomgr_posix.c",
+ "src/core/iomgr/iomgr_windows.c",
+ "src/core/iomgr/pollset_kick.c",
+ "src/core/iomgr/pollset_multipoller_with_epoll.c",
+ "src/core/iomgr/pollset_multipoller_with_poll_posix.c",
+ "src/core/iomgr/pollset_posix.c",
+ "src/core/iomgr/pollset_windows.c",
+ "src/core/iomgr/resolve_address_posix.c",
+ "src/core/iomgr/resolve_address_windows.c",
+ "src/core/iomgr/sockaddr_utils.c",
+ "src/core/iomgr/socket_utils_common_posix.c",
+ "src/core/iomgr/socket_utils_linux.c",
+ "src/core/iomgr/socket_utils_posix.c",
+ "src/core/iomgr/socket_windows.c",
+ "src/core/iomgr/tcp_client_posix.c",
+ "src/core/iomgr/tcp_client_windows.c",
+ "src/core/iomgr/tcp_posix.c",
+ "src/core/iomgr/tcp_server_posix.c",
+ "src/core/iomgr/tcp_server_windows.c",
+ "src/core/iomgr/tcp_windows.c",
+ "src/core/iomgr/time_averaged_stats.c",
+ "src/core/iomgr/wakeup_fd_eventfd.c",
+ "src/core/iomgr/wakeup_fd_nospecial.c",
+ "src/core/iomgr/wakeup_fd_pipe.c",
+ "src/core/iomgr/wakeup_fd_posix.c",
+ "src/core/json/json.c",
+ "src/core/json/json_reader.c",
+ "src/core/json/json_string.c",
+ "src/core/json/json_writer.c",
+ "src/core/statistics/census_init.c",
+ "src/core/statistics/census_log.c",
+ "src/core/statistics/census_rpc_stats.c",
+ "src/core/statistics/census_tracing.c",
+ "src/core/statistics/hash_table.c",
+ "src/core/statistics/window_stats.c",
+ "src/core/surface/byte_buffer.c",
+ "src/core/surface/byte_buffer_queue.c",
+ "src/core/surface/byte_buffer_reader.c",
+ "src/core/surface/call.c",
+ "src/core/surface/call_details.c",
+ "src/core/surface/call_log_batch.c",
+ "src/core/surface/channel.c",
+ "src/core/surface/channel_create.c",
+ "src/core/surface/client.c",
+ "src/core/surface/completion_queue.c",
+ "src/core/surface/event_string.c",
+ "src/core/surface/init.c",
+ "src/core/surface/lame_client.c",
+ "src/core/surface/metadata_array.c",
+ "src/core/surface/server.c",
+ "src/core/surface/server_chttp2.c",
+ "src/core/surface/server_create.c",
+ "src/core/surface/surface_trace.c",
+ "src/core/transport/chttp2/alpn.c",
+ "src/core/transport/chttp2/bin_encoder.c",
+ "src/core/transport/chttp2/frame_data.c",
+ "src/core/transport/chttp2/frame_goaway.c",
+ "src/core/transport/chttp2/frame_ping.c",
+ "src/core/transport/chttp2/frame_rst_stream.c",
+ "src/core/transport/chttp2/frame_settings.c",
+ "src/core/transport/chttp2/frame_window_update.c",
+ "src/core/transport/chttp2/hpack_parser.c",
+ "src/core/transport/chttp2/hpack_table.c",
+ "src/core/transport/chttp2/huffsyms.c",
+ "src/core/transport/chttp2/status_conversion.c",
+ "src/core/transport/chttp2/stream_encoder.c",
+ "src/core/transport/chttp2/stream_map.c",
+ "src/core/transport/chttp2/timeout_encoding.c",
+ "src/core/transport/chttp2/varint.c",
+ "src/core/transport/chttp2_transport.c",
+ "src/core/transport/metadata.c",
+ "src/core/transport/stream_op.c",
+ "src/core/transport/transport.c",
+ ],
+ hdrs = [
+ "include/grpc/grpc_security.h",
+ "include/grpc/byte_buffer.h",
+ "include/grpc/byte_buffer_reader.h",
+ "include/grpc/grpc.h",
+ "include/grpc/grpc_http.h",
+ "include/grpc/status.h",
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+ "//external:libssl",
+ ":gpr",
+ ],
+)
+
+
+cc_library(
+ name = "grpc_unsecure",
+ srcs = [
+ "src/core/channel/census_filter.h",
+ "src/core/channel/channel_args.h",
+ "src/core/channel/channel_stack.h",
+ "src/core/channel/child_channel.h",
+ "src/core/channel/client_channel.h",
+ "src/core/channel/client_setup.h",
+ "src/core/channel/connected_channel.h",
+ "src/core/channel/http_client_filter.h",
+ "src/core/channel/http_filter.h",
+ "src/core/channel/http_server_filter.h",
+ "src/core/channel/metadata_buffer.h",
+ "src/core/channel/noop_filter.h",
+ "src/core/compression/algorithm.h",
+ "src/core/compression/message_compress.h",
+ "src/core/debug/trace.h",
+ "src/core/iomgr/alarm.h",
+ "src/core/iomgr/alarm_heap.h",
+ "src/core/iomgr/alarm_internal.h",
+ "src/core/iomgr/endpoint.h",
+ "src/core/iomgr/endpoint_pair.h",
+ "src/core/iomgr/fd_posix.h",
+ "src/core/iomgr/iocp_windows.h",
+ "src/core/iomgr/iomgr.h",
+ "src/core/iomgr/iomgr_internal.h",
+ "src/core/iomgr/iomgr_posix.h",
+ "src/core/iomgr/pollset.h",
+ "src/core/iomgr/pollset_kick.h",
+ "src/core/iomgr/pollset_kick_posix.h",
+ "src/core/iomgr/pollset_kick_windows.h",
+ "src/core/iomgr/pollset_posix.h",
+ "src/core/iomgr/pollset_windows.h",
+ "src/core/iomgr/resolve_address.h",
+ "src/core/iomgr/sockaddr.h",
+ "src/core/iomgr/sockaddr_posix.h",
+ "src/core/iomgr/sockaddr_utils.h",
+ "src/core/iomgr/sockaddr_win32.h",
+ "src/core/iomgr/socket_utils_posix.h",
+ "src/core/iomgr/socket_windows.h",
+ "src/core/iomgr/tcp_client.h",
+ "src/core/iomgr/tcp_posix.h",
+ "src/core/iomgr/tcp_server.h",
+ "src/core/iomgr/tcp_windows.h",
+ "src/core/iomgr/time_averaged_stats.h",
+ "src/core/iomgr/wakeup_fd_pipe.h",
+ "src/core/iomgr/wakeup_fd_posix.h",
+ "src/core/json/json.h",
+ "src/core/json/json_common.h",
+ "src/core/json/json_reader.h",
+ "src/core/json/json_writer.h",
+ "src/core/statistics/census_interface.h",
+ "src/core/statistics/census_log.h",
+ "src/core/statistics/census_rpc_stats.h",
+ "src/core/statistics/census_tracing.h",
+ "src/core/statistics/hash_table.h",
+ "src/core/statistics/window_stats.h",
+ "src/core/surface/byte_buffer_queue.h",
+ "src/core/surface/call.h",
+ "src/core/surface/channel.h",
+ "src/core/surface/client.h",
+ "src/core/surface/completion_queue.h",
+ "src/core/surface/event_string.h",
+ "src/core/surface/init.h",
+ "src/core/surface/server.h",
+ "src/core/surface/surface_trace.h",
+ "src/core/transport/chttp2/alpn.h",
+ "src/core/transport/chttp2/bin_encoder.h",
+ "src/core/transport/chttp2/frame.h",
+ "src/core/transport/chttp2/frame_data.h",
+ "src/core/transport/chttp2/frame_goaway.h",
+ "src/core/transport/chttp2/frame_ping.h",
+ "src/core/transport/chttp2/frame_rst_stream.h",
+ "src/core/transport/chttp2/frame_settings.h",
+ "src/core/transport/chttp2/frame_window_update.h",
+ "src/core/transport/chttp2/hpack_parser.h",
+ "src/core/transport/chttp2/hpack_table.h",
+ "src/core/transport/chttp2/http2_errors.h",
+ "src/core/transport/chttp2/huffsyms.h",
+ "src/core/transport/chttp2/status_conversion.h",
+ "src/core/transport/chttp2/stream_encoder.h",
+ "src/core/transport/chttp2/stream_map.h",
+ "src/core/transport/chttp2/timeout_encoding.h",
+ "src/core/transport/chttp2/varint.h",
+ "src/core/transport/chttp2_transport.h",
+ "src/core/transport/metadata.h",
+ "src/core/transport/stream_op.h",
+ "src/core/transport/transport.h",
+ "src/core/transport/transport_impl.h",
+ "src/core/surface/init_unsecure.c",
+ "src/core/channel/call_op_string.c",
+ "src/core/channel/census_filter.c",
+ "src/core/channel/channel_args.c",
+ "src/core/channel/channel_stack.c",
+ "src/core/channel/child_channel.c",
+ "src/core/channel/client_channel.c",
+ "src/core/channel/client_setup.c",
+ "src/core/channel/connected_channel.c",
+ "src/core/channel/http_client_filter.c",
+ "src/core/channel/http_filter.c",
+ "src/core/channel/http_server_filter.c",
+ "src/core/channel/metadata_buffer.c",
+ "src/core/channel/noop_filter.c",
+ "src/core/compression/algorithm.c",
+ "src/core/compression/message_compress.c",
+ "src/core/debug/trace.c",
+ "src/core/iomgr/alarm.c",
+ "src/core/iomgr/alarm_heap.c",
+ "src/core/iomgr/endpoint.c",
+ "src/core/iomgr/endpoint_pair_posix.c",
+ "src/core/iomgr/fd_posix.c",
+ "src/core/iomgr/iocp_windows.c",
+ "src/core/iomgr/iomgr.c",
+ "src/core/iomgr/iomgr_posix.c",
+ "src/core/iomgr/iomgr_windows.c",
+ "src/core/iomgr/pollset_kick.c",
+ "src/core/iomgr/pollset_multipoller_with_epoll.c",
+ "src/core/iomgr/pollset_multipoller_with_poll_posix.c",
+ "src/core/iomgr/pollset_posix.c",
+ "src/core/iomgr/pollset_windows.c",
+ "src/core/iomgr/resolve_address_posix.c",
+ "src/core/iomgr/resolve_address_windows.c",
+ "src/core/iomgr/sockaddr_utils.c",
+ "src/core/iomgr/socket_utils_common_posix.c",
+ "src/core/iomgr/socket_utils_linux.c",
+ "src/core/iomgr/socket_utils_posix.c",
+ "src/core/iomgr/socket_windows.c",
+ "src/core/iomgr/tcp_client_posix.c",
+ "src/core/iomgr/tcp_client_windows.c",
+ "src/core/iomgr/tcp_posix.c",
+ "src/core/iomgr/tcp_server_posix.c",
+ "src/core/iomgr/tcp_server_windows.c",
+ "src/core/iomgr/tcp_windows.c",
+ "src/core/iomgr/time_averaged_stats.c",
+ "src/core/iomgr/wakeup_fd_eventfd.c",
+ "src/core/iomgr/wakeup_fd_nospecial.c",
+ "src/core/iomgr/wakeup_fd_pipe.c",
+ "src/core/iomgr/wakeup_fd_posix.c",
+ "src/core/json/json.c",
+ "src/core/json/json_reader.c",
+ "src/core/json/json_string.c",
+ "src/core/json/json_writer.c",
+ "src/core/statistics/census_init.c",
+ "src/core/statistics/census_log.c",
+ "src/core/statistics/census_rpc_stats.c",
+ "src/core/statistics/census_tracing.c",
+ "src/core/statistics/hash_table.c",
+ "src/core/statistics/window_stats.c",
+ "src/core/surface/byte_buffer.c",
+ "src/core/surface/byte_buffer_queue.c",
+ "src/core/surface/byte_buffer_reader.c",
+ "src/core/surface/call.c",
+ "src/core/surface/call_details.c",
+ "src/core/surface/call_log_batch.c",
+ "src/core/surface/channel.c",
+ "src/core/surface/channel_create.c",
+ "src/core/surface/client.c",
+ "src/core/surface/completion_queue.c",
+ "src/core/surface/event_string.c",
+ "src/core/surface/init.c",
+ "src/core/surface/lame_client.c",
+ "src/core/surface/metadata_array.c",
+ "src/core/surface/server.c",
+ "src/core/surface/server_chttp2.c",
+ "src/core/surface/server_create.c",
+ "src/core/surface/surface_trace.c",
+ "src/core/transport/chttp2/alpn.c",
+ "src/core/transport/chttp2/bin_encoder.c",
+ "src/core/transport/chttp2/frame_data.c",
+ "src/core/transport/chttp2/frame_goaway.c",
+ "src/core/transport/chttp2/frame_ping.c",
+ "src/core/transport/chttp2/frame_rst_stream.c",
+ "src/core/transport/chttp2/frame_settings.c",
+ "src/core/transport/chttp2/frame_window_update.c",
+ "src/core/transport/chttp2/hpack_parser.c",
+ "src/core/transport/chttp2/hpack_table.c",
+ "src/core/transport/chttp2/huffsyms.c",
+ "src/core/transport/chttp2/status_conversion.c",
+ "src/core/transport/chttp2/stream_encoder.c",
+ "src/core/transport/chttp2/stream_map.c",
+ "src/core/transport/chttp2/timeout_encoding.c",
+ "src/core/transport/chttp2/varint.c",
+ "src/core/transport/chttp2_transport.c",
+ "src/core/transport/metadata.c",
+ "src/core/transport/stream_op.c",
+ "src/core/transport/transport.c",
+ ],
+ hdrs = [
+ "include/grpc/byte_buffer.h",
+ "include/grpc/byte_buffer_reader.h",
+ "include/grpc/grpc.h",
+ "include/grpc/grpc_http.h",
+ "include/grpc/status.h",
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+ ":gpr",
+ ],
+)
+
+
+cc_library(
+ name = "grpc++",
+ srcs = [
+ "src/cpp/client/secure_credentials.h",
+ "src/cpp/server/secure_server_credentials.h",
+ "src/cpp/client/channel.h",
+ "src/cpp/proto/proto_utils.h",
+ "src/cpp/server/thread_pool.h",
+ "src/cpp/util/time.h",
+ "src/cpp/client/secure_credentials.cc",
+ "src/cpp/server/secure_server_credentials.cc",
+ "src/cpp/client/channel.cc",
+ "src/cpp/client/channel_arguments.cc",
+ "src/cpp/client/client_context.cc",
+ "src/cpp/client/client_unary_call.cc",
+ "src/cpp/client/create_channel.cc",
+ "src/cpp/client/credentials.cc",
+ "src/cpp/client/generic_stub.cc",
+ "src/cpp/client/insecure_credentials.cc",
+ "src/cpp/client/internal_stub.cc",
+ "src/cpp/common/call.cc",
+ "src/cpp/common/completion_queue.cc",
+ "src/cpp/common/rpc_method.cc",
+ "src/cpp/proto/proto_utils.cc",
+ "src/cpp/server/async_generic_service.cc",
+ "src/cpp/server/insecure_server_credentials.cc",
+ "src/cpp/server/server.cc",
+ "src/cpp/server/server_builder.cc",
+ "src/cpp/server/server_context.cc",
+ "src/cpp/server/server_credentials.cc",
+ "src/cpp/server/thread_pool.cc",
+ "src/cpp/util/byte_buffer.cc",
+ "src/cpp/util/slice.cc",
+ "src/cpp/util/status.cc",
+ "src/cpp/util/time.cc",
+ ],
+ hdrs = [
+ "include/grpc++/async_generic_service.h",
+ "include/grpc++/async_unary_call.h",
+ "include/grpc++/byte_buffer.h",
+ "include/grpc++/channel_arguments.h",
+ "include/grpc++/channel_interface.h",
+ "include/grpc++/client_context.h",
+ "include/grpc++/completion_queue.h",
+ "include/grpc++/config.h",
+ "include/grpc++/create_channel.h",
+ "include/grpc++/credentials.h",
+ "include/grpc++/generic_stub.h",
+ "include/grpc++/impl/call.h",
+ "include/grpc++/impl/client_unary_call.h",
+ "include/grpc++/impl/internal_stub.h",
+ "include/grpc++/impl/rpc_method.h",
+ "include/grpc++/impl/rpc_service_method.h",
+ "include/grpc++/impl/service_type.h",
+ "include/grpc++/server.h",
+ "include/grpc++/server_builder.h",
+ "include/grpc++/server_context.h",
+ "include/grpc++/server_credentials.h",
+ "include/grpc++/slice.h",
+ "include/grpc++/status.h",
+ "include/grpc++/status_code_enum.h",
+ "include/grpc++/stream.h",
+ "include/grpc++/thread_pool_interface.h",
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+ "//external:protobuf_clib",
+ ":gpr",
+ ":grpc",
+ ],
+)
+
+
+cc_library(
+ name = "grpc++_unsecure",
+ srcs = [
+ "src/cpp/client/channel.h",
+ "src/cpp/proto/proto_utils.h",
+ "src/cpp/server/thread_pool.h",
+ "src/cpp/util/time.h",
+ "src/cpp/client/channel.cc",
+ "src/cpp/client/channel_arguments.cc",
+ "src/cpp/client/client_context.cc",
+ "src/cpp/client/client_unary_call.cc",
+ "src/cpp/client/create_channel.cc",
+ "src/cpp/client/credentials.cc",
+ "src/cpp/client/generic_stub.cc",
+ "src/cpp/client/insecure_credentials.cc",
+ "src/cpp/client/internal_stub.cc",
+ "src/cpp/common/call.cc",
+ "src/cpp/common/completion_queue.cc",
+ "src/cpp/common/rpc_method.cc",
+ "src/cpp/proto/proto_utils.cc",
+ "src/cpp/server/async_generic_service.cc",
+ "src/cpp/server/insecure_server_credentials.cc",
+ "src/cpp/server/server.cc",
+ "src/cpp/server/server_builder.cc",
+ "src/cpp/server/server_context.cc",
+ "src/cpp/server/server_credentials.cc",
+ "src/cpp/server/thread_pool.cc",
+ "src/cpp/util/byte_buffer.cc",
+ "src/cpp/util/slice.cc",
+ "src/cpp/util/status.cc",
+ "src/cpp/util/time.cc",
+ ],
+ hdrs = [
+ "include/grpc++/async_generic_service.h",
+ "include/grpc++/async_unary_call.h",
+ "include/grpc++/byte_buffer.h",
+ "include/grpc++/channel_arguments.h",
+ "include/grpc++/channel_interface.h",
+ "include/grpc++/client_context.h",
+ "include/grpc++/completion_queue.h",
+ "include/grpc++/config.h",
+ "include/grpc++/create_channel.h",
+ "include/grpc++/credentials.h",
+ "include/grpc++/generic_stub.h",
+ "include/grpc++/impl/call.h",
+ "include/grpc++/impl/client_unary_call.h",
+ "include/grpc++/impl/internal_stub.h",
+ "include/grpc++/impl/rpc_method.h",
+ "include/grpc++/impl/rpc_service_method.h",
+ "include/grpc++/impl/service_type.h",
+ "include/grpc++/server.h",
+ "include/grpc++/server_builder.h",
+ "include/grpc++/server_context.h",
+ "include/grpc++/server_credentials.h",
+ "include/grpc++/slice.h",
+ "include/grpc++/status.h",
+ "include/grpc++/status_code_enum.h",
+ "include/grpc++/stream.h",
+ "include/grpc++/thread_pool_interface.h",
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+ "//external:protobuf_clib",
+ ":gpr",
+ ":grpc_unsecure",
+ ],
+)
+
+
+cc_library(
+ name = "grpc_plugin_support",
+ srcs = [
+ "src/compiler/config.h",
+ "src/compiler/cpp_generator.h",
+ "src/compiler/cpp_generator_helpers.h",
+ "src/compiler/generator_helpers.h",
+ "src/compiler/objective_c_generator.h",
+ "src/compiler/objective_c_generator_helpers.h",
+ "src/compiler/python_generator.h",
+ "src/compiler/ruby_generator.h",
+ "src/compiler/ruby_generator_helpers-inl.h",
+ "src/compiler/ruby_generator_map-inl.h",
+ "src/compiler/ruby_generator_string-inl.h",
+ "src/compiler/cpp_generator.cc",
+ "src/compiler/objective_c_generator.cc",
+ "src/compiler/python_generator.cc",
+ "src/compiler/ruby_generator.cc",
+ ],
+ hdrs = [
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+ "//external:protobuf_compiler",
+ ],
+)
+
+
+cc_library(
+ name = "grpc_csharp_ext",
+ srcs = [
+ "src/csharp/ext/grpc_csharp_ext.c",
+ ],
+ hdrs = [
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+ ":gpr",
+ ":grpc",
+ ],
+)
+
+
+
+cc_binary(
+ name = "grpc_cpp_plugin",
+ srcs = [
+ "src/compiler/cpp_plugin.cc",
+ ],
+ deps = [
+ "//external:protobuf_compiler",
+ ":grpc_plugin_support",
+ ],
+)
+
+
+cc_binary(
+ name = "grpc_objective_c_plugin",
+ srcs = [
+ "src/compiler/objective_c_plugin.cc",
+ ],
+ deps = [
+ "//external:protobuf_compiler",
+ ":grpc_plugin_support",
+ ],
+)
+
+
+cc_binary(
+ name = "grpc_python_plugin",
+ srcs = [
+ "src/compiler/python_plugin.cc",
+ ],
+ deps = [
+ "//external:protobuf_compiler",
+ ":grpc_plugin_support",
+ ],
+)
+
+
+cc_binary(
+ name = "grpc_ruby_plugin",
+ srcs = [
+ "src/compiler/ruby_plugin.cc",
+ ],
+ deps = [
+ "//external:protobuf_compiler",
+ ":grpc_plugin_support",
+ ],
+)
+
+
+
+
+
diff --git a/Makefile b/Makefile
index 857bde172e..4ba10c3c7b 100644
--- a/Makefile
+++ b/Makefile
@@ -94,6 +94,15 @@ CPPFLAGS_dbg = -O0
LDFLAGS_dbg =
DEFINES_dbg = _DEBUG DEBUG
+VALID_CONFIG_mutrace = 1
+CC_mutrace = $(DEFAULT_CC)
+CXX_mutrace = $(DEFAULT_CXX)
+LD_mutrace = $(DEFAULT_CC)
+LDXX_mutrace = $(DEFAULT_CXX)
+CPPFLAGS_mutrace = -O0
+LDFLAGS_mutrace = -rdynamic
+DEFINES_mutrace = _DEBUG DEBUG
+
VALID_CONFIG_valgrind = 1
REQUIRE_CUSTOM_LIBRARIES_valgrind = 1
CC_valgrind = $(DEFAULT_CC)
@@ -218,7 +227,6 @@ ifeq ($(HAS_CXX11),true)
CXXFLAGS += -std=c++11
else
CXXFLAGS += -std=c++0x
-DEFINES += GRPC_OLD_CXX
endif
CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter
LDFLAGS += -g
@@ -276,7 +284,7 @@ E = @echo
Q = @
endif
-VERSION = 0.5.0.0
+VERSION = 0.6.0.0
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -447,7 +455,7 @@ endif
.SECONDARY = %.pb.h %.pb.cc
-PROTOC_PLUGINS = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
+PROTOC_PLUGINS = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
ifeq ($(DEP_MISSING),)
all: static shared plugins
dep_error:
@@ -616,10 +624,14 @@ transport_metadata_test: $(BINDIR)/$(CONFIG)/transport_metadata_test
transport_security_test: $(BINDIR)/$(CONFIG)/transport_security_test
async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test
channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test
+cli_call_test: $(BINDIR)/$(CONFIG)/cli_call_test
credentials_test: $(BINDIR)/$(CONFIG)/credentials_test
+cxx_time_test: $(BINDIR)/$(CONFIG)/cxx_time_test
end2end_test: $(BINDIR)/$(CONFIG)/end2end_test
generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test
+grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli
grpc_cpp_plugin: $(BINDIR)/$(CONFIG)/grpc_cpp_plugin
+grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin
grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin
grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
interop_client: $(BINDIR)/$(CONFIG)/interop_client
@@ -629,6 +641,7 @@ pubsub_client: $(BINDIR)/$(CONFIG)/pubsub_client
pubsub_publisher_test: $(BINDIR)/$(CONFIG)/pubsub_publisher_test
pubsub_subscriber_test: $(BINDIR)/$(CONFIG)/pubsub_subscriber_test
qps_driver: $(BINDIR)/$(CONFIG)/qps_driver
+qps_smoke_test: $(BINDIR)/$(CONFIG)/qps_smoke_test
qps_worker: $(BINDIR)/$(CONFIG)/qps_worker
status_test: $(BINDIR)/$(CONFIG)/status_test
thread_pool_test: $(BINDIR)/$(CONFIG)/thread_pool_test
@@ -1069,7 +1082,7 @@ buildtests: buildtests_c buildtests_cxx
buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alarm_heap_test $(BINDIR)/$(CONFIG)/alarm_list_test $(BINDIR)/$(CONFIG)/alarm_test $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/census_hash_table_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test $(BINDIR)/$(CONFIG)/census_statistics_performance_test $(BINDIR)/$(CONFIG)/census_statistics_quick_test $(BINDIR)/$(CONFIG)/census_statistics_small_log_test $(BINDIR)/$(CONFIG)/census_stub_test $(BINDIR)/$(CONFIG)/census_window_stats_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_encoder_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/chttp2_transport_end2end_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/echo_client $(BINDIR)/$(CONFIG)/echo_server $(BINDIR)/$(CONFIG)/echo_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_cancellable_test $(BINDIR)/$(CONFIG)/gpr_cmdline_test $(BINDIR)/$(CONFIG)/gpr_env_test $(BINDIR)/$(CONFIG)/gpr_file_test $(BINDIR)/$(CONFIG)/gpr_histogram_test $(BINDIR)/$(CONFIG)/gpr_host_port_test $(BINDIR)/$(CONFIG)/gpr_log_test $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test $(BINDIR)/$(CONFIG)/gpr_slice_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_stream_op_test $(BINDIR)/$(CONFIG)/hpack_parser_test $(BINDIR)/$(CONFIG)/hpack_table_test $(BINDIR)/$(CONFIG)/httpcli_format_request_test $(BINDIR)/$(CONFIG)/httpcli_parser_test $(BINDIR)/$(CONFIG)/httpcli_test $(BINDIR)/$(CONFIG)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/metadata_buffer_test $(BINDIR)/$(CONFIG)/multi_init_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/poll_kick_posix_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_test $(BINDIR)/$(CONFIG)/sockaddr_utils_test $(BINDIR)/$(CONFIG)/tcp_client_posix_test $(BINDIR)/$(CONFIG)/tcp_posix_test $(BINDIR)/$(CONFIG)/tcp_server_posix_test $(BINDIR)/$(CONFIG)/time_averaged_stats_test $(BINDIR)/$(CONFIG)/time_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/transport_security_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_legacy_test
-buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/generic_end2end_test $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_driver $(BINDIR)/$(CONFIG)/qps_worker $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test
+buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/cli_call_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/cxx_time_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/generic_end2end_test $(BINDIR)/$(CONFIG)/grpc_cli $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_driver $(BINDIR)/$(CONFIG)/qps_smoke_test $(BINDIR)/$(CONFIG)/qps_worker $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test
test: test_c test_cxx
@@ -1901,8 +1914,12 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/async_end2end_test || ( echo test async_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing channel_arguments_test"
$(Q) $(BINDIR)/$(CONFIG)/channel_arguments_test || ( echo test channel_arguments_test failed ; exit 1 )
+ $(E) "[RUN] Testing cli_call_test"
+ $(Q) $(BINDIR)/$(CONFIG)/cli_call_test || ( echo test cli_call_test failed ; exit 1 )
$(E) "[RUN] Testing credentials_test"
$(Q) $(BINDIR)/$(CONFIG)/credentials_test || ( echo test credentials_test failed ; exit 1 )
+ $(E) "[RUN] Testing cxx_time_test"
+ $(Q) $(BINDIR)/$(CONFIG)/cxx_time_test || ( echo test cxx_time_test failed ; exit 1 )
$(E) "[RUN] Testing end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/end2end_test || ( echo test end2end_test failed ; exit 1 )
$(E) "[RUN] Testing generic_end2end_test"
@@ -1985,92 +2002,152 @@ endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/examples/pubsub/empty.pb.cc: protoc_dep_error
+$(GENDIR)/examples/pubsub/empty.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/examples/pubsub/empty.pb.cc: examples/pubsub/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
- $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+ $(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/examples/pubsub/empty.grpc.pb.cc: examples/pubsub/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+ $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/examples/pubsub/label.pb.cc: protoc_dep_error
+$(GENDIR)/examples/pubsub/label.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/examples/pubsub/label.pb.cc: examples/pubsub/label.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
- $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+ $(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/examples/pubsub/label.grpc.pb.cc: examples/pubsub/label.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+ $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/examples/pubsub/pubsub.pb.cc: protoc_dep_error
+$(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/examples/pubsub/pubsub.pb.cc: examples/pubsub/pubsub.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
- $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+ $(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc: examples/pubsub/pubsub.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+ $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/test/cpp/interop/empty.pb.cc: protoc_dep_error
+$(GENDIR)/test/cpp/interop/empty.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/test/cpp/interop/empty.pb.cc: test/cpp/interop/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
- $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+ $(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/cpp/interop/empty.grpc.pb.cc: test/cpp/interop/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+ $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/test/cpp/interop/messages.pb.cc: protoc_dep_error
+$(GENDIR)/test/cpp/interop/messages.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/test/cpp/interop/messages.pb.cc: test/cpp/interop/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
- $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+ $(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/cpp/interop/messages.grpc.pb.cc: test/cpp/interop/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+ $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/test/cpp/interop/test.pb.cc: protoc_dep_error
+$(GENDIR)/test/cpp/interop/test.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/test/cpp/interop/test.pb.cc: test/cpp/interop/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
- $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+ $(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/cpp/interop/test.grpc.pb.cc: test/cpp/interop/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+ $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/test/cpp/qps/qpstest.pb.cc: protoc_dep_error
+$(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/test/cpp/qps/qpstest.pb.cc: test/cpp/qps/qpstest.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
- $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+ $(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc: test/cpp/qps/qpstest.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+ $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/test/cpp/util/echo.pb.cc: protoc_dep_error
+$(GENDIR)/test/cpp/util/echo.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/test/cpp/util/echo.pb.cc: test/cpp/util/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
- $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+ $(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/cpp/util/echo.grpc.pb.cc: test/cpp/util/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+ $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/test/cpp/util/echo_duplicate.pb.cc: protoc_dep_error
+$(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/test/cpp/util/echo_duplicate.pb.cc: test/cpp/util/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
- $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+ $(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc: test/cpp/util/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+ $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif
ifeq ($(NO_PROTOC),true)
$(GENDIR)/test/cpp/util/messages.pb.cc: protoc_dep_error
+$(GENDIR)/test/cpp/util/messages.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/test/cpp/util/messages.pb.cc: test/cpp/util/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
- $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+ $(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/cpp/util/messages.grpc.pb.cc: test/cpp/util/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+ $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif
@@ -2147,10 +2224,11 @@ ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT) $(prefix)/lib/gpr.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr-imp.a $(prefix)/lib/libgpr-imp.a
else
-ifneq ($(SYSTEM),Darwin)
$(E) "[INSTALL] Installing libgpr.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.so.0
$(Q) ln -sf libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.so
endif
endif
@@ -2160,10 +2238,11 @@ ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(prefix)/lib/grpc.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc-imp.a $(prefix)/lib/libgrpc-imp.a
else
-ifneq ($(SYSTEM),Darwin)
$(E) "[INSTALL] Installing libgrpc.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.so.0
$(Q) ln -sf libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.so
endif
endif
@@ -2173,10 +2252,11 @@ ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT) $(prefix)/lib/grpc_unsecure.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure-imp.a $(prefix)/lib/libgrpc_unsecure-imp.a
else
-ifneq ($(SYSTEM),Darwin)
$(E) "[INSTALL] Installing libgrpc_unsecure.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.so.0
$(Q) ln -sf libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.so
endif
endif
@@ -2194,10 +2274,11 @@ ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT) $(prefix)/lib/grpc++.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++-imp.a $(prefix)/lib/libgrpc++-imp.a
else
-ifneq ($(SYSTEM),Darwin)
$(E) "[INSTALL] Installing libgrpc++.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.so.0
$(Q) ln -sf libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.so
endif
endif
@@ -2207,10 +2288,11 @@ ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/grpc++_unsecure.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure-imp.a $(prefix)/lib/libgrpc++_unsecure-imp.a
else
-ifneq ($(SYSTEM),Darwin)
$(E) "[INSTALL] Installing libgrpc++_unsecure.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.so.0
$(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.so
endif
endif
@@ -2228,10 +2310,11 @@ ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/grpc_csharp_ext.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext-imp.a $(prefix)/lib/libgrpc_csharp_ext-imp.a
else
-ifneq ($(SYSTEM),Darwin)
$(E) "[INSTALL] Installing libgrpc_csharp_ext.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.so.0
$(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.so
endif
endif
@@ -2250,6 +2333,8 @@ else
$(Q) $(INSTALL) -d $(prefix)/bin
$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(prefix)/bin/grpc_cpp_plugin
$(Q) $(INSTALL) -d $(prefix)/bin
+ $(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(prefix)/bin/grpc_objective_c_plugin
+ $(Q) $(INSTALL) -d $(prefix)/bin
$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_python_plugin $(prefix)/bin/grpc_python_plugin
$(Q) $(INSTALL) -d $(prefix)/bin
$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_ruby_plugin $(prefix)/bin/grpc_ruby_plugin
@@ -2292,6 +2377,7 @@ LIBGPR_SRC = \
src/core/support/alloc.c \
src/core/support/cancellable.c \
src/core/support/cmdline.c \
+ src/core/support/cpu_iphone.c \
src/core/support/cpu_linux.c \
src/core/support/cpu_posix.c \
src/core/support/cpu_windows.c \
@@ -2317,6 +2403,7 @@ LIBGPR_SRC = \
src/core/support/sync.c \
src/core/support/sync_posix.c \
src/core/support/sync_win32.c \
+ src/core/support/thd.c \
src/core/support/thd_posix.c \
src/core/support/thd_win32.c \
src/core/support/time.c \
@@ -2331,6 +2418,7 @@ PUBLIC_HEADERS_C += \
include/grpc/support/atm_win32.h \
include/grpc/support/cancellable_platform.h \
include/grpc/support/cmdline.h \
+ include/grpc/support/cpu.h \
include/grpc/support/histogram.h \
include/grpc/support/host_port.h \
include/grpc/support/log.h \
@@ -2369,7 +2457,7 @@ $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT): $(LIBGPR_OBJS) $(ZLIB_DEP)
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
ifeq ($(SYSTEM),Darwin)
- $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBGPR_OBJS) $(LDLIBS)
+ $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgpr.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBGPR_OBJS) $(LDLIBS)
else
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.0 -o $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBGPR_OBJS) $(LDLIBS)
$(Q) ln -sf libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgpr.so.0
@@ -2384,6 +2472,7 @@ endif
$(OBJDIR)/$(CONFIG)/src/core/support/alloc.o:
$(OBJDIR)/$(CONFIG)/src/core/support/cancellable.o:
$(OBJDIR)/$(CONFIG)/src/core/support/cmdline.o:
+$(OBJDIR)/$(CONFIG)/src/core/support/cpu_iphone.o:
$(OBJDIR)/$(CONFIG)/src/core/support/cpu_linux.o:
$(OBJDIR)/$(CONFIG)/src/core/support/cpu_posix.o:
$(OBJDIR)/$(CONFIG)/src/core/support/cpu_windows.o:
@@ -2409,6 +2498,7 @@ $(OBJDIR)/$(CONFIG)/src/core/support/string_win32.o:
$(OBJDIR)/$(CONFIG)/src/core/support/sync.o:
$(OBJDIR)/$(CONFIG)/src/core/support/sync_posix.o:
$(OBJDIR)/$(CONFIG)/src/core/support/sync_win32.o:
+$(OBJDIR)/$(CONFIG)/src/core/support/thd.o:
$(OBJDIR)/$(CONFIG)/src/core/support/thd_posix.o:
$(OBJDIR)/$(CONFIG)/src/core/support/thd_win32.o:
$(OBJDIR)/$(CONFIG)/src/core/support/time.o:
@@ -2547,6 +2637,7 @@ LIBGRPC_SRC = \
src/core/surface/byte_buffer_reader.c \
src/core/surface/call.c \
src/core/surface/call_details.c \
+ src/core/surface/call_log_batch.c \
src/core/surface/channel.c \
src/core/surface/channel_create.c \
src/core/surface/client.c \
@@ -2585,6 +2676,7 @@ PUBLIC_HEADERS_C += \
include/grpc/byte_buffer.h \
include/grpc/byte_buffer_reader.h \
include/grpc/grpc.h \
+ include/grpc/grpc_http.h \
include/grpc/status.h \
LIBGRPC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_SRC))))
@@ -2692,6 +2784,7 @@ src/core/surface/byte_buffer_queue.c: $(OPENSSL_DEP)
src/core/surface/byte_buffer_reader.c: $(OPENSSL_DEP)
src/core/surface/call.c: $(OPENSSL_DEP)
src/core/surface/call_details.c: $(OPENSSL_DEP)
+src/core/surface/call_log_batch.c: $(OPENSSL_DEP)
src/core/surface/channel.c: $(OPENSSL_DEP)
src/core/surface/channel_create.c: $(OPENSSL_DEP)
src/core/surface/client.c: $(OPENSSL_DEP)
@@ -2754,7 +2847,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT): $(LIBGRPC_OBJS) $(ZLIB_DEP) $(LIBDIR
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
ifeq ($(SYSTEM),Darwin)
- $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBGRPC_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr
+ $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBGRPC_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr
else
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBGRPC_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr
$(Q) ln -sf libgrpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.so.0
@@ -2854,6 +2947,7 @@ $(OBJDIR)/$(CONFIG)/src/core/surface/byte_buffer_queue.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/byte_buffer_reader.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/call.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/call_details.o:
+$(OBJDIR)/$(CONFIG)/src/core/surface/call_log_batch.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/channel.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/channel_create.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/client.o:
@@ -3029,6 +3123,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/surface/byte_buffer_reader.c \
src/core/surface/call.c \
src/core/surface/call_details.c \
+ src/core/surface/call_log_batch.c \
src/core/surface/channel.c \
src/core/surface/channel_create.c \
src/core/surface/client.c \
@@ -3066,6 +3161,7 @@ PUBLIC_HEADERS_C += \
include/grpc/byte_buffer.h \
include/grpc/byte_buffer_reader.h \
include/grpc/grpc.h \
+ include/grpc/grpc_http.h \
include/grpc/status.h \
LIBGRPC_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_UNSECURE_SRC))))
@@ -3091,7 +3187,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT): $(LIBGRPC_UNSECURE_OBJS) $(
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
ifeq ($(SYSTEM),Darwin)
- $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) -lgpr
+ $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc_unsecure.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) -lgpr
else
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) -lgpr
$(Q) ln -sf libgrpc_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.so.0
@@ -3167,6 +3263,7 @@ $(OBJDIR)/$(CONFIG)/src/core/surface/byte_buffer_queue.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/byte_buffer_reader.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/call.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/call_details.o:
+$(OBJDIR)/$(CONFIG)/src/core/surface/call_log_batch.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/channel.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/channel_create.o:
$(OBJDIR)/$(CONFIG)/src/core/surface/client.o:
@@ -3210,6 +3307,7 @@ LIBGRPC++_SRC = \
src/cpp/client/client_unary_call.cc \
src/cpp/client/create_channel.cc \
src/cpp/client/credentials.cc \
+ src/cpp/client/generic_stub.cc \
src/cpp/client/insecure_credentials.cc \
src/cpp/client/internal_stub.cc \
src/cpp/common/call.cc \
@@ -3239,12 +3337,19 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/config.h \
include/grpc++/create_channel.h \
include/grpc++/credentials.h \
+ include/grpc++/generic_stub.h \
include/grpc++/impl/call.h \
include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/internal_stub.h \
include/grpc++/impl/rpc_method.h \
include/grpc++/impl/rpc_service_method.h \
include/grpc++/impl/service_type.h \
+ include/grpc++/impl/sync.h \
+ include/grpc++/impl/sync_cxx11.h \
+ include/grpc++/impl/sync_no_cxx11.h \
+ include/grpc++/impl/thd.h \
+ include/grpc++/impl/thd_cxx11.h \
+ include/grpc++/impl/thd_no_cxx11.h \
include/grpc++/server.h \
include/grpc++/server_builder.h \
include/grpc++/server_context.h \
@@ -3297,6 +3402,7 @@ src/cpp/client/client_context.cc: $(OPENSSL_DEP)
src/cpp/client/client_unary_call.cc: $(OPENSSL_DEP)
src/cpp/client/create_channel.cc: $(OPENSSL_DEP)
src/cpp/client/credentials.cc: $(OPENSSL_DEP)
+src/cpp/client/generic_stub.cc: $(OPENSSL_DEP)
src/cpp/client/insecure_credentials.cc: $(OPENSSL_DEP)
src/cpp/client/internal_stub.cc: $(OPENSSL_DEP)
src/cpp/common/call.cc: $(OPENSSL_DEP)
@@ -3337,7 +3443,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT): $(LIBGRPC++_OBJS) $(ZLIB_DEP) $(LI
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
ifeq ($(SYSTEM),Darwin)
- $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc
+ $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc++.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc
$(Q) ln -sf libgrpc++.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++.so.0
@@ -3363,6 +3469,7 @@ $(OBJDIR)/$(CONFIG)/src/cpp/client/client_context.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/client_unary_call.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/create_channel.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/credentials.o:
+$(OBJDIR)/$(CONFIG)/src/cpp/client/generic_stub.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/insecure_credentials.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/internal_stub.o:
$(OBJDIR)/$(CONFIG)/src/cpp/common/call.o:
@@ -3383,9 +3490,10 @@ $(OBJDIR)/$(CONFIG)/src/cpp/util/time.o:
LIBGRPC++_TEST_UTIL_SRC = \
- $(GENDIR)/test/cpp/util/messages.pb.cc \
- $(GENDIR)/test/cpp/util/echo.pb.cc \
- $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc \
+ $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc \
+ $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc \
+ $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc \
+ test/cpp/util/cli_call.cc \
test/cpp/util/create_test_channel.cc \
@@ -3416,6 +3524,7 @@ ifneq ($(OPENSSL_DEP),)
test/cpp/util/messages.proto: $(OPENSSL_DEP)
test/cpp/util/echo.proto: $(OPENSSL_DEP)
test/cpp/util/echo_duplicate.proto: $(OPENSSL_DEP)
+test/cpp/util/cli_call.cc: $(OPENSSL_DEP)
test/cpp/util/create_test_channel.cc: $(OPENSSL_DEP)
endif
@@ -3444,7 +3553,8 @@ endif
-$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
LIBGRPC++_UNSECURE_SRC = \
@@ -3454,6 +3564,7 @@ LIBGRPC++_UNSECURE_SRC = \
src/cpp/client/client_unary_call.cc \
src/cpp/client/create_channel.cc \
src/cpp/client/credentials.cc \
+ src/cpp/client/generic_stub.cc \
src/cpp/client/insecure_credentials.cc \
src/cpp/client/internal_stub.cc \
src/cpp/common/call.cc \
@@ -3483,12 +3594,19 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/config.h \
include/grpc++/create_channel.h \
include/grpc++/credentials.h \
+ include/grpc++/generic_stub.h \
include/grpc++/impl/call.h \
include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/internal_stub.h \
include/grpc++/impl/rpc_method.h \
include/grpc++/impl/rpc_service_method.h \
include/grpc++/impl/service_type.h \
+ include/grpc++/impl/sync.h \
+ include/grpc++/impl/sync_cxx11.h \
+ include/grpc++/impl/sync_no_cxx11.h \
+ include/grpc++/impl/thd.h \
+ include/grpc++/impl/thd_cxx11.h \
+ include/grpc++/impl/thd_no_cxx11.h \
include/grpc++/server.h \
include/grpc++/server_builder.h \
include/grpc++/server_context.h \
@@ -3536,7 +3654,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS)
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
ifeq ($(SYSTEM),Darwin)
- $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
+ $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc++_unsecure.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
$(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.so.0
@@ -3556,6 +3674,7 @@ $(OBJDIR)/$(CONFIG)/src/cpp/client/client_context.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/client_unary_call.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/create_channel.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/credentials.o:
+$(OBJDIR)/$(CONFIG)/src/cpp/client/generic_stub.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/insecure_credentials.o:
$(OBJDIR)/$(CONFIG)/src/cpp/client/internal_stub.o:
$(OBJDIR)/$(CONFIG)/src/cpp/common/call.o:
@@ -3575,10 +3694,52 @@ $(OBJDIR)/$(CONFIG)/src/cpp/util/status.o:
$(OBJDIR)/$(CONFIG)/src/cpp/util/time.o:
+LIBGRPC_PLUGIN_SUPPORT_SRC = \
+ src/compiler/cpp_generator.cc \
+ src/compiler/objective_c_generator.cc \
+ src/compiler/python_generator.cc \
+ src/compiler/ruby_generator.cc \
+
+
+LIBGRPC_PLUGIN_SUPPORT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_PLUGIN_SUPPORT_SRC))))
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: protobuf_dep_error
+
+
+else
+
+$(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBGRPC_PLUGIN_SUPPORT_OBJS)
+ $(E) "[AR] Creating $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
+ $(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(LIBGRPC_PLUGIN_SUPPORT_OBJS)
+ifeq ($(SYSTEM),Darwin)
+ $(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
+endif
+
+
+
+
+endif
+
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC_PLUGIN_SUPPORT_OBJS:.o=.dep)
+endif
+
+$(OBJDIR)/$(CONFIG)/src/compiler/cpp_generator.o:
+$(OBJDIR)/$(CONFIG)/src/compiler/objective_c_generator.o:
+$(OBJDIR)/$(CONFIG)/src/compiler/python_generator.o:
+$(OBJDIR)/$(CONFIG)/src/compiler/ruby_generator.o:
+
+
LIBPUBSUB_CLIENT_LIB_SRC = \
- $(GENDIR)/examples/pubsub/label.pb.cc \
- $(GENDIR)/examples/pubsub/empty.pb.cc \
- $(GENDIR)/examples/pubsub/pubsub.pb.cc \
+ $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc \
+ $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc \
+ $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc \
examples/pubsub/publisher.cc \
examples/pubsub/subscriber.cc \
@@ -3639,13 +3800,14 @@ endif
-$(OBJDIR)/$(CONFIG)/examples/pubsub/publisher.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc
-$(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc
+$(OBJDIR)/$(CONFIG)/examples/pubsub/publisher.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc
LIBQPS_SRC = \
- $(GENDIR)/test/cpp/qps/qpstest.pb.cc \
+ $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc \
test/cpp/qps/driver.cc \
+ test/cpp/qps/report.cc \
test/cpp/qps/timer.cc \
@@ -3675,6 +3837,7 @@ ifneq ($(OPENSSL_DEP),)
# otherwise parallel compilation will fail if a source is compiled first.
test/cpp/qps/qpstest.proto: $(OPENSSL_DEP)
test/cpp/qps/driver.cc: $(OPENSSL_DEP)
+test/cpp/qps/report.cc: $(OPENSSL_DEP)
test/cpp/qps/timer.cc: $(OPENSSL_DEP)
endif
@@ -3701,8 +3864,9 @@ endif
endif
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
LIBGRPC_CSHARP_EXT_SRC = \
@@ -3754,7 +3918,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT): $(LIBGRPC_CSHARP_EXT_OBJS)
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
ifeq ($(SYSTEM),Darwin)
- $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc
+ $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc_csharp_ext.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc
else
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc
$(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.so.0
@@ -7971,6 +8135,48 @@ endif
endif
+CLI_CALL_TEST_SRC = \
+ test/cpp/util/cli_call_test.cc \
+
+CLI_CALL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CLI_CALL_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL with ALPN.
+
+$(BINDIR)/$(CONFIG)/cli_call_test: openssl_dep_error
+
+else
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/cli_call_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/cli_call_test: $(PROTOBUF_DEP) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(CLI_CALL_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/cli_call_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_cli_call_test: $(CLI_CALL_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CLI_CALL_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
CREDENTIALS_TEST_SRC = \
test/cpp/client/credentials_test.cc \
@@ -8013,6 +8219,48 @@ endif
endif
+CXX_TIME_TEST_SRC = \
+ test/cpp/util/time_test.cc \
+
+CXX_TIME_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CXX_TIME_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL with ALPN.
+
+$(BINDIR)/$(CONFIG)/cxx_time_test: openssl_dep_error
+
+else
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/cxx_time_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/cxx_time_test: $(PROTOBUF_DEP) $(CXX_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(CXX_TIME_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/cxx_time_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/util/time_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_cxx_time_test: $(CXX_TIME_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CXX_TIME_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
END2END_TEST_SRC = \
test/cpp/end2end/end2end_test.cc \
@@ -8097,8 +8345,49 @@ endif
endif
+GRPC_CLI_SRC = \
+ test/cpp/util/grpc_cli.cc \
+
+GRPC_CLI_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_CLI_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL with ALPN.
+
+$(BINDIR)/$(CONFIG)/grpc_cli: openssl_dep_error
+
+else
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/grpc_cli: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/grpc_cli: $(PROTOBUF_DEP) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(GRPC_CLI_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_cli
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_cli.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_grpc_cli: $(GRPC_CLI_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(GRPC_CLI_OBJS:.o=.dep)
+endif
+endif
+
+
GRPC_CPP_PLUGIN_SRC = \
- src/compiler/cpp_generator.cc \
src/compiler/cpp_plugin.cc \
GRPC_CPP_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_CPP_PLUGIN_SRC))))
@@ -8112,15 +8401,14 @@ $(BINDIR)/$(CONFIG)/grpc_cpp_plugin: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/grpc_cpp_plugin: $(PROTOBUF_DEP) $(GRPC_CPP_PLUGIN_OBJS)
+$(BINDIR)/$(CONFIG)/grpc_cpp_plugin: $(PROTOBUF_DEP) $(GRPC_CPP_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
$(E) "[HOSTLD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_CPP_PLUGIN_OBJS) $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_cpp_plugin
+ $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_CPP_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_cpp_plugin
endif
-$(OBJDIR)/$(CONFIG)/src/compiler/cpp_generator.o:
-$(OBJDIR)/$(CONFIG)/src/compiler/cpp_plugin.o:
+$(OBJDIR)/$(CONFIG)/src/compiler/cpp_plugin.o: $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
deps_grpc_cpp_plugin: $(GRPC_CPP_PLUGIN_OBJS:.o=.dep)
@@ -8129,8 +8417,37 @@ ifneq ($(NO_DEPS),true)
endif
+GRPC_OBJECTIVE_C_PLUGIN_SRC = \
+ src/compiler/objective_c_plugin.cc \
+
+GRPC_OBJECTIVE_C_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_OBJECTIVE_C_PLUGIN_SRC))))
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/grpc_objective_c_plugin: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/grpc_objective_c_plugin: $(PROTOBUF_DEP) $(GRPC_OBJECTIVE_C_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
+ $(E) "[HOSTLD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_OBJECTIVE_C_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin
+
+endif
+
+$(OBJDIR)/$(CONFIG)/src/compiler/objective_c_plugin.o: $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
+
+deps_grpc_objective_c_plugin: $(GRPC_OBJECTIVE_C_PLUGIN_OBJS:.o=.dep)
+
+ifneq ($(NO_DEPS),true)
+-include $(GRPC_OBJECTIVE_C_PLUGIN_OBJS:.o=.dep)
+endif
+
+
GRPC_PYTHON_PLUGIN_SRC = \
- src/compiler/python_generator.cc \
src/compiler/python_plugin.cc \
GRPC_PYTHON_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_PYTHON_PLUGIN_SRC))))
@@ -8144,15 +8461,14 @@ $(BINDIR)/$(CONFIG)/grpc_python_plugin: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/grpc_python_plugin: $(PROTOBUF_DEP) $(GRPC_PYTHON_PLUGIN_OBJS)
+$(BINDIR)/$(CONFIG)/grpc_python_plugin: $(PROTOBUF_DEP) $(GRPC_PYTHON_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
$(E) "[HOSTLD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_PYTHON_PLUGIN_OBJS) $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_python_plugin
+ $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_PYTHON_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_python_plugin
endif
-$(OBJDIR)/$(CONFIG)/src/compiler/python_generator.o:
-$(OBJDIR)/$(CONFIG)/src/compiler/python_plugin.o:
+$(OBJDIR)/$(CONFIG)/src/compiler/python_plugin.o: $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
deps_grpc_python_plugin: $(GRPC_PYTHON_PLUGIN_OBJS:.o=.dep)
@@ -8162,7 +8478,6 @@ endif
GRPC_RUBY_PLUGIN_SRC = \
- src/compiler/ruby_generator.cc \
src/compiler/ruby_plugin.cc \
GRPC_RUBY_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_RUBY_PLUGIN_SRC))))
@@ -8176,15 +8491,14 @@ $(BINDIR)/$(CONFIG)/grpc_ruby_plugin: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/grpc_ruby_plugin: $(PROTOBUF_DEP) $(GRPC_RUBY_PLUGIN_OBJS)
+$(BINDIR)/$(CONFIG)/grpc_ruby_plugin: $(PROTOBUF_DEP) $(GRPC_RUBY_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
$(E) "[HOSTLD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_RUBY_PLUGIN_OBJS) $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
+ $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_RUBY_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
endif
-$(OBJDIR)/$(CONFIG)/src/compiler/ruby_generator.o:
-$(OBJDIR)/$(CONFIG)/src/compiler/ruby_plugin.o:
+$(OBJDIR)/$(CONFIG)/src/compiler/ruby_plugin.o: $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
deps_grpc_ruby_plugin: $(GRPC_RUBY_PLUGIN_OBJS:.o=.dep)
@@ -8194,9 +8508,9 @@ endif
INTEROP_CLIENT_SRC = \
- $(GENDIR)/test/cpp/interop/empty.pb.cc \
- $(GENDIR)/test/cpp/interop/messages.pb.cc \
- $(GENDIR)/test/cpp/interop/test.pb.cc \
+ $(GENDIR)/test/cpp/interop/empty.pb.cc $(GENDIR)/test/cpp/interop/empty.grpc.pb.cc \
+ $(GENDIR)/test/cpp/interop/messages.pb.cc $(GENDIR)/test/cpp/interop/messages.grpc.pb.cc \
+ $(GENDIR)/test/cpp/interop/test.pb.cc $(GENDIR)/test/cpp/interop/test.grpc.pb.cc \
test/cpp/interop/client.cc \
INTEROP_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INTEROP_CLIENT_SRC))))
@@ -8242,9 +8556,9 @@ endif
INTEROP_SERVER_SRC = \
- $(GENDIR)/test/cpp/interop/empty.pb.cc \
- $(GENDIR)/test/cpp/interop/messages.pb.cc \
- $(GENDIR)/test/cpp/interop/test.pb.cc \
+ $(GENDIR)/test/cpp/interop/empty.pb.cc $(GENDIR)/test/cpp/interop/empty.grpc.pb.cc \
+ $(GENDIR)/test/cpp/interop/messages.pb.cc $(GENDIR)/test/cpp/interop/messages.grpc.pb.cc \
+ $(GENDIR)/test/cpp/interop/test.pb.cc $(GENDIR)/test/cpp/interop/test.grpc.pb.cc \
test/cpp/interop/server.cc \
INTEROP_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INTEROP_SERVER_SRC))))
@@ -8499,6 +8813,48 @@ endif
endif
+QPS_SMOKE_TEST_SRC = \
+ test/cpp/qps/smoke_test.cc \
+
+QPS_SMOKE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_SMOKE_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL with ALPN.
+
+$(BINDIR)/$(CONFIG)/qps_smoke_test: openssl_dep_error
+
+else
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/qps_smoke_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/qps_smoke_test: $(PROTOBUF_DEP) $(QPS_SMOKE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(QPS_SMOKE_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/qps_smoke_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/smoke_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_qps_smoke_test: $(QPS_SMOKE_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(QPS_SMOKE_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
QPS_WORKER_SRC = \
test/cpp/qps/client_async.cc \
test/cpp/qps/client_sync.cc \
diff --git a/README.md b/README.md
index fa60b83d16..b78745f02c 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,10 @@
Copyright 2015 Google Inc.
+#Documentation
+
+You can find more detailed documentation and examples in the [grpc-common repository](http://github.com/grpc/grpc-common).
+
#Installation
See grpc/INSTALL for installation instructions for various platforms.
@@ -25,10 +29,6 @@ of shared C core library [src/core] (src/core).
Java source code is in [grpc-java] (http://github.com/grpc/grpc-java) repository.
Go source code is in [grpc-go] (http://github.com/grpc/grpc-go) repository.
-#Documentation
-
-You can find more detailed documentation and examples in the [grpc-common repository](http://github.com/grpc/grpc-common).
-
#Current Status of libraries
Libraries in different languages are in different state of development. We are seeking contributions for all of these libraries.
diff --git a/build.json b/build.json
index 999e140c5a..0a7b81d5f5 100644
--- a/build.json
+++ b/build.json
@@ -3,7 +3,7 @@
"#": "The public version number of the library.",
"version": {
"major": 0,
- "minor": 5,
+ "minor": 6,
"micro": 0,
"build": 0
}
@@ -22,12 +22,19 @@
"include/grpc++/config.h",
"include/grpc++/create_channel.h",
"include/grpc++/credentials.h",
+ "include/grpc++/generic_stub.h",
"include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h",
"include/grpc++/impl/internal_stub.h",
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
"include/grpc++/impl/service_type.h",
+ "include/grpc++/impl/sync.h",
+ "include/grpc++/impl/sync_cxx11.h",
+ "include/grpc++/impl/sync_no_cxx11.h",
+ "include/grpc++/impl/thd.h",
+ "include/grpc++/impl/thd_cxx11.h",
+ "include/grpc++/impl/thd_no_cxx11.h",
"include/grpc++/server.h",
"include/grpc++/server_builder.h",
"include/grpc++/server_context.h",
@@ -51,6 +58,7 @@
"src/cpp/client/client_unary_call.cc",
"src/cpp/client/create_channel.cc",
"src/cpp/client/credentials.cc",
+ "src/cpp/client/generic_stub.cc",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/client/internal_stub.cc",
"src/cpp/common/call.cc",
@@ -76,6 +84,7 @@
"include/grpc/byte_buffer.h",
"include/grpc/byte_buffer_reader.h",
"include/grpc/grpc.h",
+ "include/grpc/grpc_http.h",
"include/grpc/status.h"
],
"headers": [
@@ -143,6 +152,7 @@
"src/core/surface/init.h",
"src/core/surface/server.h",
"src/core/surface/surface_trace.h",
+ "src/core/transport/chttp2/alpn.h",
"src/core/transport/chttp2/bin_encoder.h",
"src/core/transport/chttp2/frame.h",
"src/core/transport/chttp2/frame_data.h",
@@ -230,6 +240,7 @@
"src/core/surface/byte_buffer_reader.c",
"src/core/surface/call.c",
"src/core/surface/call_details.c",
+ "src/core/surface/call_log_batch.c",
"src/core/surface/channel.c",
"src/core/surface/channel_create.c",
"src/core/surface/client.c",
@@ -278,6 +289,7 @@
"include/grpc/support/atm_win32.h",
"include/grpc/support/cancellable_platform.h",
"include/grpc/support/cmdline.h",
+ "include/grpc/support/cpu.h",
"include/grpc/support/histogram.h",
"include/grpc/support/host_port.h",
"include/grpc/support/log.h",
@@ -305,6 +317,7 @@
"src/core/support/alloc.c",
"src/core/support/cancellable.c",
"src/core/support/cmdline.c",
+ "src/core/support/cpu_iphone.c",
"src/core/support/cpu_linux.c",
"src/core/support/cpu_posix.c",
"src/core/support/cpu_windows.c",
@@ -330,6 +343,7 @@
"src/core/support/sync.c",
"src/core/support/sync_posix.c",
"src/core/support/sync_win32.c",
+ "src/core/support/thd.c",
"src/core/support/thd_posix.c",
"src/core/support/thd_win32.c",
"src/core/support/time.c",
@@ -343,6 +357,9 @@
"name": "gpr_test_util",
"build": "private",
"language": "c",
+ "headers": [
+ "test/core/util/test_config.h"
+ ],
"src": [
"test/core/util/test_config.c"
],
@@ -367,6 +384,7 @@
"src/core/security/base64.h",
"src/core/security/credentials.h",
"src/core/security/json_token.h",
+ "src/core/security/secure_endpoint.h",
"src/core/security/secure_transport_setup.h",
"src/core/security/security_context.h",
"src/core/tsi/fake_transport_security.h",
@@ -426,6 +444,7 @@
],
"deps": [
"gpr",
+ "gpr_test_util",
"grpc"
],
"vs_project_guid": "{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}"
@@ -451,6 +470,10 @@
"name": "grpc++",
"build": "all",
"language": "c++",
+ "headers": [
+ "src/cpp/client/secure_credentials.h",
+ "src/cpp/server/secure_server_credentials.h"
+ ],
"src": [
"src/cpp/client/secure_credentials.cc",
"src/cpp/server/secure_server_credentials.cc"
@@ -474,6 +497,7 @@
"test/cpp/util/messages.proto",
"test/cpp/util/echo.proto",
"test/cpp/util/echo_duplicate.proto",
+ "test/cpp/util/cli_call.cc",
"test/cpp/util/create_test_channel.cc"
]
},
@@ -492,6 +516,32 @@
"secure": "no"
},
{
+ "name": "grpc_plugin_support",
+ "build": "protoc",
+ "language": "c++",
+ "headers": [
+ "src/compiler/config.h",
+ "src/compiler/cpp_generator.h",
+ "src/compiler/cpp_generator_helpers.h",
+ "src/compiler/generator_helpers.h",
+ "src/compiler/objective_c_generator.h",
+ "src/compiler/objective_c_generator_helpers.h",
+ "src/compiler/python_generator.h",
+ "src/compiler/ruby_generator.h",
+ "src/compiler/ruby_generator_helpers-inl.h",
+ "src/compiler/ruby_generator_map-inl.h",
+ "src/compiler/ruby_generator_string-inl.h"
+ ],
+ "src": [
+ "src/compiler/cpp_generator.cc",
+ "src/compiler/objective_c_generator.cc",
+ "src/compiler/python_generator.cc",
+ "src/compiler/ruby_generator.cc"
+ ],
+ "deps": [],
+ "secure": "no"
+ },
+ {
"name": "pubsub_client_lib",
"build": "private",
"language": "c++",
@@ -514,11 +564,13 @@
"language": "c++",
"headers": [
"test/cpp/qps/driver.h",
+ "test/cpp/qps/report.h",
"test/cpp/qps/timer.h"
],
"src": [
"test/cpp/qps/qpstest.proto",
"test/cpp/qps/driver.cc",
+ "test/cpp/qps/report.cc",
"test/cpp/qps/timer.cc"
]
},
@@ -1676,6 +1728,22 @@
]
},
{
+ "name": "cli_call_test",
+ "build": "test",
+ "language": "c++",
+ "src": [
+ "test/cpp/util/cli_call_test.cc"
+ ],
+ "deps": [
+ "grpc++_test_util",
+ "grpc_test_util",
+ "grpc++",
+ "grpc",
+ "gpr_test_util",
+ "gpr"
+ ]
+ },
+ {
"name": "credentials_test",
"build": "test",
"language": "c++",
@@ -1689,6 +1757,21 @@
]
},
{
+ "name": "cxx_time_test",
+ "build": "test",
+ "language": "c++",
+ "src": [
+ "test/cpp/util/time_test.cc"
+ ],
+ "deps": [
+ "grpc_test_util",
+ "grpc++",
+ "grpc",
+ "gpr_test_util",
+ "gpr"
+ ]
+ },
+ {
"name": "end2end_test",
"build": "test",
"language": "c++",
@@ -1721,32 +1804,56 @@
]
},
{
+ "name": "grpc_cli",
+ "build": "test",
+ "run": false,
+ "language": "c++",
+ "src": [
+ "test/cpp/util/grpc_cli.cc"
+ ],
+ "deps": [
+ "grpc++_test_util",
+ "grpc_test_util",
+ "grpc++",
+ "grpc",
+ "gpr_test_util",
+ "gpr"
+ ]
+ },
+ {
"name": "grpc_cpp_plugin",
"build": "protoc",
"language": "c++",
- "headers": [
- "src/compiler/cpp_generator.h",
- "src/compiler/cpp_generator_helpers.h"
- ],
"src": [
- "src/compiler/cpp_generator.cc",
"src/compiler/cpp_plugin.cc"
],
- "deps": [],
+ "deps": [
+ "grpc_plugin_support"
+ ],
"secure": "no"
},
{
- "name": "grpc_python_plugin",
+ "name": "grpc_objective_c_plugin",
"build": "protoc",
"language": "c++",
- "headers": [
- "src/compiler/python_generator.h"
+ "src": [
+ "src/compiler/objective_c_plugin.cc"
],
+ "deps": [
+ "grpc_plugin_support"
+ ],
+ "secure": "no"
+ },
+ {
+ "name": "grpc_python_plugin",
+ "build": "protoc",
+ "language": "c++",
"src": [
- "src/compiler/python_generator.cc",
"src/compiler/python_plugin.cc"
],
- "deps": [],
+ "deps": [
+ "grpc_plugin_support"
+ ],
"secure": "no"
},
{
@@ -1754,10 +1861,11 @@
"build": "protoc",
"language": "c++",
"src": [
- "src/compiler/ruby_generator.cc",
"src/compiler/ruby_plugin.cc"
],
- "deps": [],
+ "deps": [
+ "grpc_plugin_support"
+ ],
"secure": "no"
},
{
@@ -1884,6 +1992,24 @@
]
},
{
+ "name": "qps_smoke_test",
+ "build": "test",
+ "run": false,
+ "language": "c++",
+ "src": [
+ "test/cpp/qps/smoke_test.cc"
+ ],
+ "deps": [
+ "qps",
+ "grpc++_test_util",
+ "grpc_test_util",
+ "grpc++",
+ "grpc",
+ "gpr_test_util",
+ "gpr"
+ ]
+ },
+ {
"name": "qps_worker",
"build": "test",
"run": false,
diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md
new file mode 100644
index 0000000000..3f5ce37e1e
--- /dev/null
+++ b/doc/interop-test-descriptions.md
@@ -0,0 +1,685 @@
+Interoperability Test Case Descriptions
+=======================================
+
+Client and server use
+[test.proto](https://github.com/grpc/grpc/blob/master/test/cpp/interop/test.proto)
+and the [gRPC over HTTP/2 v2
+protocol](https://github.com/grpc/grpc-common/blob/master/PROTOCOL-HTTP2.md).
+
+Client
+------
+
+Clients implement test cases that test certain functionally. Each client is
+provided the test case it is expected to run as a command-line parameter. Names
+should be lowercase and without spaces.
+
+Clients should accept these arguments:
+* --server_host=HOSTNAME
+ * The server host to connect to. For example, "localhost" or "127.0.0.1"
+* --server_host_override=HOSTNAME
+ * The server host to claim to be connecting to, for use in TLS and HTTP/2
+ :authority header. If unspecified, the value of --server_host will be
+ used
+* --server_port=PORT
+ * The server port to connect to. For example, "8080"
+* --test_case=TESTCASE
+ * The name of the test case to execute. For example, "empty_unary"
+* --use_tls=BOOLEAN
+ * Whether to use a plaintext or encrypted connection
+* --use_test_ca=BOOLEAN
+ * Whether to replace platform root CAs with
+ [ca.pem](https://github.com/grpc/grpc/blob/master/src/core/tsi/test_creds/ca.pem)
+ as the CA root
+
+Clients must support TLS with ALPN. Clients must not disable certificate
+checking.
+
+### empty_unary
+
+This test verifies that implementations support zero-size messages. Ideally,
+client implementations would verify that the request and response were zero
+bytes serialized, but this is generally prohibitive to perform, so is not
+required.
+
+Server features:
+* [EmptyCall][]
+
+Procedure:
+ 1. Client calls EmptyCall with the default Empty message
+
+Asserts:
+* call was successful
+* response is non-null
+
+*It may be possible to use UnaryCall instead of EmptyCall, but it is harder to
+ensure that the proto serialized to zero bytes.*
+
+### large_unary
+
+This test verifies unary calls succeed in sending messages, and touches on flow
+control (even if compression is enabled on the channel).
+
+Server features:
+* [UnaryCall][]
+* [Compressable Payload][]
+
+Procedure:
+ 1. Client calls UnaryCall with:
+
+ ```
+ {
+ response_type: COMPRESSABLE
+ response_size: 314159
+ payload:{
+ body: 271828 bytes of zeros
+ }
+ }
+ ```
+
+Asserts:
+* call was successful
+* response payload type is COMPRESSABLE
+* response payload body is 314159 bytes in size
+* clients are free to assert that the response payload body contents are zero
+ and comparing the entire response message against a golden response
+
+### client_streaming
+
+This test verifies that client-only streaming succeeds.
+
+Server features:
+* [StreamingInputCall][]
+* [Compressable Payload][]
+
+Procedure:
+ 1. Client calls StreamingInputCall
+ 2. Client sends:
+
+ ```
+ {
+ payload:{
+ body: 27182 bytes of zeros
+ }
+ }
+ ```
+ 3. Client then sends:
+
+ ```
+ {
+ payload:{
+ body: 8 bytes of zeros
+ }
+ }
+ ```
+ 4. Client then sends:
+
+ ```
+ {
+ payload:{
+ body: 1828 bytes of zeros
+ }
+ }
+ ```
+ 5. Client then sends:
+
+ ```
+ {
+ payload:{
+ body: 45904 bytes of zeros
+ }
+ }
+ ```
+ 6. Client halfCloses
+
+Asserts:
+* call was successful
+* response aggregated_payload_size is 74922
+
+### server_streaming
+
+This test verifies that server-only streaming succeeds.
+
+Server features:
+* [StreamingOutputCall][]
+* [Compressable Payload][]
+
+Procedure:
+ 1. Client calls StreamingOutputCall with:
+
+ ```
+ {
+ response_type:COMPRESSABLE
+ response_parameters:{
+ size: 31415
+ }
+ response_parameters:{
+ size: 9
+ }
+ response_parameters:{
+ size: 2653
+ }
+ response_parameters:{
+ size: 58979
+ }
+ }
+ ```
+
+Asserts:
+* call was successful
+* exactly four responses
+* response payloads are COMPRESSABLE
+* response payload bodies are sized (in order): 31415, 9, 2653, 58979
+* clients are free to assert that the response payload body contents are zero
+ and comparing the entire response messages against golden responses
+
+### ping_pong
+
+This test verifies that full duplex bidi is supported.
+
+Server features:
+* [FullDuplexCall][]
+* [Compressable Payload][]
+
+Procedure:
+ 1. Client calls FullDuplexCall with:
+
+ ```
+ {
+ response_type: COMPRESSABLE
+ response_parameters:{
+ size: 31415
+ }
+ payload:{
+ body: 27182 bytes of zeros
+ }
+ }
+ ```
+ 2. After getting a reply, it sends:
+
+ ```
+ {
+ response_type: COMPRESSABLE
+ response_parameters:{
+ size: 9
+ }
+ payload:{
+ body: 8 bytes of zeros
+ }
+ }
+ ```
+ 3. After getting a reply, it sends:
+
+ ```
+ {
+ response_type: COMPRESSABLE
+ response_parameters:{
+ size: 2653
+ }
+ payload:{
+ body: 1828 bytes of zeros
+ }
+ }
+ ```
+ 4. After getting a reply, it sends:
+
+ ```
+ {
+ response_type: COMPRESSABLE
+ response_parameters:{
+ size: 58979
+ }
+ payload:{
+ body: 45904 bytes of zeros
+ }
+ }
+ ```
+
+Asserts:
+* call was successful
+* exactly four responses
+* response payloads are COMPRESSABLE
+* response payload bodies are sized (in order): 31415, 9, 2653, 58979
+* clients are free to assert that the response payload body contents are zero
+ and comparing the entire response messages against golden responses
+
+### empty_stream
+
+This test verifies that streams support having zero-messages in both
+directions.
+
+Server features:
+* [FullDuplexCall][]
+
+Procedure:
+ 1. Client calls FullDuplexCall and then half-closes
+
+Asserts:
+* call was successful
+* exactly zero responses
+
+### compute_engine_creds
+
+Status: Not yet implementable
+
+This test is only for cloud-to-prod path.
+
+This test verifies unary calls succeed in sending messages while using Service
+Credentials from GCE metadata server. The client instance needs to be created
+with desired oauth scope.
+
+Server features:
+* [UnaryCall][]
+* [Compressable Payload][]
+* SimpeResponse.username
+* SimpleResponse.oauth_scope
+
+Procedure:
+ 1. Client sets flags default_service_account with GCE service account name and
+ oauth_scope with the oauth scope to use.
+ 2. Client configures channel to use GCECredentials
+ 3. Client calls UnaryCall on the channel with:
+
+ ```
+ {
+ response_type: COMPRESSABLE
+ response_size: 314159
+ payload:{
+ body: 271828 bytes of zeros
+ }
+ fill_username: true
+ fill_oauth_scope: true
+ }
+ ```
+
+Asserts:
+* call was successful
+* received SimpleResponse.username equals FLAGS_default_service_account
+* received SimpleResponse.oauth_scope is in FLAGS_oauth_scope
+* response payload body is 314159 bytes in size
+* clients are free to assert that the response payload body contents are zero
+ and comparing the entire response message against a golden response
+
+### service_account_creds
+
+Status: Not yet implementable
+
+This test is only for cloud-to-prod path.
+
+This test verifies unary calls succeed in sending messages while using JWT
+signing keys (redeemed for OAuth2 access tokens by the auth implementation)
+
+Server features:
+* [UnaryCall][]
+* [Compressable Payload][]
+* SimpleResponse.username
+* SimpleResponse.oauth_scope
+
+Procedure:
+ 1. Client sets flags service_account_key_file with the path to json key file,
+ oauth_scope to the oauth scope.
+ 2. Client configures the channel to use ServiceAccountCredentials.
+ 3. Client calls UnaryCall with:
+
+ ```
+ {
+ response_type: COMPRESSABLE
+ response_size: 314159
+ payload:{
+ body: 271828 bytes of zeros
+ }
+ fill_username: true
+ fill_oauth_scope: true
+ }
+ ```
+
+Asserts:
+* call was successful
+* received SimpleResponse.username is in the json key file read from
+ FLAGS_service_account_key_file
+* received SimpleResponse.oauth_scope is in FLAGS_oauth_scope
+* response payload body is 314159 bytes in size
+* clients are free to assert that the response payload body contents are zero
+ and comparing the entire response message against a golden response
+
+### jwt_token_creds
+
+Status: Not yet implementable
+
+This test is only for cloud-to-prod path.
+
+This test verifies unary calls succeed in sending messages while using JWT
+token (created by the project's key file)
+
+Server features:
+* [UnaryCall][]
+* [Compressable Payload][]
+* SimpleResponse.username
+* SimpleResponse.oauth_scope
+
+Procedure:
+ 1. Client sets flags service_account_key_file with the path to json key file
+ 2. Client configures the channel to use JWTTokenCredentials.
+ 3. Client calls UnaryCall with:
+
+ ```
+ {
+ response_type: COMPRESSABLE
+ response_size: 314159
+ payload:{
+ body: 271828 bytes of zeros
+ }
+ fill_username: true
+ }
+ ```
+
+Asserts:
+* call was successful
+* received SimpleResponse.username is in the json key file read from
+ FLAGS_service_account_key_file
+* response payload body is 314159 bytes in size
+* clients are free to assert that the response payload body contents are zero
+ and comparing the entire response message against a golden response
+
+### Metadata (TODO: fix name)
+
+Status: Not yet implementable
+
+This test verifies that custom metadata in either binary or ascii format can be
+sent in header and trailer.
+
+Server features:
+* [UnaryCall][]
+* [Compressable Payload][]
+* Ability to receive custom metadata from client in header and send custom data
+ back to client in both header and trailer. (TODO: this is not defined)
+
+Procedure:
+ 1. While sending custom metadata (ascii + binary) in the header, client calls UnaryCall with:
+
+ ```
+ {
+ response_type: COMPRESSABLE
+ response_size: 314159
+ payload:{
+ body: 271828 bytes of zeros
+ }
+ }
+ ```
+
+Asserts:
+* call was successful
+* custom metadata is echoed back in the response header.
+* custom metadata is echoed back in the response trailer.
+
+### status_code_and_message
+
+Status: Not yet implementable
+
+This test verifies unary calls succeed in sending messages, and propagates back
+status code and message sent along with the messages.
+
+Server features:
+* [UnaryCall][]
+
+Procedure:
+ 1. Client calls UnaryCall with:
+
+ ```
+ {
+ response_status:{
+ code: 2
+ message: "test status message"
+ }
+ }
+ ```
+
+Asserts:
+* received status code is the same with sent code
+* received status message is the same with sent message
+
+### unimplemented_method
+
+Status: Not yet implementable
+
+This test verifies calling unimplemented RPC method returns unimplemented
+status.
+
+Procedure:
+* Client calls UnimplementedCall with:
+
+ ```
+ {
+ response_type: COMPRESSABLE
+ response_size: 314159
+ payload:{
+ body: 271828 bytes of zeros
+ }
+ }
+ ```
+
+Asserts:
+* received status code is 12 (UNIMPLEMENTED)
+* received status message is empty or null/unset
+
+### cancel_after_begin
+
+This test verifies that a request can be cancelled after metadata has been sent
+but before payloads are sent.
+
+Server features:
+* [StreamingInputCall][]
+
+Procedure:
+ 1. Client starts StreamingInputCall
+ 2. Client immediately cancels request
+
+Asserts:
+* Call completed with status CANCELLED
+
+### cancel_after_first_response
+
+This test verifies that a request can be cancelled after receiving a message
+from the server.
+
+Server features:
+* [FullDuplexCall][]
+* [Compressable Payload][]
+
+Procedure:
+ 1. Client starts FullDuplexCall with
+
+ ```
+ {
+ response_type: COMPRESSABLE
+ response_parameters:{
+ size: 31415
+ }
+ payload:{
+ body: 27182 bytes of zeros
+ }
+ }
+ ```
+ 2. After receiving a response, client cancels request
+
+Asserts:
+* Call completed with status CANCELLED
+
+### concurrent_large_unary
+
+Status: TODO
+
+Client performs 1000 large_unary tests in parallel on the same channel.
+
+### Flow control. Pushback at client for large messages (TODO: fix name)
+
+Status: TODO
+
+This test verifies that a client sending faster than a server can drain sees
+pushback (i.e., attempts to send succeed only after appropriate delays).
+
+### TODO Tests
+
+High priority:
+
+Propagation of status code and message (yangg)
+
+Cancel after sent headers (ctiller - done)
+
+Cancel after received first message (ctiller - done)
+
+Timeout after expire (zhaoq)
+
+Zero-message streams (ejona)
+
+Multiple thousand simultaneous calls on same Channel (ctiller - done)
+
+OAuth2 tokens + Service Credentials from GCE metadata server (GCE->prod only)
+(abhishek)
+
+OAuth2 tokens + JWT signing key (GCE->prod only) (abhishek)
+
+Metadata: client headers, server headers + trailers, binary+ascii (chenw)
+
+Normal priority:
+
+Cancel before start (ctiller)
+
+Cancel after sent first message (ctiller)
+
+Cancel after received headers (ctiller)
+
+Timeout but completed before expire (zhaoq)
+
+Multiple thousand simultaneous calls timeout on same Channel (ctiller)
+
+Lower priority:
+
+Flow control. Pushback at client for large messages (abhishek)
+
+Flow control. Pushback at server for large messages (abhishek)
+
+Going over max concurrent streams doesn't fail (client controls itself)
+(abhishek)
+
+RPC method not implemented (yangg)
+
+Multiple thousand simultaneous calls on different Channels (ctiller)
+
+Failed TLS hostname verification (ejona?)
+
+To priorize:
+
+Start streaming RPC but don't send any requests, server responds
+
+### Postponed Tests
+
+Resilience to buggy servers: These tests would verify that a client application
+isn't affected negatively by the responses put on the wire by a buggy server
+(e.g. the client library won't make the application crash).
+
+Reconnect after transport failure
+
+Reconnect backoff
+
+Fuzz testing
+
+
+Server
+------
+
+Servers implement various named features for clients to test with. Server
+features are orthogonal. If a server implements a feature, it is always
+available for clients. Names are simple descriptions for developer
+communication and tracking.
+
+Servers should accept these arguments:
+
+* --port=PORT
+
+ * The port to listen on. For example, "8080"
+
+* --use_tls=BOOLEAN
+
+ * Whether to use a plaintext or encrypted connection
+
+Servers must support TLS with ALPN. They should use
+[server1.pem](https://github.com/grpc/grpc/blob/master/src/core/tsi/test_creds/server1.pem)
+for their certificate.
+
+### EmptyCall
+[EmptyCall]: #emptycall
+
+Server implements EmptyCall which immediately returns the empty message.
+
+### UnaryCall
+[UnaryCall]: #unarycall
+
+Server implements UnaryCall which immediately returns a SimpleResponse with a
+payload body of size SimpleRequest.response_size bytes and type as appropriate
+for the SimpleRequest.response_type. If the server does not support the
+response_type, then it should fail the RPC with INVALID_ARGUMENT.
+
+If the request sets fill_username, the server should return the client username
+it sees in field SimpleResponse.username. If the request sets fill_oauth_scope,
+the server should return the oauth scope of the rpc in the form of "xapi_zoo"
+in field SimpleResponse.oauth_scope.
+
+### StreamingInputCall
+[StreamingInputCall]: #streaminginputcall
+
+Server implements StreamingInputCall which upon half close immediately returns
+a StreamingInputCallResponse where aggregated_payload_size is the sum of all
+request payload bodies received.
+
+### StreamingOutputCall
+[StreamingOutputCall]: #streamingoutputcall
+
+Server implements StreamingOutputCall by replying, in order, with one
+StreamingOutputCallResponses for each ResponseParameters in
+StreamingOutputCallRequest. Each StreamingOutputCallResponses should have a
+payload body of size ResponseParameters.size bytes, as specified by its
+respective ResponseParameters. After sending all responses, it closes with OK.
+
+### FullDuplexCall
+[FullDuplexCall]: #fullduplexcall
+
+Server implements FullDuplexCall by replying, in order, with one
+StreamingOutputCallResponses for each ResponseParameters in each
+StreamingOutputCallRequest. Each StreamingOutputCallResponses should have a
+payload body of size ResponseParameters.size bytes, as specified by its
+respective ResponseParameters. After receiving half close and sending all
+responses, it closes with OK.
+
+### Compressable Payload
+[Compressable Payload]: #compressable-payload
+
+When the client requests COMPRESSABLE payload, the response includes a payload
+of the size requested containing all zeros and the payload type is
+COMPRESSABLE.
+
+### Observe ResponseParameters.interval_us
+[Observe ResponseParameters.interval_us]: #observe-responseparametersinterval_us
+
+In StreamingOutputCall and FullDuplexCall, server delays sending a
+StreamingOutputCallResponse by the ResponseParameters's interval_us for that
+particular response, relative to the last response sent. That is, interval_us
+acts like a sleep *before* sending the response and accumulates from one
+response to the next.
+
+Interaction with flow control is unspecified.
+
+### Echo Auth Information
+
+Status: Pending
+
+If a SimpleRequest has fill_username=true and that request was successfully
+authenticated, then the SimpleResponse should have username filled with the
+canonical form of the authenticated source. The canonical form is dependent on
+the authentication method, but is likely to be a base 10 integer identifier or
+an email address.
+
+Discussion:
+
+Ideally, this would be communicated via metadata and not in the
+request/response, but we want to use this test in code paths that don't yet
+fully communicate metadata.
diff --git a/examples/pubsub/main.cc b/examples/pubsub/main.cc
index 6f7737e247..cc5076f0a5 100644
--- a/examples/pubsub/main.cc
+++ b/examples/pubsub/main.cc
@@ -51,14 +51,14 @@
#include "examples/pubsub/subscriber.h"
DEFINE_int32(server_port, 443, "Server port.");
-DEFINE_string(server_host,
- "pubsub-staging.googleapis.com", "Server host to connect to");
+DEFINE_string(server_host, "pubsub-staging.googleapis.com",
+ "Server host to connect to");
DEFINE_string(project_id, "", "GCE project id such as stoked-keyword-656");
// In some distros, gflags is in the namespace google, and in some others,
// in gflags. This hack is enabling us to find both.
-namespace google { }
-namespace gflags { }
+namespace google {}
+namespace gflags {}
using namespace google;
using namespace gflags;
@@ -92,32 +92,32 @@ int main(int argc, char** argv) {
grpc::string topic = ss.str();
ss.str("");
- ss << FLAGS_project_id << "/" << kSubscriptionName;
+ ss << FLAGS_project_id << "/" << kSubscriptionName;
grpc::string subscription_name = ss.str();
// Clean up test topic and subcription if they exist before.
grpc::string subscription_topic;
- if (subscriber.GetSubscription(
- subscription_name, &subscription_topic).IsOk()) {
+ if (subscriber.GetSubscription(subscription_name, &subscription_topic)
+ .IsOk()) {
subscriber.DeleteSubscription(subscription_name);
}
if (publisher.GetTopic(topic).IsOk()) publisher.DeleteTopic(topic);
grpc::Status s = publisher.CreateTopic(topic);
- gpr_log(GPR_INFO, "Create topic returns code %d, %s",
- s.code(), s.details().c_str());
+ gpr_log(GPR_INFO, "Create topic returns code %d, %s", s.code(),
+ s.details().c_str());
GPR_ASSERT(s.IsOk());
s = publisher.GetTopic(topic);
- gpr_log(GPR_INFO, "Get topic returns code %d, %s",
- s.code(), s.details().c_str());
+ gpr_log(GPR_INFO, "Get topic returns code %d, %s", s.code(),
+ s.details().c_str());
GPR_ASSERT(s.IsOk());
std::vector<grpc::string> topics;
s = publisher.ListTopics(FLAGS_project_id, &topics);
- gpr_log(GPR_INFO, "List topic returns code %d, %s",
- s.code(), s.details().c_str());
+ gpr_log(GPR_INFO, "List topic returns code %d, %s", s.code(),
+ s.details().c_str());
bool topic_found = false;
for (unsigned int i = 0; i < topics.size(); i++) {
if (topics[i] == topic) topic_found = true;
@@ -127,27 +127,27 @@ int main(int argc, char** argv) {
GPR_ASSERT(topic_found);
s = subscriber.CreateSubscription(topic, subscription_name);
- gpr_log(GPR_INFO, "create subscrption returns code %d, %s",
- s.code(), s.details().c_str());
+ gpr_log(GPR_INFO, "create subscrption returns code %d, %s", s.code(),
+ s.details().c_str());
GPR_ASSERT(s.IsOk());
s = publisher.Publish(topic, kMessageData);
- gpr_log(GPR_INFO, "Publish %s returns code %d, %s",
- kMessageData, s.code(), s.details().c_str());
+ gpr_log(GPR_INFO, "Publish %s returns code %d, %s", kMessageData, s.code(),
+ s.details().c_str());
GPR_ASSERT(s.IsOk());
grpc::string data;
s = subscriber.Pull(subscription_name, &data);
gpr_log(GPR_INFO, "Pull %s", data.c_str());
- s = subscriber.DeleteSubscription(subscription_name);
- gpr_log(GPR_INFO, "Delete subscription returns code %d, %s",
- s.code(), s.details().c_str());
+ s = subscriber.DeleteSubscription(subscription_name);
+ gpr_log(GPR_INFO, "Delete subscription returns code %d, %s", s.code(),
+ s.details().c_str());
GPR_ASSERT(s.IsOk());
s = publisher.DeleteTopic(topic);
- gpr_log(GPR_INFO, "Delete topic returns code %d, %s",
- s.code(), s.details().c_str());
+ gpr_log(GPR_INFO, "Delete topic returns code %d, %s", s.code(),
+ s.details().c_str());
GPR_ASSERT(s.IsOk());
subscriber.Shutdown();
diff --git a/examples/pubsub/publisher.cc b/examples/pubsub/publisher.cc
index 308f9a77e5..458050af73 100644
--- a/examples/pubsub/publisher.cc
+++ b/examples/pubsub/publisher.cc
@@ -51,12 +51,9 @@ namespace examples {
namespace pubsub {
Publisher::Publisher(std::shared_ptr<ChannelInterface> channel)
- : stub_(PublisherService::NewStub(channel)) {
-}
+ : stub_(PublisherService::NewStub(channel)) {}
-void Publisher::Shutdown() {
- stub_.reset();
-}
+void Publisher::Shutdown() { stub_.reset(); }
Status Publisher::CreateTopic(const grpc::string& topic) {
Topic request;
diff --git a/examples/pubsub/publisher.h b/examples/pubsub/publisher.h
index c90406ffef..33bcf98df4 100644
--- a/examples/pubsub/publisher.h
+++ b/examples/pubsub/publisher.h
@@ -37,7 +37,7 @@
#include <grpc++/channel_interface.h>
#include <grpc++/status.h>
-#include "examples/pubsub/pubsub.pb.h"
+#include "examples/pubsub/pubsub.grpc.pb.h"
namespace grpc {
namespace examples {
diff --git a/examples/pubsub/publisher_test.cc b/examples/pubsub/publisher_test.cc
index 62442c7384..ac4921283f 100644
--- a/examples/pubsub/publisher_test.cc
+++ b/examples/pubsub/publisher_test.cc
@@ -31,8 +31,6 @@
*
*/
-#include <google/protobuf/stubs/common.h>
-
#include <grpc++/channel_arguments.h>
#include <grpc++/channel_interface.h>
#include <grpc++/client_context.h>
@@ -84,20 +82,19 @@ class PublisherServiceImpl : public tech::pubsub::PublisherService::Service {
Status ListTopics(
ServerContext* context, const ::tech::pubsub::ListTopicsRequest* request,
::tech::pubsub::ListTopicsResponse* response) GRPC_OVERRIDE {
- std::ostringstream ss;
- ss << "cloud.googleapis.com/project in (/projects/" << kProjectId << ")";
- EXPECT_EQ(request->query(), ss.str());
- response->add_topic()->set_name(kTopic);
- return Status::OK;
- }
-
- Status DeleteTopic(ServerContext* context,
- const ::tech::pubsub::DeleteTopicRequest* request,
- ::proto2::Empty* response) GRPC_OVERRIDE {
- EXPECT_EQ(request->topic(), kTopic);
+ std::ostringstream ss;
+ ss << "cloud.googleapis.com/project in (/projects/" << kProjectId << ")";
+ EXPECT_EQ(request->query(), ss.str());
+ response->add_topic()->set_name(kTopic);
return Status::OK;
- }
+ }
+ Status DeleteTopic(ServerContext* context,
+ const ::tech::pubsub::DeleteTopicRequest* request,
+ ::proto2::Empty* response) GRPC_OVERRIDE {
+ EXPECT_EQ(request->topic(), kTopic);
+ return Status::OK;
+ }
};
class PublisherTest : public ::testing::Test {
@@ -107,11 +104,13 @@ class PublisherTest : public ::testing::Test {
int port = grpc_pick_unused_port_or_die();
server_address_ << "localhost:" << port;
ServerBuilder builder;
- builder.AddListeningPort(server_address_.str(), grpc::InsecureServerCredentials());
+ builder.AddListeningPort(server_address_.str(),
+ grpc::InsecureServerCredentials());
builder.RegisterService(&service_);
server_ = builder.BuildAndStart();
- channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(), ChannelArguments());
+ channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(),
+ ChannelArguments());
publisher_.reset(new grpc::examples::pubsub::Publisher(channel_));
}
diff --git a/examples/pubsub/subscriber.cc b/examples/pubsub/subscriber.cc
index 29f6635b7c..d9e0292ba0 100644
--- a/examples/pubsub/subscriber.cc
+++ b/examples/pubsub/subscriber.cc
@@ -49,12 +49,9 @@ namespace examples {
namespace pubsub {
Subscriber::Subscriber(std::shared_ptr<ChannelInterface> channel)
- : stub_(SubscriberService::NewStub(channel)) {
-}
+ : stub_(SubscriberService::NewStub(channel)) {}
-void Subscriber::Shutdown() {
- stub_.reset();
-}
+void Subscriber::Shutdown() { stub_.reset(); }
Status Subscriber::CreateSubscription(const grpc::string& topic,
const grpc::string& name) {
diff --git a/examples/pubsub/subscriber.h b/examples/pubsub/subscriber.h
index c587c01b82..40ab45471d 100644
--- a/examples/pubsub/subscriber.h
+++ b/examples/pubsub/subscriber.h
@@ -37,7 +37,7 @@
#include <grpc++/channel_interface.h>
#include <grpc++/status.h>
-#include "examples/pubsub/pubsub.pb.h"
+#include "examples/pubsub/pubsub.grpc.pb.h"
namespace grpc {
namespace examples {
diff --git a/examples/pubsub/subscriber_test.cc b/examples/pubsub/subscriber_test.cc
index b8dd1f9486..9ab60ed6a7 100644
--- a/examples/pubsub/subscriber_test.cc
+++ b/examples/pubsub/subscriber_test.cc
@@ -31,8 +31,6 @@
*
*/
-#include <google/protobuf/stubs/common.h>
-
#include <grpc++/channel_arguments.h>
#include <grpc++/channel_interface.h>
#include <grpc++/client_context.h>
@@ -95,7 +93,6 @@ class SubscriberServiceImpl : public tech::pubsub::SubscriberService::Service {
proto2::Empty* response) GRPC_OVERRIDE {
return Status::OK;
}
-
};
class SubscriberTest : public ::testing::Test {
@@ -105,11 +102,13 @@ class SubscriberTest : public ::testing::Test {
int port = grpc_pick_unused_port_or_die();
server_address_ << "localhost:" << port;
ServerBuilder builder;
- builder.AddListeningPort(server_address_.str(), grpc::InsecureServerCredentials());
+ builder.AddListeningPort(server_address_.str(),
+ grpc::InsecureServerCredentials());
builder.RegisterService(&service_);
server_ = builder.BuildAndStart();
- channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(), ChannelArguments());
+ channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(),
+ ChannelArguments());
subscriber_.reset(new grpc::examples::pubsub::Subscriber(channel_));
}
@@ -129,17 +128,15 @@ class SubscriberTest : public ::testing::Test {
};
TEST_F(SubscriberTest, TestSubscriber) {
- EXPECT_TRUE(subscriber_->CreateSubscription(kTopic,
- kSubscriptionName).IsOk());
+ EXPECT_TRUE(
+ subscriber_->CreateSubscription(kTopic, kSubscriptionName).IsOk());
grpc::string topic;
- EXPECT_TRUE(subscriber_->GetSubscription(kSubscriptionName,
- &topic).IsOk());
+ EXPECT_TRUE(subscriber_->GetSubscription(kSubscriptionName, &topic).IsOk());
EXPECT_EQ(topic, kTopic);
grpc::string data;
- EXPECT_TRUE(subscriber_->Pull(kSubscriptionName,
- &data).IsOk());
+ EXPECT_TRUE(subscriber_->Pull(kSubscriptionName, &data).IsOk());
EXPECT_TRUE(subscriber_->DeleteSubscription(kSubscriptionName).IsOk());
}
diff --git a/include/grpc++/completion_queue.h b/include/grpc++/completion_queue.h
index f4619a1060..e6a8c6fe55 100644
--- a/include/grpc++/completion_queue.h
+++ b/include/grpc++/completion_queue.h
@@ -36,6 +36,7 @@
#include <chrono>
#include <grpc++/impl/client_unary_call.h>
+#include <grpc/support/time.h>
struct grpc_completion_queue;
@@ -88,9 +89,7 @@ class CompletionQueue {
// Returns false if the queue is ready for destruction, true if event
bool Next(void** tag, bool* ok) {
- return (
- AsyncNext(tag, ok, (std::chrono::system_clock::time_point::max)()) !=
- SHUTDOWN);
+ return (AsyncNextInternal(tag, ok, gpr_inf_future) != SHUTDOWN);
}
// Shutdown has to be called, and the CompletionQueue can only be
@@ -122,6 +121,8 @@ class CompletionQueue {
const grpc::protobuf::Message& request,
grpc::protobuf::Message* result);
+ NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline);
+
// Wraps grpc_completion_queue_pluck.
// Cannot be mixed with calls to Next().
bool Pluck(CompletionQueueTag* tag);
diff --git a/include/grpc++/config.h b/include/grpc++/config.h
index 35bf507364..0f3d69289f 100644
--- a/include/grpc++/config.h
+++ b/include/grpc++/config.h
@@ -34,11 +34,46 @@
#ifndef GRPCXX_CONFIG_H
#define GRPCXX_CONFIG_H
-#ifdef GRPC_OLD_CXX
+#if !defined(GRPC_NO_AUTODETECT_PLATFORM)
+
+#ifdef _MSC_VER
+// Visual Studio 2010 is 1600.
+#if _MSC_VER < 1600
+#error "gRPC is only supported with Visual Studio starting at 2010"
+// Visual Studio 2013 is 1800.
+#elif _MSC_VER < 1800
+#define GRPC_CXX0X_NO_FINAL 1
+#define GRPC_CXX0X_NO_OVERRIDE 1
+#define GRPC_CXX0X_NO_CHRONO 1
+#define GRPC_CXX0X_NO_THREAD 1
+#endif
+#endif // Visual Studio
+
+#ifndef __clang__
+#ifdef __GNUC__
+// nullptr was added in gcc 4.6
+#if (__GNUC__ * 100 + __GNUC_MINOR__ < 406)
+#define GRPC_CXX0X_NO_NULLPTR 1
+#endif
+// final and override were added in gcc 4.7
+#if (__GNUC__ * 100 + __GNUC_MINOR__ < 407)
+#define GRPC_CXX0X_NO_FINAL 1
+#define GRPC_CXX0X_NO_OVERRIDE 1
+#endif
+#endif
+#endif
+
+#endif
+
+#ifdef GRPC_CXX0X_NO_FINAL
#define GRPC_FINAL
-#define GRPC_OVERRIDE
#else
#define GRPC_FINAL final
+#endif
+
+#ifdef GRPC_CXX0X_NO_OVERRIDE
+#define GRPC_OVERRIDE
+#else
#define GRPC_OVERRIDE override
#endif
@@ -65,6 +100,20 @@
::google::protobuf::io::ZeroCopyInputStream
#endif
+#ifdef GRPC_CXX0X_NO_NULLPTR
+#include <memory>
+const class {
+public:
+ template <class T> operator T*() const {return static_cast<T *>(0);}
+ template <class T> operator std::unique_ptr<T>() const {
+ return std::unique_ptr<T>(static_cast<T *>(0));
+ }
+ operator bool() const {return false;}
+private:
+ void operator&() const = delete;
+} nullptr = {};
+#endif
+
namespace grpc {
typedef GRPC_CUSTOM_STRING string;
diff --git a/include/grpc++/generic_stub.h b/include/grpc++/generic_stub.h
index d4c8380ad4..c34e1fcf55 100644
--- a/include/grpc++/generic_stub.h
+++ b/include/grpc++/generic_stub.h
@@ -39,6 +39,7 @@
namespace grpc {
+class CompletionQueue;
typedef ClientAsyncReaderWriter<ByteBuffer, ByteBuffer>
GenericClientAsyncReaderWriter;
@@ -51,7 +52,8 @@ class GenericStub GRPC_FINAL {
// begin a call to a named method
std::unique_ptr<GenericClientAsyncReaderWriter> Call(
- ClientContext* context, const grpc::string& method);
+ ClientContext* context, const grpc::string& method,
+ CompletionQueue* cq, void* tag);
private:
std::shared_ptr<ChannelInterface> channel_;
diff --git a/include/grpc++/impl/call.h b/include/grpc++/impl/call.h
index e117ac6313..b14c41dfa6 100644
--- a/include/grpc++/impl/call.h
+++ b/include/grpc++/impl/call.h
@@ -109,7 +109,9 @@ class CallOpBuffer : public CompletionQueueTag {
char* status_details_;
size_t status_details_capacity_;
// Server send status
- const Status* send_status_;
+ bool send_status_available_;
+ grpc_status_code send_status_code_;
+ grpc::string send_status_details_;
size_t trailing_metadata_count_;
grpc_metadata* trailing_metadata_;
int cancelled_buf_;
diff --git a/src/php/ext/grpc/event.h b/include/grpc++/impl/sync.h
index ef5846aee1..2f41d2bdeb 100755..100644
--- a/src/php/ext/grpc/event.h
+++ b/include/grpc++/impl/sync.h
@@ -31,21 +31,15 @@
*
*/
-#ifndef NET_GRPC_PHP_GRPC_EVENT_H_
-#define NET_GRPC_PHP_GRPC_EVENT_H_
+#ifndef GRPCXX_IMPL_SYNC_H
+#define GRPCXX_IMPL_SYNC_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "php_grpc.h"
+#include <grpc++/config.h>
-#include "grpc/grpc.h"
-
-/* Create a new Event object that wraps an existing grpc_event struct */
-zval *grpc_php_convert_event(grpc_event *event);
+#ifdef GRPC_CXX0X_NO_THREAD
+#include <grpc++/impl/sync_no_cxx11.h>
+#else
+#include <grpc++/impl/sync_cxx11.h>
+#endif
-#endif /* NET_GRPC_PHP_GRPC_COMPLETION_CHANNEL_H */
+#endif // GRPCXX_IMPL_SYNC_H
diff --git a/src/php/lib/autoload.php b/include/grpc++/impl/sync_cxx11.h
index 42eb33d65b..4e6f1da3a6 100755..100644
--- a/src/php/lib/autoload.php
+++ b/include/grpc++/impl/sync_cxx11.h
@@ -1,4 +1,3 @@
-<?php
/*
*
* Copyright 2015, Google Inc.
@@ -31,23 +30,20 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-function grpcAutoloader($class) {
- $prefix = 'Grpc\\';
- $base_dir = __DIR__ . '/Grpc/';
+#ifndef GRPCXX_IMPL_SYNC_CXX11_H
+#define GRPCXX_IMPL_SYNC_CXX11_H
- $len = strlen($prefix);
- if (strncmp($prefix, $class, $len) !== 0) {
- return;
- }
+#include <condition_variable>
+#include <mutex>
- $relative_class = substr($class, $len);
+namespace grpc {
- $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
+using std::condition_variable;
+using std::mutex;
+using std::lock_guard;
+using std::unique_lock;
- if (file_exists($file)) {
- include $file;
- }
-}
+} // namespace grpc
-spl_autoload_register('grpcAutoloader');
+#endif // GRPCXX_IMPL_SYNC_CXX11_H
diff --git a/include/grpc++/impl/sync_no_cxx11.h b/include/grpc++/impl/sync_no_cxx11.h
new file mode 100644
index 0000000000..5636373b81
--- /dev/null
+++ b/include/grpc++/impl/sync_no_cxx11.h
@@ -0,0 +1,101 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_SYNC_NO_CXX11_H
+#define GRPCXX_IMPL_SYNC_NO_CXX11_H
+
+#include <grpc/support/sync.h>
+
+namespace grpc {
+
+template<class mutex>
+class lock_guard;
+class condition_variable;
+
+class mutex {
+ public:
+ mutex() { gpr_mu_init(&mu_); }
+ ~mutex() { gpr_mu_destroy(&mu_); }
+ private:
+ ::gpr_mu mu_;
+ template <class mutex>
+ friend class lock_guard;
+ friend class condition_variable;
+};
+
+template <class mutex>
+class lock_guard {
+ public:
+ lock_guard(mutex &mu) : mu_(mu), locked(true) { gpr_mu_lock(&mu.mu_); }
+ ~lock_guard() { unlock_internal(); }
+ protected:
+ void lock_internal() {
+ if (!locked) gpr_mu_lock(&mu_.mu_);
+ locked = true;
+ }
+ void unlock_internal() {
+ if (locked) gpr_mu_unlock(&mu_.mu_);
+ locked = false;
+ }
+ private:
+ mutex &mu_;
+ bool locked;
+ friend class condition_variable;
+};
+
+template <class mutex>
+class unique_lock : public lock_guard<mutex> {
+ public:
+ unique_lock(mutex &mu) : lock_guard(mu) { }
+ void lock() { lock_internal(); }
+ void unlock() { unlock_internal(); }
+};
+
+class condition_variable {
+ public:
+ condition_variable() { gpr_cv_init(&cv_); }
+ ~condition_variable() { gpr_cv_destroy(&cv_); }
+ void wait(lock_guard<mutex> &mu) {
+ mu.locked = false;
+ gpr_cv_wait(&cv_, &mu.mu_.mu_, gpr_inf_future);
+ mu.locked = true;
+ }
+ void notify_one() { gpr_cv_signal(&cv_); }
+ void notify_all() { gpr_cv_broadcast(&cv_); }
+ private:
+ gpr_cv cv_;
+};
+
+} // namespace grpc
+
+#endif // GRPCXX_IMPL_SYNC_NO_CXX11_H
diff --git a/src/php/tests/unit_tests/CompletionQueueTest.php b/include/grpc++/impl/thd.h
index 76ee61dfe8..4c4578a92d 100755..100644
--- a/src/php/tests/unit_tests/CompletionQueueTest.php
+++ b/include/grpc++/impl/thd.h
@@ -1,4 +1,3 @@
-<?php
/*
*
* Copyright 2015, Google Inc.
@@ -31,16 +30,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-class CompletionQueueTest extends PHPUnit_Framework_TestCase{
- public function testNextReturnsNullWithNoCall() {
- $cq = new Grpc\CompletionQueue();
- $event = $cq->next(Grpc\Timeval::zero());
- $this->assertNull($event);
- }
- public function testPluckReturnsNullWithNoCall() {
- $cq = new Grpc\CompletionQueue();
- $event = $cq->pluck(0, Grpc\Timeval::zero());
- $this->assertNull($event);
- }
-}
+#ifndef GRPCXX_IMPL_THD_H
+#define GRPCXX_IMPL_THD_H
+
+#include <grpc++/config.h>
+
+#ifdef GRPC_CXX0X_NO_THREAD
+#include <grpc++/impl/thd_no_cxx11.h>
+#else
+#include <grpc++/impl/thd_cxx11.h>
+#endif
+
+#endif // GRPCXX_IMPL_THD_H
diff --git a/include/grpc++/impl/thd_cxx11.h b/include/grpc++/impl/thd_cxx11.h
new file mode 100644
index 0000000000..2055b1d538
--- /dev/null
+++ b/include/grpc++/impl/thd_cxx11.h
@@ -0,0 +1,45 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_THD_CXX11_H
+#define GRPCXX_IMPL_THD_CXX11_H
+
+#include <thread>
+
+namespace grpc {
+
+using std::thread;
+
+} // namespace grpc
+
+#endif // GRPCXX_IMPL_THD_CXX11_H
diff --git a/include/grpc++/impl/thd_no_cxx11.h b/include/grpc++/impl/thd_no_cxx11.h
new file mode 100644
index 0000000000..a01b931df8
--- /dev/null
+++ b/include/grpc++/impl/thd_no_cxx11.h
@@ -0,0 +1,89 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_THD_NO_CXX11_H
+#define GRPCXX_IMPL_THD_NO_CXX11_H
+
+#include <grpc/support/thd.h>
+
+namespace grpc {
+
+class thread {
+ public:
+ template<class T> thread(void (T::*fptr)(), T *obj) {
+ func_ = new thread_function<T>(fptr, obj);
+ joined_ = false;
+ start();
+ }
+ ~thread() {
+ if (!joined_) std::terminate();
+ delete func_;
+ }
+ void join() {
+ gpr_thd_join(thd_);
+ joined_ = true;
+ }
+ private:
+ void start() {
+ gpr_thd_options options = gpr_thd_options_default();
+ gpr_thd_options_set_joinable(&options);
+ gpr_thd_new(&thd_, thread_func, (void *) func_, &options);
+ }
+ static void thread_func(void *arg) {
+ thread_function_base *func = (thread_function_base *) arg;
+ func->call();
+ }
+ class thread_function_base {
+ public:
+ virtual ~thread_function_base() { }
+ virtual void call() = 0;
+ };
+ template<class T>
+ class thread_function : public thread_function_base {
+ public:
+ thread_function(void (T::*fptr)(), T *obj)
+ : fptr_(fptr)
+ , obj_(obj) { }
+ virtual void call() { (obj_->*fptr_)(); }
+ private:
+ void (T::*fptr_)();
+ T *obj_;
+ };
+ thread_function_base *func_;
+ gpr_thd_id thd_;
+ bool joined_;
+};
+
+} // namespace grpc
+
+#endif // GRPCXX_IMPL_THD_NO_CXX11_H
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index bddb4f62aa..eb50611573 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -34,15 +34,14 @@
#ifndef GRPCXX_SERVER_H
#define GRPCXX_SERVER_H
-#include <condition_variable>
#include <list>
#include <memory>
-#include <mutex>
#include <grpc++/completion_queue.h>
#include <grpc++/config.h>
#include <grpc++/impl/call.h>
#include <grpc++/impl/service_type.h>
+#include <grpc++/impl/sync.h>
#include <grpc++/status.h>
struct grpc_server;
@@ -110,12 +109,12 @@ class Server GRPC_FINAL : private CallHook,
CompletionQueue cq_;
// Sever status
- std::mutex mu_;
+ grpc::mutex mu_;
bool started_;
bool shutdown_;
// The number of threads which are running callbacks.
int num_running_cb_;
- std::condition_variable callback_cv_;
+ grpc::condition_variable callback_cv_;
std::list<SyncRequest> sync_methods_;
diff --git a/include/grpc/support/port_platform.h b/include/grpc/support/port_platform.h
index 53f6cd098f..034de5bd34 100644
--- a/include/grpc/support/port_platform.h
+++ b/include/grpc/support/port_platform.h
@@ -223,7 +223,7 @@
#endif
#if defined(GPR_POSIX_SOCKET) + defined(GPR_WIN32) != 1
-#error Must define exactly one of GPR_POSIX_POLLSET, GPR_WIN32
+#error Must define exactly one of GPR_POSIX_SOCKET, GPR_WIN32
#endif
typedef int16_t gpr_int16;
diff --git a/include/grpc/support/thd.h b/include/grpc/support/thd.h
index 64d5bed49a..8126992d6b 100644
--- a/include/grpc/support/thd.h
+++ b/include/grpc/support/thd.h
@@ -52,9 +52,8 @@ typedef gpr_uint64 gpr_thd_id;
/* Thread creation options. */
typedef struct {
- int flags; /* Flags below can be set here. Default value 0. */
+ int flags; /* Opaque field. Get and set with accessors below. */
} gpr_thd_options;
-/* No flags are currently defined. */
/* Create a new thread running (*thd_body)(arg) and place its thread identifier
in *t, and return true. If there are insufficient resources, return false.
@@ -66,9 +65,25 @@ int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg,
/* Return a gpr_thd_options struct with all fields set to defaults. */
gpr_thd_options gpr_thd_options_default(void);
+/* Set the thread to become detached on startup - this is the default. */
+void gpr_thd_options_set_detached(gpr_thd_options *options);
+
+/* Set the thread to become joinable - mutually exclusive with detached. */
+void gpr_thd_options_set_joinable(gpr_thd_options *options);
+
+/* Returns non-zero if the option detached is set. */
+int gpr_thd_options_is_detached(const gpr_thd_options *options);
+
+/* Returns non-zero if the option joinable is set. */
+int gpr_thd_options_is_joinable(const gpr_thd_options *options);
+
/* Returns the identifier of the current thread. */
gpr_thd_id gpr_thd_currentid(void);
+/* Blocks until the specified thread properly terminates.
+ Calling this on a detached thread has unpredictable results. */
+void gpr_thd_join(gpr_thd_id t);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index d5004624d4..c78f0333d8 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -109,9 +109,49 @@ bool HasBidiStreaming(const grpc::protobuf::FileDescriptor *file) {
}
return false;
}
+
+grpc::string FilenameIdentifier(const grpc::string& filename) {
+ grpc::string result;
+ for (unsigned i = 0; i < filename.size(); i++) {
+ char c = filename[i];
+ if (isalnum(c)) {
+ result.push_back(c);
+ } else {
+ static char hex[] = "0123456789abcdef";
+ result.push_back('_');
+ result.push_back(hex[(c >> 4) & 0xf]);
+ result.push_back(hex[c & 0xf]);
+ }
+ }
+ return result;
+}
} // namespace
-grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file) {
+grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params) {
+ grpc::string output;
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+
+ vars["filename"] = file->name();
+ vars["filename_identifier"] = FilenameIdentifier(file->name());
+ vars["filename_base"] = grpc_generator::StripProto(file->name());
+
+ printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
+ printer.Print(vars, "// If you make any local change, they will be lost.\n");
+ printer.Print(vars, "// source: $filename$\n");
+ printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
+ printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
+ printer.Print(vars, "\n");
+ printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
+ printer.Print(vars, "\n");
+
+ return output;
+}
+
+grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params) {
grpc::string temp =
"#include <grpc++/impl/internal_stub.h>\n"
"#include <grpc++/impl/service_type.h>\n"
@@ -155,17 +195,21 @@ grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file) {
"class ServerAsyncReaderWriter;\n");
}
temp.append("} // namespace grpc\n");
- return temp;
-}
-grpc::string GetSourceIncludes() {
- return "#include <grpc++/async_unary_call.h>\n"
- "#include <grpc++/channel_interface.h>\n"
- "#include <grpc++/impl/client_unary_call.h>\n"
- "#include <grpc++/impl/rpc_method.h>\n"
- "#include <grpc++/impl/rpc_service_method.h>\n"
- "#include <grpc++/impl/service_type.h>\n"
- "#include <grpc++/stream.h>\n";
+ temp.append("\n");
+
+ std::vector<grpc::string> parts =
+ grpc_generator::tokenize(file->package(), ".");
+
+ for (auto part = parts.begin(); part != parts.end(); part++) {
+ temp.append("namespace ");
+ temp.append(*part);
+ temp.append(" {\n");
+ }
+
+ temp.append("\n");
+
+ return temp;
}
void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
@@ -353,16 +397,99 @@ void PrintHeaderService(grpc::protobuf::io::Printer *printer,
printer->Print("};\n");
}
-grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file) {
+grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params) {
grpc::string output;
grpc::protobuf::io::StringOutputStream output_stream(&output);
grpc::protobuf::io::Printer printer(&output_stream, '$');
std::map<grpc::string, grpc::string> vars;
+ if (!params.services_namespace.empty()) {
+ vars["services_namespace"] = params.services_namespace;
+ printer.Print(vars, "\nnamespace $services_namespace$ {\n\n");
+ }
+
for (int i = 0; i < file->service_count(); ++i) {
PrintHeaderService(&printer, file->service(i), &vars);
printer.Print("\n");
}
+
+ if (!params.services_namespace.empty()) {
+ printer.Print(vars, "} // namespace $services_namespace$\n\n");
+ }
+
+ return output;
+}
+
+grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params) {
+ grpc::string output;
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+
+ vars["filename"] = file->name();
+ vars["filename_identifier"] = FilenameIdentifier(file->name());
+
+ std::vector<grpc::string> parts =
+ grpc_generator::tokenize(file->package(), ".");
+
+ for (auto part = parts.rbegin(); part != parts.rend(); part++) {
+ vars["part"] = *part;
+ printer.Print(vars, "} // namespace $part$\n");
+ }
+
+ printer.Print(vars, "\n\n");
+ printer.Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
+
+ return output;
+}
+
+grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params) {
+ grpc::string output;
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+
+ vars["filename"] = file->name();
+ vars["filename_base"] = grpc_generator::StripProto(file->name());
+
+ printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
+ printer.Print(vars, "// If you make any local change, they will be lost.\n");
+ printer.Print(vars, "// source: $filename$\n\n");
+ printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
+ printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
+ printer.Print(vars, "\n");
+
+ return output;
+}
+
+grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &param) {
+ grpc::string output;
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+
+ printer.Print(vars, "#include <grpc++/async_unary_call.h>\n");
+ printer.Print(vars, "#include <grpc++/channel_interface.h>\n");
+ printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
+ printer.Print(vars, "#include <grpc++/impl/rpc_method.h>\n");
+ printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
+ printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
+ printer.Print(vars, "#include <grpc++/stream.h>\n");
+
+ std::vector<grpc::string> parts =
+ grpc_generator::tokenize(file->package(), ".");
+
+ for (auto part = parts.begin(); part != parts.end(); part++) {
+ vars["part"] = *part;
+ printer.Print(vars, "namespace $part$ {\n");
+ }
+
+ printer.Print(vars, "\n");
+
return output;
}
@@ -376,18 +503,18 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
grpc_cpp_generator::ClassName(method->output_type(), true);
if (NoStreaming(method)) {
printer->Print(*vars,
- "::grpc::Status $Service$::Stub::$Method$("
+ "::grpc::Status $ns$$Service$::Stub::$Method$("
"::grpc::ClientContext* context, "
"const $Request$& request, $Response$* response) {\n");
printer->Print(*vars,
" return ::grpc::BlockingUnaryCall(channel(),"
- "::grpc::RpcMethod($Service$_method_names[$Idx$]), "
+ "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$]), "
"context, request, response);\n"
"}\n\n");
printer->Print(
*vars,
"std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
- "$Service$::Stub::Async$Method$(::grpc::ClientContext* context, "
+ "$ns$$Service$::Stub::Async$Method$(::grpc::ClientContext* context, "
"const $Request$& request, "
"::grpc::CompletionQueue* cq, void* tag) {\n");
printer->Print(*vars,
@@ -395,32 +522,32 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
"::grpc::ClientAsyncResponseReader< $Response$>>(new "
"::grpc::ClientAsyncResponseReader< $Response$>("
"channel(), cq, "
- "::grpc::RpcMethod($Service$_method_names[$Idx$]), "
+ "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$]), "
"context, request, tag));\n"
"}\n\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(*vars,
"std::unique_ptr< ::grpc::ClientWriter< $Request$>> "
- "$Service$::Stub::$Method$("
+ "$ns$$Service$::Stub::$Method$("
"::grpc::ClientContext* context, $Response$* response) {\n");
printer->Print(*vars,
" return std::unique_ptr< ::grpc::ClientWriter< "
"$Request$>>(new ::grpc::ClientWriter< $Request$>("
"channel(),"
- "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+ "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
"::grpc::RpcMethod::RpcType::CLIENT_STREAMING), "
"context, response));\n"
"}\n\n");
printer->Print(*vars,
"std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>> "
- "$Service$::Stub::Async$Method$("
+ "$ns$$Service$::Stub::Async$Method$("
"::grpc::ClientContext* context, $Response$* response, "
"::grpc::CompletionQueue* cq, void* tag) {\n");
printer->Print(*vars,
" return std::unique_ptr< ::grpc::ClientAsyncWriter< "
"$Request$>>(new ::grpc::ClientAsyncWriter< $Request$>("
"channel(), cq, "
- "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+ "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
"::grpc::RpcMethod::RpcType::CLIENT_STREAMING), "
"context, response, tag));\n"
"}\n\n");
@@ -428,26 +555,26 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
printer->Print(
*vars,
"std::unique_ptr< ::grpc::ClientReader< $Response$>> "
- "$Service$::Stub::$Method$("
+ "$ns$$Service$::Stub::$Method$("
"::grpc::ClientContext* context, const $Request$& request) {\n");
printer->Print(*vars,
" return std::unique_ptr< ::grpc::ClientReader< "
"$Response$>>(new ::grpc::ClientReader< $Response$>("
"channel(),"
- "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+ "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
"::grpc::RpcMethod::RpcType::SERVER_STREAMING), "
"context, request));\n"
"}\n\n");
printer->Print(*vars,
"std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
- "$Service$::Stub::Async$Method$("
+ "$ns$$Service$::Stub::Async$Method$("
"::grpc::ClientContext* context, const $Request$& request, "
"::grpc::CompletionQueue* cq, void* tag) {\n");
printer->Print(*vars,
" return std::unique_ptr< ::grpc::ClientAsyncReader< "
"$Response$>>(new ::grpc::ClientAsyncReader< $Response$>("
"channel(), cq, "
- "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+ "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
"::grpc::RpcMethod::RpcType::SERVER_STREAMING), "
"context, request, tag));\n"
"}\n\n");
@@ -455,27 +582,27 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
printer->Print(
*vars,
"std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>> "
- "$Service$::Stub::$Method$(::grpc::ClientContext* context) {\n");
+ "$ns$$Service$::Stub::$Method$(::grpc::ClientContext* context) {\n");
printer->Print(*vars,
" return std::unique_ptr< ::grpc::ClientReaderWriter< "
"$Request$, $Response$>>(new ::grpc::ClientReaderWriter< "
"$Request$, $Response$>("
"channel(),"
- "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+ "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
"::grpc::RpcMethod::RpcType::BIDI_STREAMING), "
"context));\n"
"}\n\n");
printer->Print(*vars,
"std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
"$Request$, $Response$>> "
- "$Service$::Stub::Async$Method$(::grpc::ClientContext* context, "
+ "$ns$$Service$::Stub::Async$Method$(::grpc::ClientContext* context, "
"::grpc::CompletionQueue* cq, void* tag) {\n");
printer->Print(*vars,
" return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
"$Request$, $Response$>>(new "
"::grpc::ClientAsyncReaderWriter< $Request$, $Response$>("
"channel(), cq, "
- "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+ "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
"::grpc::RpcMethod::RpcType::BIDI_STREAMING), "
"context, tag));\n"
"}\n\n");
@@ -492,7 +619,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
grpc_cpp_generator::ClassName(method->output_type(), true);
if (NoStreaming(method)) {
printer->Print(*vars,
- "::grpc::Status $Service$::Service::$Method$("
+ "::grpc::Status $ns$$Service$::Service::$Method$("
"::grpc::ServerContext* context, "
"const $Request$* request, $Response$* response) {\n");
printer->Print(
@@ -501,7 +628,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
printer->Print("}\n\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(*vars,
- "::grpc::Status $Service$::Service::$Method$("
+ "::grpc::Status $ns$$Service$::Service::$Method$("
"::grpc::ServerContext* context, "
"::grpc::ServerReader< $Request$>* reader, "
"$Response$* response) {\n");
@@ -511,7 +638,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
printer->Print("}\n\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(*vars,
- "::grpc::Status $Service$::Service::$Method$("
+ "::grpc::Status $ns$$Service$::Service::$Method$("
"::grpc::ServerContext* context, "
"const $Request$* request, "
"::grpc::ServerWriter< $Response$>* writer) {\n");
@@ -521,7 +648,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
printer->Print("}\n\n");
} else if (BidiStreaming(method)) {
printer->Print(*vars,
- "::grpc::Status $Service$::Service::$Method$("
+ "::grpc::Status $ns$$Service$::Service::$Method$("
"::grpc::ServerContext* context, "
"::grpc::ServerReaderWriter< $Response$, $Request$>* "
"stream) {\n");
@@ -543,7 +670,7 @@ void PrintSourceServerAsyncMethod(
grpc_cpp_generator::ClassName(method->output_type(), true);
if (NoStreaming(method)) {
printer->Print(*vars,
- "void $Service$::AsyncService::Request$Method$("
+ "void $ns$$Service$::AsyncService::Request$Method$("
"::grpc::ServerContext* context, "
"$Request$* request, "
"::grpc::ServerAsyncResponseWriter< $Response$>* response, "
@@ -554,7 +681,7 @@ void PrintSourceServerAsyncMethod(
printer->Print("}\n\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(*vars,
- "void $Service$::AsyncService::Request$Method$("
+ "void $ns$$Service$::AsyncService::Request$Method$("
"::grpc::ServerContext* context, "
"::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
"::grpc::CompletionQueue* cq, void* tag) {\n");
@@ -564,7 +691,7 @@ void PrintSourceServerAsyncMethod(
printer->Print("}\n\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(*vars,
- "void $Service$::AsyncService::Request$Method$("
+ "void $ns$$Service$::AsyncService::Request$Method$("
"::grpc::ServerContext* context, "
"$Request$* request, "
"::grpc::ServerAsyncWriter< $Response$>* writer, "
@@ -576,7 +703,7 @@ void PrintSourceServerAsyncMethod(
} else if (BidiStreaming(method)) {
printer->Print(
*vars,
- "void $Service$::AsyncService::Request$Method$("
+ "void $ns$$Service$::AsyncService::Request$Method$("
"::grpc::ServerContext* context, "
"::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
"::grpc::CompletionQueue* cq, void *tag) {\n");
@@ -592,7 +719,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Service"] = service->name();
- printer->Print(*vars, "static const char* $Service$_method_names[] = {\n");
+ printer->Print(*vars, "static const char* $prefix$$Service$_method_names[] = {\n");
for (int i = 0; i < service->method_count(); ++i) {
(*vars)["Method"] = service->method(i)->name();
printer->Print(*vars, " \"/$Package$$Service$/$Method$\",\n");
@@ -601,9 +728,9 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
printer->Print(
*vars,
- "std::unique_ptr< $Service$::Stub> $Service$::NewStub("
+ "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
"const std::shared_ptr< ::grpc::ChannelInterface>& channel) {\n"
- " std::unique_ptr< $Service$::Stub> stub(new $Service$::Stub());\n"
+ " std::unique_ptr< $ns$$Service$::Stub> stub(new $ns$$Service$::Stub());\n"
" stub->set_channel(channel);\n"
" return stub;\n"
"}\n\n");
@@ -615,12 +742,12 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
(*vars)["MethodCount"] = as_string(service->method_count());
printer->Print(
*vars,
- "$Service$::AsyncService::AsyncService(::grpc::CompletionQueue* cq) : "
- "::grpc::AsynchronousService(cq, $Service$_method_names, $MethodCount$) "
+ "$ns$$Service$::AsyncService::AsyncService(::grpc::CompletionQueue* cq) : "
+ "::grpc::AsynchronousService(cq, $prefix$$Service$_method_names, $MethodCount$) "
"{}\n\n");
printer->Print(*vars,
- "$Service$::Service::~Service() {\n"
+ "$ns$$Service$::Service::~Service() {\n"
" delete service_;\n"
"}\n\n");
for (int i = 0; i < service->method_count(); ++i) {
@@ -629,7 +756,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
PrintSourceServerAsyncMethod(printer, service->method(i), vars);
}
printer->Print(*vars,
- "::grpc::RpcService* $Service$::Service::service() {\n");
+ "::grpc::RpcService* $ns$$Service$::Service::service() {\n");
printer->Indent();
printer->Print(
"if (service_ != nullptr) {\n"
@@ -648,52 +775,52 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
printer->Print(
*vars,
"service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
- " $Service$_method_names[$Idx$],\n"
+ " $prefix$$Service$_method_names[$Idx$],\n"
" ::grpc::RpcMethod::NORMAL_RPC,\n"
- " new ::grpc::RpcMethodHandler< $Service$::Service, $Request$, "
+ " new ::grpc::RpcMethodHandler< $ns$$Service$::Service, $Request$, "
"$Response$>(\n"
- " std::function< ::grpc::Status($Service$::Service*, "
+ " std::function< ::grpc::Status($ns$$Service$::Service*, "
"::grpc::ServerContext*, const $Request$*, $Response$*)>("
- "&$Service$::Service::$Method$), this),\n"
+ "&$ns$$Service$::Service::$Method$), this),\n"
" new $Request$, new $Response$));\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(
*vars,
"service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
- " $Service$_method_names[$Idx$],\n"
+ " $prefix$$Service$_method_names[$Idx$],\n"
" ::grpc::RpcMethod::CLIENT_STREAMING,\n"
" new ::grpc::ClientStreamingHandler< "
- "$Service$::Service, $Request$, $Response$>(\n"
- " std::function< ::grpc::Status($Service$::Service*, "
+ "$ns$$Service$::Service, $Request$, $Response$>(\n"
+ " std::function< ::grpc::Status($ns$$Service$::Service*, "
"::grpc::ServerContext*, "
"::grpc::ServerReader< $Request$>*, $Response$*)>("
- "&$Service$::Service::$Method$), this),\n"
+ "&$ns$$Service$::Service::$Method$), this),\n"
" new $Request$, new $Response$));\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
"service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
- " $Service$_method_names[$Idx$],\n"
+ " $prefix$$Service$_method_names[$Idx$],\n"
" ::grpc::RpcMethod::SERVER_STREAMING,\n"
" new ::grpc::ServerStreamingHandler< "
- "$Service$::Service, $Request$, $Response$>(\n"
- " std::function< ::grpc::Status($Service$::Service*, "
+ "$ns$$Service$::Service, $Request$, $Response$>(\n"
+ " std::function< ::grpc::Status($ns$$Service$::Service*, "
"::grpc::ServerContext*, "
"const $Request$*, ::grpc::ServerWriter< $Response$>*)>("
- "&$Service$::Service::$Method$), this),\n"
+ "&$ns$$Service$::Service::$Method$), this),\n"
" new $Request$, new $Response$));\n");
} else if (BidiStreaming(method)) {
printer->Print(
*vars,
"service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
- " $Service$_method_names[$Idx$],\n"
+ " $prefix$$Service$_method_names[$Idx$],\n"
" ::grpc::RpcMethod::BIDI_STREAMING,\n"
" new ::grpc::BidiStreamingHandler< "
- "$Service$::Service, $Request$, $Response$>(\n"
- " std::function< ::grpc::Status($Service$::Service*, "
+ "$ns$$Service$::Service, $Request$, $Response$>(\n"
+ " std::function< ::grpc::Status($ns$$Service$::Service*, "
"::grpc::ServerContext*, "
"::grpc::ServerReaderWriter< $Response$, $Request$>*)>("
- "&$Service$::Service::$Method$), this),\n"
+ "&$ns$$Service$::Service::$Method$), this),\n"
" new $Request$, new $Response$));\n");
}
}
@@ -702,7 +829,8 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
printer->Print("}\n\n");
}
-grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file) {
+grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params) {
grpc::string output;
grpc::protobuf::io::StringOutputStream output_stream(&output);
grpc::protobuf::io::Printer printer(&output_stream, '$');
@@ -713,6 +841,13 @@ grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file) {
if (!file->package().empty()) {
vars["Package"].append(".");
}
+ if (!params.services_namespace.empty()) {
+ vars["ns"] = params.services_namespace + "::";
+ vars["prefix"] = params.services_namespace;
+ } else {
+ vars["ns"] = "";
+ vars["prefix"] = "";
+ }
for (int i = 0; i < file->service_count(); ++i) {
PrintSourceService(&printer, file->service(i), &vars);
@@ -721,4 +856,22 @@ grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file) {
return output;
}
+grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params) {
+ grpc::string temp;
+
+ std::vector<grpc::string> parts =
+ grpc_generator::tokenize(file->package(), ".");
+
+ for (auto part = parts.begin(); part != parts.end(); part++) {
+ temp.append("} // namespace ");
+ temp.append(*part);
+ temp.append("\n");
+ }
+
+ temp.append("\n");
+
+ return temp;
+}
+
} // namespace grpc_cpp_generator
diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h
index 2ecdb5c47e..70c2e985f6 100644
--- a/src/compiler/cpp_generator.h
+++ b/src/compiler/cpp_generator.h
@@ -38,17 +38,43 @@
namespace grpc_cpp_generator {
+// Contains all the parameters that are parsed from the command line.
+struct Parameters {
+ // Puts the service into a namespace
+ grpc::string services_namespace;
+};
+
+// Return the prologue of the generated header file.
+grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params);
+
// Return the includes needed for generated header file.
-grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file);
+grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params);
// Return the includes needed for generated source file.
-grpc::string GetSourceIncludes();
+grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params);
+
+// Return the epilogue of the generated header file.
+grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params);
+
+// Return the prologue of the generated source file.
+grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params);
// Return the services for generated header file.
-grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file);
+grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params);
// Return the services for generated source file.
-grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file);
+grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params);
+
+// Return the epilogue of the generated source file.
+grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
+ const Parameters &params);
} // namespace grpc_cpp_generator
diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc
index 5b83aa85cf..88c704948e 100644
--- a/src/compiler/cpp_plugin.cc
+++ b/src/compiler/cpp_plugin.cc
@@ -58,18 +58,48 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
return false;
}
+ grpc_cpp_generator::Parameters generator_parameters;
+
+ if (!parameter.empty()) {
+ std::vector<grpc::string> parameters_list =
+ grpc_generator::tokenize(parameter, ",");
+ for (auto parameter_string = parameters_list.begin();
+ parameter_string != parameters_list.end();
+ parameter_string++) {
+ std::vector<grpc::string> param =
+ grpc_generator::tokenize(*parameter_string, "=");
+ if (param[0] == "services_namespace") {
+ generator_parameters.services_namespace = param[1];
+ } else {
+ *error = grpc::string("Unknown parameter: ") + *parameter_string;
+ return false;
+ }
+ }
+ }
+
grpc::string file_name = grpc_generator::StripProto(file->name());
- // Generate .pb.h
- Insert(context, file_name + ".pb.h", "includes",
- grpc_cpp_generator::GetHeaderIncludes(file));
- Insert(context, file_name + ".pb.h", "namespace_scope",
- grpc_cpp_generator::GetHeaderServices(file));
- // Generate .pb.cc
- Insert(context, file_name + ".pb.cc", "includes",
- grpc_cpp_generator::GetSourceIncludes());
- Insert(context, file_name + ".pb.cc", "namespace_scope",
- grpc_cpp_generator::GetSourceServices(file));
+ grpc::string header_code =
+ grpc_cpp_generator::GetHeaderPrologue(file, generator_parameters) +
+ grpc_cpp_generator::GetHeaderIncludes(file, generator_parameters) +
+ grpc_cpp_generator::GetHeaderServices(file, generator_parameters) +
+ grpc_cpp_generator::GetHeaderEpilogue(file, generator_parameters);
+ std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output(
+ context->Open(file_name + ".grpc.pb.h"));
+ grpc::protobuf::io::CodedOutputStream header_coded_out(
+ header_output.get());
+ header_coded_out.WriteRaw(header_code.data(), header_code.size());
+
+ grpc::string source_code =
+ grpc_cpp_generator::GetSourcePrologue(file, generator_parameters) +
+ grpc_cpp_generator::GetSourceIncludes(file, generator_parameters) +
+ grpc_cpp_generator::GetSourceServices(file, generator_parameters) +
+ grpc_cpp_generator::GetSourceEpilogue(file, generator_parameters);
+ std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output(
+ context->Open(file_name + ".grpc.pb.cc"));
+ grpc::protobuf::io::CodedOutputStream source_coded_out(
+ source_output.get());
+ source_coded_out.WriteRaw(source_code.data(), source_code.size());
return true;
}
diff --git a/src/compiler/generator_helpers.h b/src/compiler/generator_helpers.h
index 1e6727dd4c..374e1374cf 100644
--- a/src/compiler/generator_helpers.h
+++ b/src/compiler/generator_helpers.h
@@ -75,6 +75,47 @@ inline grpc::string StringReplace(grpc::string str, const grpc::string &from,
return str;
}
+inline std::vector<grpc::string> tokenize(const grpc::string &input,
+ const grpc::string &delimiters) {
+ std::vector<grpc::string> tokens;
+ size_t pos, last_pos = 0;
+
+ for (;;) {
+ bool done = false;
+ pos = input.find_first_of(delimiters, last_pos);
+ if (pos == grpc::string::npos) {
+ done = true;
+ pos = input.length();
+ }
+
+ tokens.push_back(input.substr(last_pos, pos - last_pos));
+ if (done) return tokens;
+
+ last_pos = pos + 1;
+ }
+}
+
+inline grpc::string CapitalizeFirstLetter(grpc::string s) {
+ if (s.empty()) {
+ return s;
+ }
+ s[0] = ::toupper(s[0]);
+ return s;
+}
+
+inline grpc::string LowerUnderscoreToUpperCamel(grpc::string str) {
+ std::vector<grpc::string> tokens = tokenize(str, "_");
+ grpc::string result = "";
+ for (unsigned int i = 0; i < tokens.size(); i++) {
+ result += CapitalizeFirstLetter(tokens[i]);
+ }
+ return result;
+}
+
+inline grpc::string FileNameInUpperCamel(const grpc::protobuf::FileDescriptor *file) {
+ return LowerUnderscoreToUpperCamel(StripProto(file->name()));
+}
+
} // namespace grpc_generator
#endif // GRPC_INTERNAL_COMPILER_GENERATOR_HELPERS_H
diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc
new file mode 100644
index 0000000000..c68c9c37c2
--- /dev/null
+++ b/src/compiler/objective_c_generator.cc
@@ -0,0 +1,236 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <map>
+
+#include "src/compiler/objective_c_generator.h"
+#include "src/compiler/objective_c_generator_helpers.h"
+
+#include "src/compiler/config.h"
+
+#include <sstream>
+
+namespace grpc_objective_c_generator {
+namespace {
+
+void PrintSimpleBlockSignature(grpc::protobuf::io::Printer *printer,
+ const grpc::protobuf::MethodDescriptor *method,
+ std::map<grpc::string, grpc::string> *vars) {
+ (*vars)["method_name"] = method->name();
+ (*vars)["request_type"] = PrefixedName(method->input_type()->name());
+ (*vars)["response_type"] = PrefixedName(method->output_type()->name());
+
+ if (method->server_streaming()) {
+ printer->Print("// When the response stream finishes, the handler is "
+ "called with nil for both arguments.\n\n");
+ } else {
+ printer->Print("// The handler is only called once.\n\n");
+ }
+ printer->Print(*vars, "- (id<GRXLiveSource>)$method_name$WithRequest:"
+ "($request_type$)request completionHandler:(void(^)"
+ "($response_type$ *, NSError *))handler");
+}
+
+void PrintSimpleDelegateSignature(grpc::protobuf::io::Printer *printer,
+ const grpc::protobuf::MethodDescriptor *method,
+ std::map<grpc::string, grpc::string> *vars) {
+ (*vars)["method_name"] = method->name();
+ (*vars)["request_type"] = PrefixedName(method->input_type()->name());
+
+ printer->Print(*vars, "- (id<GRXLiveSource>)$method_name$WithRequest:"
+ "($request_type$)request delegate:(id<GRXSink>)delegate");
+}
+
+void PrintAdvancedSignature(grpc::protobuf::io::Printer *printer,
+ const grpc::protobuf::MethodDescriptor *method,
+ std::map<grpc::string, grpc::string> *vars) {
+ (*vars)["method_name"] = method->name();
+ printer->Print(*vars, "- (GRXSource *)$method_name$WithRequest:"
+ "(id<GRXSource>)request");
+}
+
+void PrintSourceMethodSimpleBlock(grpc::protobuf::io::Printer *printer,
+ const grpc::protobuf::MethodDescriptor *method,
+ std::map<grpc::string, grpc::string> *vars) {
+ PrintSimpleBlockSignature(printer, method, vars);
+
+ (*vars)["method_name"] = method->name();
+ printer->Print(" {\n");
+ printer->Indent();
+ printer->Print(*vars, "return [[self $method_name$WithRequest:request] "
+ "connectHandler:^(id value, NSError *error) {\n");
+ printer->Indent();
+ printer->Print("handler(value, error);\n");
+ printer->Outdent();
+ printer->Print("}];\n");
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void PrintSourceMethodSimpleDelegate(grpc::protobuf::io::Printer *printer,
+ const grpc::protobuf::MethodDescriptor *method,
+ std::map<grpc::string, grpc::string> *vars) {
+ PrintSimpleDelegateSignature(printer, method, vars);
+
+ (*vars)["method_name"] = method->name();
+ printer->Print(" {\n");
+ printer->Indent();
+ printer->Print(*vars, "return [[self $method_name$WithRequest:request]"
+ "connectToSink:delegate];\n");
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void PrintSourceMethodAdvanced(grpc::protobuf::io::Printer *printer,
+ const grpc::protobuf::MethodDescriptor *method,
+ std::map<grpc::string, grpc::string> *vars) {
+ PrintAdvancedSignature(printer, method, vars);
+
+ (*vars)["method_name"] = method->name();
+ printer->Print(" {\n");
+ printer->Indent();
+ printer->Print(*vars, "return [self $method_name$WithRequest:request "
+ "client:[self newClient]];\n");
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void PrintSourceMethodHandler(grpc::protobuf::io::Printer *printer,
+ const grpc::protobuf::MethodDescriptor *method,
+ std::map<grpc::string, grpc::string> *vars) {
+ (*vars)["method_name"] = method->name();
+ (*vars)["response_type"] = PrefixedName(method->output_type()->name());
+ (*vars)["caps_name"] = grpc_generator::CapitalizeFirstLetter(method->name());
+
+ printer->Print(*vars, "- (GRXSource *)$method_name$WithRequest:"
+ "(id<GRXSource>)request client:(PBgRPCClient *)client {\n");
+ printer->Indent();
+ printer->Print(*vars,
+ "return [self responseWithMethod:$@\"$caps_name\"\n");
+ printer->Print(*vars,
+ " class:[$response_type$ class]\n");
+ printer->Print(" request:request\n");
+ printer->Print(" client:client];\n");
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+}
+
+grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service,
+ const grpc::string message_header) {
+ grpc::string output;
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+ printer.Print("#import \"PBgRPCClient.h\"\n");
+ printer.Print("#import \"PBStub.h\"\n");
+ vars["message_header"] = message_header;
+ printer.Print(vars, "#import \"$message_header$\"\n\n");
+ printer.Print("@protocol GRXSource\n");
+ printer.Print("@class GRXSource\n\n");
+ vars["service_name"] = service->name();
+ printer.Print("@protocol $service_name$Stub <NSObject>\n\n");
+ printer.Print("#pragma mark Simple block handlers\n\n");
+ for (int i = 0; i < service->method_count(); i++) {
+ PrintSimpleBlockSignature(&printer, service->method(i), &vars);
+ printer.Print(";\n");
+ }
+ printer.Print("\n");
+ printer.Print("#pragma mark Simple delegate handlers.\n\n");
+ printer.Print("# TODO(jcanizales): Use high-level snippets to remove this duplication.");
+ for (int i = 0; i < service->method_count(); i++) {
+ PrintSimpleDelegateSignature(&printer, service->method(i), &vars);
+ printer.Print(";\n");
+ }
+ printer.Print("\n");
+ printer.Print("#pragma mark Advanced handlers.\n\n");
+ for (int i = 0; i < service->method_count(); i++) {
+ PrintAdvancedSignature(&printer, service->method(i), &vars);
+ printer.Print(";\n");
+ }
+ printer.Print("\n");
+ printer.Print("@end\n\n");
+ printer.Print("// Basic stub that only does marshalling and parsing\n");
+ printer.Print(vars, "@interface $service_name$Stub :"
+ " PBStub<$service_name$Stub>\n");
+ printer.Print("- (instancetype)initWithHost:(NSString *)host;\n");
+ printer.Print("@end\n");
+ return output;
+}
+
+grpc::string GetSource(const grpc::protobuf::ServiceDescriptor *service) {
+ grpc::string output;
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+ vars["service_name"] = service->name();
+ printer.Print(vars, "#import \"$service_name$Stub.pb.h\"\n");
+ printer.Print("#import \"PBGeneratedMessage+GRXSource.h\"\n\n");
+ vars["full_name"] = service->full_name();
+ printer.Print(vars,
+ "static NSString *const kInterface = @\"$full_name$\";\n");
+ printer.Print("@implementation $service_name$Stub\n\n");
+ printer.Print("- (instancetype)initWithHost:(NSString *)host {\n");
+ printer.Indent();
+ printer.Print("if ((self = [super initWithHost:host "
+ "interface:kInterface])) {\n");
+ printer.Print("}\n");
+ printer.Print("return self;\n");
+ printer.Outdent();
+ printer.Print("}\n\n");
+ printer.Print("#pragma mark Simple block handlers.\n");
+ for (int i = 0; i < service->method_count(); i++) {
+ PrintSourceMethodSimpleBlock(&printer, service->method(i), &vars);
+ }
+ printer.Print("\n");
+ printer.Print("#pragma mark Simple delegate handlers.\n");
+ for (int i = 0; i < service->method_count(); i++) {
+ PrintSourceMethodSimpleDelegate(&printer, service->method(i), &vars);
+ }
+ printer.Print("\n");
+ printer.Print("#pragma mark Advanced handlers.\n");
+ for (int i = 0; i < service->method_count(); i++) {
+ PrintSourceMethodAdvanced(&printer, service->method(i), &vars);
+ }
+ printer.Print("\n");
+ printer.Print("#pragma mark Handlers for subclasses "
+ "(stub wrappers) to override.\n");
+ for (int i = 0; i < service->method_count(); i++) {
+ PrintSourceMethodHandler(&printer, service->method(i), &vars);
+ }
+ printer.Print("@end\n");
+ return output;
+}
+
+} // namespace grpc_objective_c_generator
diff --git a/src/compiler/objective_c_generator.h b/src/compiler/objective_c_generator.h
new file mode 100644
index 0000000000..93c730b34e
--- /dev/null
+++ b/src/compiler/objective_c_generator.h
@@ -0,0 +1,48 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H
+#define GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H
+
+#include "src/compiler/config.h"
+
+namespace grpc_objective_c_generator {
+
+grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service,
+ const grpc::string message_header);
+
+grpc::string GetSource(const grpc::protobuf::ServiceDescriptor *service);
+
+} // namespace grpc_objective_c_generator
+
+#endif // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H
diff --git a/src/compiler/objective_c_generator_helpers.h b/src/compiler/objective_c_generator_helpers.h
new file mode 100644
index 0000000000..6a7c13991f
--- /dev/null
+++ b/src/compiler/objective_c_generator_helpers.h
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H
+#define GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H
+
+#include <map>
+#include "src/compiler/config.h"
+#include "src/compiler/generator_helpers.h"
+
+namespace grpc_objective_c_generator {
+
+const grpc::string prefix = "PBG";
+
+inline grpc::string MessageHeaderName(const grpc::protobuf::FileDescriptor *file) {
+ return grpc_generator::FileNameInUpperCamel(file) + ".pb.h";
+}
+
+inline grpc::string StubFileName(grpc::string service_name) {
+ return prefix + service_name + "Stub";
+}
+
+inline grpc::string PrefixedName(grpc::string name) {
+ return prefix + name;
+}
+
+}
+#endif // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H
diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc
new file mode 100644
index 0000000000..eebce0cd20
--- /dev/null
+++ b/src/compiler/objective_c_plugin.cc
@@ -0,0 +1,98 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+// Generates Objective C gRPC service interface out of Protobuf IDL.
+
+#include <memory>
+
+#include "src/compiler/config.h"
+#include "src/compiler/objective_c_generator.h"
+#include "src/compiler/objective_c_generator_helpers.h"
+
+class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
+ public:
+ ObjectiveCGrpcGenerator() {}
+ virtual ~ObjectiveCGrpcGenerator() {}
+
+ virtual bool Generate(const grpc::protobuf::FileDescriptor *file,
+ const grpc::string &parameter,
+ grpc::protobuf::compiler::GeneratorContext *context,
+ grpc::string *error) const {
+
+ if (file->service_count() == 0) {
+ // No services. Do nothing.
+ return true;
+ }
+
+ for (int i = 0; i < file->service_count(); i++) {
+ const grpc::protobuf::ServiceDescriptor *service = file->service(i);
+ grpc::string file_name = grpc_objective_c_generator::StubFileName(
+ service->name());
+
+ // Generate .pb.h
+ grpc::string header_code = grpc_objective_c_generator::GetHeader(
+ service, grpc_objective_c_generator::MessageHeaderName(file));
+ std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output(
+ context->Open(file_name + ".pb.h"));
+ grpc::protobuf::io::CodedOutputStream header_coded_out(
+ header_output.get());
+ header_coded_out.WriteRaw(header_code.data(), header_code.size());
+
+ // Generate .pb.m
+ grpc::string source_code = grpc_objective_c_generator::GetSource(service);
+ std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output(
+ context->Open(file_name + ".pb.m"));
+ grpc::protobuf::io::CodedOutputStream source_coded_out(
+ source_output.get());
+ source_coded_out.WriteRaw(source_code.data(), source_code.size());
+ }
+
+ return true;
+ }
+
+ private:
+ // Insert the given code into the given file at the given insertion point.
+ void Insert(grpc::protobuf::compiler::GeneratorContext *context,
+ const grpc::string &filename, const grpc::string &insertion_point,
+ const grpc::string &code) const {
+ std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
+ context->OpenForInsert(filename, insertion_point));
+ grpc::protobuf::io::CodedOutputStream coded_out(output.get());
+ coded_out.WriteRaw(code.data(), code.size());
+ }
+};
+
+int main(int argc, char *argv[]) {
+ ObjectiveCGrpcGenerator generator;
+ return grpc::protobuf::compiler::PluginMain(argc, argv, &generator);
+}
diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
index e4f85450f5..72149bc4e3 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -36,25 +36,28 @@
#include <cctype>
#include <cstring>
#include <map>
+#include <memory>
#include <ostream>
#include <sstream>
+#include <tuple>
#include <vector>
+#include "grpc++/config.h"
+#include "src/compiler/config.h"
#include "src/compiler/generator_helpers.h"
#include "src/compiler/python_generator.h"
-#include <google/protobuf/io/printer.h>
-#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/descriptor.h>
using grpc_generator::StringReplace;
using grpc_generator::StripProto;
-using google::protobuf::Descriptor;
-using google::protobuf::FileDescriptor;
-using google::protobuf::MethodDescriptor;
-using google::protobuf::ServiceDescriptor;
-using google::protobuf::io::Printer;
-using google::protobuf::io::StringOutputStream;
+using grpc::protobuf::Descriptor;
+using grpc::protobuf::FileDescriptor;
+using grpc::protobuf::MethodDescriptor;
+using grpc::protobuf::ServiceDescriptor;
+using grpc::protobuf::compiler::GeneratorContext;
+using grpc::protobuf::io::CodedOutputStream;
+using grpc::protobuf::io::Printer;
+using grpc::protobuf::io::StringOutputStream;
+using grpc::protobuf::io::ZeroCopyOutputStream;
using std::initializer_list;
using std::make_pair;
using std::map;
@@ -63,6 +66,41 @@ using std::replace;
using std::vector;
namespace grpc_python_generator {
+
+PythonGrpcGenerator::PythonGrpcGenerator(const GeneratorConfiguration& config)
+ : config_(config) {}
+
+PythonGrpcGenerator::~PythonGrpcGenerator() {}
+
+bool PythonGrpcGenerator::Generate(
+ const FileDescriptor* file, const grpc::string& parameter,
+ GeneratorContext* context, grpc::string* error) const {
+ // Get output file name.
+ grpc::string file_name;
+ static const int proto_suffix_length = strlen(".proto");
+ if (file->name().size() > static_cast<size_t>(proto_suffix_length) &&
+ file->name().find_last_of(".proto") == file->name().size() - 1) {
+ file_name = file->name().substr(
+ 0, file->name().size() - proto_suffix_length) + "_pb2.py";
+ } else {
+ *error = "Invalid proto file name. Proto file must end with .proto";
+ return false;
+ }
+
+ std::unique_ptr<ZeroCopyOutputStream> output(
+ context->OpenForInsert(file_name, "module_scope"));
+ CodedOutputStream coded_out(output.get());
+ bool success = false;
+ grpc::string code = "";
+ tie(success, code) = grpc_python_generator::GetServices(file, config_);
+ if (success) {
+ coded_out.WriteRaw(code.data(), code.size());
+ return true;
+ } else {
+ return false;
+ }
+}
+
namespace {
//////////////////////////////////
// BEGIN FORMATTING BOILERPLATE //
@@ -70,14 +108,15 @@ namespace {
// Converts an initializer list of the form { key0, value0, key1, value1, ... }
// into a map of key* to value*. Is merely a readability helper for later code.
-map<std::string, std::string> ListToDict(const initializer_list<std::string>& values) {
+map<grpc::string, grpc::string> ListToDict(
+ const initializer_list<grpc::string>& values) {
assert(values.size() % 2 == 0);
- map<std::string, std::string> value_map;
+ map<grpc::string, grpc::string> value_map;
auto value_iter = values.begin();
for (unsigned i = 0; i < values.size()/2; ++i) {
- std::string key = *value_iter;
+ grpc::string key = *value_iter;
++value_iter;
- std::string value = *value_iter;
+ grpc::string value = *value_iter;
value_map[key] = value;
++value_iter;
}
@@ -111,8 +150,8 @@ class IndentScope {
bool PrintServicer(const ServiceDescriptor* service,
Printer* out) {
- std::string doc = "<fill me in later!>";
- map<std::string, std::string> dict = ListToDict({
+ grpc::string doc = "<fill me in later!>";
+ map<grpc::string, grpc::string> dict = ListToDict({
"Service", service->name(),
"Documentation", doc,
});
@@ -123,7 +162,7 @@ bool PrintServicer(const ServiceDescriptor* service,
out->Print("__metaclass__ = abc.ABCMeta\n");
for (int i = 0; i < service->method_count(); ++i) {
auto meth = service->method(i);
- std::string arg_name = meth->client_streaming() ?
+ grpc::string arg_name = meth->client_streaming() ?
"request_iterator" : "request";
out->Print("@abc.abstractmethod\n");
out->Print("def $Method$(self, $ArgName$, context):\n",
@@ -138,8 +177,8 @@ bool PrintServicer(const ServiceDescriptor* service,
}
bool PrintServer(const ServiceDescriptor* service, Printer* out) {
- std::string doc = "<fill me in later!>";
- map<std::string, std::string> dict = ListToDict({
+ grpc::string doc = "<fill me in later!>";
+ map<grpc::string, grpc::string> dict = ListToDict({
"Service", service->name(),
"Documentation", doc,
});
@@ -167,8 +206,8 @@ bool PrintServer(const ServiceDescriptor* service, Printer* out) {
bool PrintStub(const ServiceDescriptor* service,
Printer* out) {
- std::string doc = "<fill me in later!>";
- map<std::string, std::string> dict = ListToDict({
+ grpc::string doc = "<fill me in later!>";
+ map<grpc::string, grpc::string> dict = ListToDict({
"Service", service->name(),
"Documentation", doc,
});
@@ -179,7 +218,7 @@ bool PrintStub(const ServiceDescriptor* service,
out->Print("__metaclass__ = abc.ABCMeta\n");
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* meth = service->method(i);
- std::string arg_name = meth->client_streaming() ?
+ grpc::string arg_name = meth->client_streaming() ?
"request_iterator" : "request";
auto methdict = ListToDict({"Method", meth->name(), "ArgName", arg_name});
out->Print("@abc.abstractmethod\n");
@@ -196,29 +235,29 @@ bool PrintStub(const ServiceDescriptor* service,
// TODO(protobuf team): Export `ModuleName` from protobuf's
// `src/google/protobuf/compiler/python/python_generator.cc` file.
-std::string ModuleName(const std::string& filename) {
- std::string basename = StripProto(filename);
+grpc::string ModuleName(const grpc::string& filename) {
+ grpc::string basename = StripProto(filename);
basename = StringReplace(basename, "-", "_");
basename = StringReplace(basename, "/", ".");
return basename + "_pb2";
}
bool GetModuleAndMessagePath(const Descriptor* type,
- pair<std::string, std::string>* out) {
+ pair<grpc::string, grpc::string>* out) {
const Descriptor* path_elem_type = type;
vector<const Descriptor*> message_path;
do {
message_path.push_back(path_elem_type);
path_elem_type = path_elem_type->containing_type();
} while (path_elem_type != nullptr);
- std::string file_name = type->file()->name();
+ grpc::string file_name = type->file()->name();
static const int proto_suffix_length = strlen(".proto");
if (!(file_name.size() > static_cast<size_t>(proto_suffix_length) &&
file_name.find_last_of(".proto") == file_name.size() - 1)) {
return false;
}
- std::string module = ModuleName(file_name);
- std::string message_type;
+ grpc::string module = ModuleName(file_name);
+ grpc::string message_type;
for (auto path_iter = message_path.rbegin();
path_iter != message_path.rend(); ++path_iter) {
message_type += (*path_iter)->name() + ".";
@@ -229,28 +268,30 @@ bool GetModuleAndMessagePath(const Descriptor* type,
return true;
}
-bool PrintServerFactory(const std::string& package_qualified_service_name,
+bool PrintServerFactory(const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service, Printer* out) {
out->Print("def early_adopter_create_$Service$_server(servicer, port, "
- "root_certificates, key_chain_pairs):\n",
+ "private_key=None, certificate_chain=None):\n",
"Service", service->name());
{
IndentScope raii_create_server_indent(out);
- map<std::string, std::string> method_description_constructors;
- map<std::string, pair<std::string, std::string>> input_message_modules_and_classes;
- map<std::string, pair<std::string, std::string>> output_message_modules_and_classes;
+ map<grpc::string, grpc::string> method_description_constructors;
+ map<grpc::string, pair<grpc::string, grpc::string>>
+ input_message_modules_and_classes;
+ map<grpc::string, pair<grpc::string, grpc::string>>
+ output_message_modules_and_classes;
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
- const std::string method_description_constructor =
- std::string(method->client_streaming() ? "stream_" : "unary_") +
- std::string(method->server_streaming() ? "stream_" : "unary_") +
+ const grpc::string method_description_constructor =
+ grpc::string(method->client_streaming() ? "stream_" : "unary_") +
+ grpc::string(method->server_streaming() ? "stream_" : "unary_") +
"service_description";
- pair<std::string, std::string> input_message_module_and_class;
+ pair<grpc::string, grpc::string> input_message_module_and_class;
if (!GetModuleAndMessagePath(method->input_type(),
&input_message_module_and_class)) {
return false;
}
- pair<std::string, std::string> output_message_module_and_class;
+ pair<grpc::string, grpc::string> output_message_module_and_class;
if (!GetModuleAndMessagePath(method->output_type(),
&output_message_module_and_class)) {
return false;
@@ -268,17 +309,20 @@ bool PrintServerFactory(const std::string& package_qualified_service_name,
make_pair(method->name(), output_message_module_and_class));
}
out->Print("method_service_descriptions = {\n");
- for (auto& name_and_description_constructor :
- method_description_constructors) {
+ for (auto name_and_description_constructor =
+ method_description_constructors.begin();
+ name_and_description_constructor !=
+ method_description_constructors.end();
+ name_and_description_constructor++) {
IndentScope raii_descriptions_indent(out);
- const std::string method_name = name_and_description_constructor.first;
+ const grpc::string method_name = name_and_description_constructor->first;
auto input_message_module_and_class =
input_message_modules_and_classes.find(method_name);
auto output_message_module_and_class =
output_message_modules_and_classes.find(method_name);
out->Print("\"$Method$\": utilities.$Constructor$(\n", "Method",
method_name, "Constructor",
- name_and_description_constructor.second);
+ name_and_description_constructor->second);
{
IndentScope raii_description_arguments_indent(out);
out->Print("servicer.$Method$,\n", "Method", method_name);
@@ -295,38 +339,43 @@ bool PrintServerFactory(const std::string& package_qualified_service_name,
}
out->Print("}\n");
out->Print(
- "return implementations.secure_server("
+ "return implementations.server("
"\"$PackageQualifiedServiceName$\","
- " method_service_descriptions, port, root_certificates,"
- " key_chain_pairs)\n",
+ " method_service_descriptions, port, private_key=private_key,"
+ " certificate_chain=certificate_chain)\n",
"PackageQualifiedServiceName", package_qualified_service_name);
}
return true;
}
-bool PrintStubFactory(const std::string& package_qualified_service_name,
+bool PrintStubFactory(const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service, Printer* out) {
- map<std::string, std::string> dict = ListToDict({
+ map<grpc::string, grpc::string> dict = ListToDict({
"Service", service->name(),
});
- out->Print(dict, "def early_adopter_create_$Service$_stub(host, port):\n");
+ out->Print(dict, "def early_adopter_create_$Service$_stub(host, port,"
+ " metadata_transformer=None,"
+ " secure=False, root_certificates=None, private_key=None,"
+ " certificate_chain=None, server_host_override=None):\n");
{
IndentScope raii_create_server_indent(out);
- map<std::string, std::string> method_description_constructors;
- map<std::string, pair<std::string, std::string>> input_message_modules_and_classes;
- map<std::string, pair<std::string, std::string>> output_message_modules_and_classes;
+ map<grpc::string, grpc::string> method_description_constructors;
+ map<grpc::string, pair<grpc::string, grpc::string>>
+ input_message_modules_and_classes;
+ map<grpc::string, pair<grpc::string, grpc::string>>
+ output_message_modules_and_classes;
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
- const std::string method_description_constructor =
- std::string(method->client_streaming() ? "stream_" : "unary_") +
- std::string(method->server_streaming() ? "stream_" : "unary_") +
+ const grpc::string method_description_constructor =
+ grpc::string(method->client_streaming() ? "stream_" : "unary_") +
+ grpc::string(method->server_streaming() ? "stream_" : "unary_") +
"invocation_description";
- pair<std::string, std::string> input_message_module_and_class;
+ pair<grpc::string, grpc::string> input_message_module_and_class;
if (!GetModuleAndMessagePath(method->input_type(),
&input_message_module_and_class)) {
return false;
}
- pair<std::string, std::string> output_message_module_and_class;
+ pair<grpc::string, grpc::string> output_message_module_and_class;
if (!GetModuleAndMessagePath(method->output_type(),
&output_message_module_and_class)) {
return false;
@@ -344,17 +393,20 @@ bool PrintStubFactory(const std::string& package_qualified_service_name,
make_pair(method->name(), output_message_module_and_class));
}
out->Print("method_invocation_descriptions = {\n");
- for (auto& name_and_description_constructor :
- method_description_constructors) {
+ for (auto name_and_description_constructor =
+ method_description_constructors.begin();
+ name_and_description_constructor !=
+ method_description_constructors.end();
+ name_and_description_constructor++) {
IndentScope raii_descriptions_indent(out);
- const std::string method_name = name_and_description_constructor.first;
+ const grpc::string method_name = name_and_description_constructor->first;
auto input_message_module_and_class =
input_message_modules_and_classes.find(method_name);
auto output_message_module_and_class =
output_message_modules_and_classes.find(method_name);
out->Print("\"$Method$\": utilities.$Constructor$(\n", "Method",
method_name, "Constructor",
- name_and_description_constructor.second);
+ name_and_description_constructor->second);
{
IndentScope raii_description_arguments_indent(out);
out->Print(
@@ -370,30 +422,37 @@ bool PrintStubFactory(const std::string& package_qualified_service_name,
}
out->Print("}\n");
out->Print(
- "return implementations.insecure_stub("
+ "return implementations.stub("
"\"$PackageQualifiedServiceName$\","
- " method_invocation_descriptions, host, port)\n",
+ " method_invocation_descriptions, host, port,"
+ " metadata_transformer=metadata_transformer, secure=secure,"
+ " root_certificates=root_certificates, private_key=private_key,"
+ " certificate_chain=certificate_chain,"
+ " server_host_override=server_host_override)\n",
"PackageQualifiedServiceName", package_qualified_service_name);
}
return true;
}
-bool PrintPreamble(const FileDescriptor* file, Printer* out) {
+bool PrintPreamble(const FileDescriptor* file,
+ const GeneratorConfiguration& config, Printer* out) {
out->Print("import abc\n");
- out->Print("from grpc.early_adopter import implementations\n");
+ out->Print("from $Package$ import implementations\n",
+ "Package", config.implementations_package_root);
out->Print("from grpc.framework.alpha import utilities\n");
return true;
}
} // namespace
-pair<bool, std::string> GetServices(const FileDescriptor* file) {
- std::string output;
+pair<bool, grpc::string> GetServices(const FileDescriptor* file,
+ const GeneratorConfiguration& config) {
+ grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
StringOutputStream output_stream(&output);
Printer out(&output_stream, '$');
- if (!PrintPreamble(file, &out)) {
+ if (!PrintPreamble(file, config, &out)) {
return make_pair(false, "");
}
auto package = file->package();
diff --git a/src/compiler/python_generator.h b/src/compiler/python_generator.h
index df29ca17e3..b47f3c1243 100644
--- a/src/compiler/python_generator.h
+++ b/src/compiler/python_generator.h
@@ -34,18 +34,34 @@
#ifndef GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
#define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
-#include <string>
#include <utility>
-namespace google {
-namespace protobuf {
-class FileDescriptor;
-} // namespace protobuf
-} // namespace google
+#include "src/compiler/config.h"
namespace grpc_python_generator {
-std::pair<bool, std::string> GetServices(const google::protobuf::FileDescriptor* file);
+// Data pertaining to configuration of the generator with respect to anything
+// that may be used internally at Google.
+struct GeneratorConfiguration {
+ grpc::string implementations_package_root;
+};
+
+class PythonGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
+ public:
+ PythonGrpcGenerator(const GeneratorConfiguration& config);
+ ~PythonGrpcGenerator();
+
+ bool Generate(const grpc::protobuf::FileDescriptor* file,
+ const grpc::string& parameter,
+ grpc::protobuf::compiler::GeneratorContext* context,
+ grpc::string* error) const;
+ private:
+ GeneratorConfiguration config_;
+};
+
+std::pair<bool, grpc::string> GetServices(
+ const grpc::protobuf::FileDescriptor* file,
+ const GeneratorConfiguration& config);
} // namespace grpc_python_generator
diff --git a/src/compiler/python_plugin.cc b/src/compiler/python_plugin.cc
index e7d172f7bf..d1f49442da 100644
--- a/src/compiler/python_plugin.cc
+++ b/src/compiler/python_plugin.cc
@@ -33,60 +33,12 @@
// Generates a Python gRPC service interface out of Protobuf IDL.
-#include <cstring>
-#include <memory>
-#include <string>
-#include <tuple>
-
+#include "src/compiler/config.h"
#include "src/compiler/python_generator.h"
-#include <google/protobuf/compiler/code_generator.h>
-#include <google/protobuf/compiler/plugin.h>
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream.h>
-#include <google/protobuf/descriptor.h>
-
-using google::protobuf::FileDescriptor;
-using google::protobuf::compiler::CodeGenerator;
-using google::protobuf::compiler::GeneratorContext;
-using google::protobuf::compiler::PluginMain;
-using google::protobuf::io::CodedOutputStream;
-using google::protobuf::io::ZeroCopyOutputStream;
-
-class PythonGrpcGenerator : public CodeGenerator {
- public:
- PythonGrpcGenerator() {}
- ~PythonGrpcGenerator() {}
-
- bool Generate(const FileDescriptor* file, const std::string& parameter,
- GeneratorContext* context, std::string* error) const {
- // Get output file name.
- std::string file_name;
- static const int proto_suffix_length = strlen(".proto");
- if (file->name().size() > static_cast<size_t>(proto_suffix_length) &&
- file->name().find_last_of(".proto") == file->name().size() - 1) {
- file_name = file->name().substr(
- 0, file->name().size() - proto_suffix_length) + "_pb2.py";
- } else {
- *error = "Invalid proto file name. Proto file must end with .proto";
- return false;
- }
-
- std::unique_ptr<ZeroCopyOutputStream> output(
- context->OpenForInsert(file_name, "module_scope"));
- CodedOutputStream coded_out(output.get());
- bool success = false;
- std::string code = "";
- tie(success, code) = grpc_python_generator::GetServices(file);
- if (success) {
- coded_out.WriteRaw(code.data(), code.size());
- return true;
- } else {
- return false;
- }
- }
-};
int main(int argc, char* argv[]) {
- PythonGrpcGenerator generator;
- return PluginMain(argc, argv, &generator);
+ grpc_python_generator::GeneratorConfiguration config;
+ config.implementations_package_root = "grpc.early_adopter";
+ grpc_python_generator::PythonGrpcGenerator generator(config);
+ return grpc::protobuf::compiler::PluginMain(argc, argv, &generator);
}
diff --git a/src/compiler/ruby_generator.cc b/src/compiler/ruby_generator.cc
index 32b6a8d8e4..a0bb92848b 100644
--- a/src/compiler/ruby_generator.cc
+++ b/src/compiler/ruby_generator.cc
@@ -32,24 +32,20 @@
*/
#include <cctype>
-#include <string>
#include <map>
#include <vector>
+#include "src/compiler/config.h"
#include "src/compiler/ruby_generator.h"
#include "src/compiler/ruby_generator_helpers-inl.h"
#include "src/compiler/ruby_generator_map-inl.h"
#include "src/compiler/ruby_generator_string-inl.h"
-#include <google/protobuf/io/printer.h>
-#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/descriptor.h>
-
-using google::protobuf::FileDescriptor;
-using google::protobuf::ServiceDescriptor;
-using google::protobuf::MethodDescriptor;
-using google::protobuf::io::Printer;
-using google::protobuf::io::StringOutputStream;
+
+using grpc::protobuf::FileDescriptor;
+using grpc::protobuf::ServiceDescriptor;
+using grpc::protobuf::MethodDescriptor;
+using grpc::protobuf::io::Printer;
+using grpc::protobuf::io::StringOutputStream;
using std::map;
using std::vector;
@@ -57,38 +53,38 @@ namespace grpc_ruby_generator {
namespace {
// Prints out the method using the ruby gRPC DSL.
-void PrintMethod(const MethodDescriptor *method, const std::string &package,
+void PrintMethod(const MethodDescriptor *method, const grpc::string &package,
Printer *out) {
- std::string input_type = RubyTypeOf(method->input_type()->name(), package);
+ grpc::string input_type = RubyTypeOf(method->input_type()->name(), package);
if (method->client_streaming()) {
input_type = "stream(" + input_type + ")";
}
- std::string output_type = RubyTypeOf(method->output_type()->name(), package);
+ grpc::string output_type = RubyTypeOf(method->output_type()->name(), package);
if (method->server_streaming()) {
output_type = "stream(" + output_type + ")";
}
- std::map<std::string, std::string> method_vars =
+ std::map<grpc::string, grpc::string> method_vars =
ListToDict({"mth.name", method->name(), "input.type", input_type,
"output.type", output_type, });
out->Print(method_vars, "rpc :$mth.name$, $input.type$, $output.type$\n");
}
// Prints out the service using the ruby gRPC DSL.
-void PrintService(const ServiceDescriptor *service, const std::string &package,
+void PrintService(const ServiceDescriptor *service, const grpc::string &package,
Printer *out) {
if (service->method_count() == 0) {
return;
}
// Begin the service module
- std::map<std::string, std::string> module_vars =
+ std::map<grpc::string, grpc::string> module_vars =
ListToDict({"module.name", CapitalizeFirst(service->name()), });
out->Print(module_vars, "module $module.name$\n");
out->Indent();
// TODO(temiola): add documentation
- std::string doc = "TODO: add proto service documentation here";
- std::map<std::string, std::string> template_vars =
+ grpc::string doc = "TODO: add proto service documentation here";
+ std::map<grpc::string, grpc::string> template_vars =
ListToDict({"Documentation", doc, });
out->Print("\n");
out->Print(template_vars, "# $Documentation$\n");
@@ -101,7 +97,7 @@ void PrintService(const ServiceDescriptor *service, const std::string &package,
out->Print("\n");
out->Print("self.marshal_class_method = :encode\n");
out->Print("self.unmarshal_class_method = :decode\n");
- std::map<std::string, std::string> pkg_vars =
+ std::map<grpc::string, grpc::string> pkg_vars =
ListToDict({"service.name", service->name(), "pkg.name", package, });
out->Print(pkg_vars, "self.service_name = '$pkg.name$.$service.name$'\n");
out->Print("\n");
@@ -121,8 +117,8 @@ void PrintService(const ServiceDescriptor *service, const std::string &package,
} // namespace
-std::string GetServices(const FileDescriptor *file) {
- std::string output;
+grpc::string GetServices(const FileDescriptor *file) {
+ grpc::string output;
StringOutputStream output_stream(&output);
Printer out(&output_stream, '$');
@@ -133,7 +129,7 @@ std::string GetServices(const FileDescriptor *file) {
}
// Write out a file header.
- std::map<std::string, std::string> header_comment_vars = ListToDict(
+ std::map<grpc::string, grpc::string> header_comment_vars = ListToDict(
{"file.name", file->name(), "file.package", file->package(), });
out.Print("# Generated by the protocol buffer compiler. DO NOT EDIT!\n");
out.Print(header_comment_vars,
@@ -144,15 +140,15 @@ std::string GetServices(const FileDescriptor *file) {
// Write out require statemment to import the separately generated file
// that defines the messages used by the service. This is generated by the
// main ruby plugin.
- std::map<std::string, std::string> dep_vars =
+ std::map<grpc::string, grpc::string> dep_vars =
ListToDict({"dep.name", MessagesRequireName(file), });
out.Print(dep_vars, "require '$dep.name$'\n");
// Write out services within the modules
out.Print("\n");
- std::vector<std::string> modules = Split(file->package(), '.');
+ std::vector<grpc::string> modules = Split(file->package(), '.');
for (size_t i = 0; i < modules.size(); ++i) {
- std::map<std::string, std::string> module_vars =
+ std::map<grpc::string, grpc::string> module_vars =
ListToDict({"module.name", CapitalizeFirst(modules[i]), });
out.Print(module_vars, "module $module.name$\n");
out.Indent();
diff --git a/src/compiler/ruby_generator.h b/src/compiler/ruby_generator.h
index 4dd38e0c27..a2ab36d4d9 100644
--- a/src/compiler/ruby_generator.h
+++ b/src/compiler/ruby_generator.h
@@ -34,17 +34,11 @@
#ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_H
#define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_H
-#include <string>
-
-namespace google {
-namespace protobuf {
-class FileDescriptor;
-} // namespace protobuf
-} // namespace google
+#include "src/compiler/config.h"
namespace grpc_ruby_generator {
-std::string GetServices(const google::protobuf::FileDescriptor *file);
+grpc::string GetServices(const grpc::protobuf::FileDescriptor *file);
} // namespace grpc_ruby_generator
diff --git a/src/compiler/ruby_generator_helpers-inl.h b/src/compiler/ruby_generator_helpers-inl.h
index f3a087b3f8..9da7cab3c7 100644
--- a/src/compiler/ruby_generator_helpers-inl.h
+++ b/src/compiler/ruby_generator_helpers-inl.h
@@ -34,15 +34,13 @@
#ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_HELPERS_INL_H
#define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_HELPERS_INL_H
-#include <string>
-
-#include <google/protobuf/descriptor.h>
+#include "src/compiler/config.h"
#include "src/compiler/ruby_generator_string-inl.h"
namespace grpc_ruby_generator {
-inline bool ServicesFilename(const google::protobuf::FileDescriptor *file,
- std::string *file_name_or_error) {
+inline bool ServicesFilename(const grpc::protobuf::FileDescriptor *file,
+ grpc::string *file_name_or_error) {
// Get output file name.
static const unsigned proto_suffix_length = 6; // length of ".proto"
if (file->name().size() > proto_suffix_length &&
@@ -57,8 +55,8 @@ inline bool ServicesFilename(const google::protobuf::FileDescriptor *file,
}
}
-inline std::string MessagesRequireName(
- const google::protobuf::FileDescriptor *file) {
+inline grpc::string MessagesRequireName(
+ const grpc::protobuf::FileDescriptor *file) {
return Replace(file->name(), ".proto", "");
}
diff --git a/src/compiler/ruby_generator_map-inl.h b/src/compiler/ruby_generator_map-inl.h
index f902b6d98f..6b87774f21 100644
--- a/src/compiler/ruby_generator_map-inl.h
+++ b/src/compiler/ruby_generator_map-inl.h
@@ -34,11 +34,12 @@
#ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_MAP_INL_H
#define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_MAP_INL_H
+#include "src/compiler/config.h"
+
#include <iostream>
#include <initializer_list>
#include <map>
#include <ostream> // NOLINT
-#include <string>
#include <vector>
using std::initializer_list;
@@ -49,18 +50,18 @@ namespace grpc_ruby_generator {
// Converts an initializer list of the form { key0, value0, key1, value1, ... }
// into a map of key* to value*. Is merely a readability helper for later code.
-inline std::map<std::string, std::string> ListToDict(
- const initializer_list<std::string> &values) {
+inline std::map<grpc::string, grpc::string> ListToDict(
+ const initializer_list<grpc::string> &values) {
if (values.size() % 2 != 0) {
std::cerr << "Not every 'key' has a value in `values`."
<< std::endl;
}
- std::map<std::string, std::string> value_map;
+ std::map<grpc::string, grpc::string> value_map;
auto value_iter = values.begin();
for (unsigned i = 0; i < values.size() / 2; ++i) {
- std::string key = *value_iter;
+ grpc::string key = *value_iter;
++value_iter;
- std::string value = *value_iter;
+ grpc::string value = *value_iter;
value_map[key] = value;
++value_iter;
}
diff --git a/src/compiler/ruby_generator_string-inl.h b/src/compiler/ruby_generator_string-inl.h
index bdd314c16e..8da3a88da2 100644
--- a/src/compiler/ruby_generator_string-inl.h
+++ b/src/compiler/ruby_generator_string-inl.h
@@ -34,8 +34,9 @@
#ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_STRING_INL_H
#define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_STRING_INL_H
+#include "src/compiler/config.h"
+
#include <algorithm>
-#include <string>
#include <sstream>
#include <vector>
@@ -45,10 +46,10 @@ using std::transform;
namespace grpc_ruby_generator {
// Split splits a string using char into elems.
-inline std::vector<std::string> &Split(const std::string &s, char delim,
- std::vector<std::string> *elems) {
+inline std::vector<grpc::string> &Split(const grpc::string &s, char delim,
+ std::vector<grpc::string> *elems) {
std::stringstream ss(s);
- std::string item;
+ grpc::string item;
while (getline(ss, item, delim)) {
elems->push_back(item);
}
@@ -56,17 +57,17 @@ inline std::vector<std::string> &Split(const std::string &s, char delim,
}
// Split splits a string using char, returning the result in a vector.
-inline std::vector<std::string> Split(const std::string &s, char delim) {
- std::vector<std::string> elems;
+inline std::vector<grpc::string> Split(const grpc::string &s, char delim) {
+ std::vector<grpc::string> elems;
Split(s, delim, &elems);
return elems;
}
// Replace replaces from with to in s.
-inline std::string Replace(std::string s, const std::string &from,
- const std::string &to) {
+inline grpc::string Replace(grpc::string s, const grpc::string &from,
+ const grpc::string &to) {
size_t start_pos = s.find(from);
- if (start_pos == std::string::npos) {
+ if (start_pos == grpc::string::npos) {
return s;
}
s.replace(start_pos, from.length(), to);
@@ -74,10 +75,10 @@ inline std::string Replace(std::string s, const std::string &from,
}
// ReplaceAll replaces all instances of search with replace in s.
-inline std::string ReplaceAll(std::string s, const std::string &search,
- const std::string &replace) {
+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)) != std::string::npos) {
+ while ((pos = s.find(search, pos)) != grpc::string::npos) {
s.replace(pos, search.length(), replace);
pos += replace.length();
}
@@ -85,10 +86,10 @@ inline std::string ReplaceAll(std::string s, const std::string &search,
}
// ReplacePrefix replaces from with to in s if search is a prefix of s.
-inline bool ReplacePrefix(std::string *s, const std::string &from,
- const std::string &to) {
+inline bool ReplacePrefix(grpc::string *s, const grpc::string &from,
+ const grpc::string &to) {
size_t start_pos = s->find(from);
- if (start_pos == std::string::npos || start_pos != 0) {
+ if (start_pos == grpc::string::npos || start_pos != 0) {
return false;
}
s->replace(start_pos, from.length(), to);
@@ -96,7 +97,7 @@ inline bool ReplacePrefix(std::string *s, const std::string &from,
}
// CapitalizeFirst capitalizes the first char in a string.
-inline std::string CapitalizeFirst(std::string s) {
+inline grpc::string CapitalizeFirst(grpc::string s) {
if (s.empty()) {
return s;
}
@@ -105,15 +106,15 @@ inline std::string CapitalizeFirst(std::string s) {
}
// RubyTypeOf updates a proto type to the required ruby equivalent.
-inline std::string RubyTypeOf(const std::string &a_type,
- const std::string &package) {
- std::string res(a_type);
+inline grpc::string RubyTypeOf(const grpc::string &a_type,
+ const grpc::string &package) {
+ grpc::string res(a_type);
ReplacePrefix(&res, package, ""); // remove the leading package if present
ReplacePrefix(&res, ".", ""); // remove the leading . (no package)
- if (res.find('.') == std::string::npos) {
+ if (res.find('.') == grpc::string::npos) {
return res;
} else {
- std::vector<std::string> prefixes_and_type = Split(res, '.');
+ std::vector<grpc::string> prefixes_and_type = Split(res, '.');
for (unsigned int i = 0; i < prefixes_and_type.size(); ++i) {
if (i != 0) {
res += "::"; // switch '.' to the ruby module delim
diff --git a/src/compiler/ruby_plugin.cc b/src/compiler/ruby_plugin.cc
index 4a6e9f7a5d..bd10d46e9c 100644
--- a/src/compiler/ruby_plugin.cc
+++ b/src/compiler/ruby_plugin.cc
@@ -32,43 +32,35 @@
*/
// Generates Ruby gRPC service interface out of Protobuf IDL.
-//
-// This is a Proto2 compiler plugin. See net/proto2/compiler/proto/plugin.proto
-// and net/proto2/compiler/public/plugin.h for more information on plugins.
#include <memory>
-#include <string>
+#include "src/compiler/config.h"
#include "src/compiler/ruby_generator.h"
#include "src/compiler/ruby_generator_helpers-inl.h"
-#include <google/protobuf/compiler/code_generator.h>
-#include <google/protobuf/compiler/plugin.h>
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream.h>
-#include <google/protobuf/descriptor.h>
-class RubyGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
+class RubyGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
public:
RubyGrpcGenerator() {}
~RubyGrpcGenerator() {}
- bool Generate(const google::protobuf::FileDescriptor *file,
- const std::string &parameter,
- google::protobuf::compiler::GeneratorContext *context,
- std::string *error) const {
- std::string code = grpc_ruby_generator::GetServices(file);
+ bool Generate(const grpc::protobuf::FileDescriptor *file,
+ const grpc::string &parameter,
+ grpc::protobuf::compiler::GeneratorContext *context,
+ grpc::string *error) const {
+ grpc::string code = grpc_ruby_generator::GetServices(file);
if (code.size() == 0) {
return true; // don't generate a file if there are no services
}
// Get output file name.
- std::string file_name;
+ grpc::string file_name;
if (!grpc_ruby_generator::ServicesFilename(file, &file_name)) {
return false;
}
- std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
+ std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
context->Open(file_name));
- google::protobuf::io::CodedOutputStream coded_out(output.get());
+ grpc::protobuf::io::CodedOutputStream coded_out(output.get());
coded_out.WriteRaw(code.data(), code.size());
return true;
}
@@ -76,5 +68,5 @@ class RubyGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
int main(int argc, char *argv[]) {
RubyGrpcGenerator generator;
- return google::protobuf::compiler::PluginMain(argc, argv, &generator);
+ return grpc::protobuf::compiler::PluginMain(argc, argv, &generator);
}
diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c
index f565cbf3ae..9da8b333ca 100644
--- a/src/core/channel/http_server_filter.c
+++ b/src/core/channel/http_server_filter.c
@@ -189,7 +189,8 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
/* translate host to :authority since :authority may be
omitted */
grpc_mdelem *authority = grpc_mdelem_from_metadata_strings(
- channeld->mdctx, channeld->authority_key, op->data.metadata->value);
+ channeld->mdctx, grpc_mdstr_ref(channeld->authority_key),
+ grpc_mdstr_ref(op->data.metadata->value));
grpc_mdelem_unref(op->data.metadata);
op->data.metadata = authority;
/* pass the event up */
diff --git a/src/core/httpcli/parser.c b/src/core/httpcli/parser.c
index f4decda98a..7b2a62060c 100644
--- a/src/core/httpcli/parser.c
+++ b/src/core/httpcli/parser.c
@@ -177,6 +177,8 @@ static int addbyte(grpc_httpcli_parser *parser, gpr_uint8 byte) {
}
gpr_log(GPR_ERROR, "should never reach here");
abort();
+
+ return 0;
}
void grpc_httpcli_parser_init(grpc_httpcli_parser *parser) {
diff --git a/src/core/iomgr/iocp_windows.c b/src/core/iomgr/iocp_windows.c
index 8b019e8049..aec626509a 100644
--- a/src/core/iomgr/iocp_windows.c
+++ b/src/core/iomgr/iocp_windows.c
@@ -52,10 +52,11 @@ static OVERLAPPED g_iocp_custom_overlap;
static gpr_event g_shutdown_iocp;
static gpr_event g_iocp_done;
+static gpr_atm g_orphans = 0;
static HANDLE g_iocp;
-static int do_iocp_work() {
+static void do_iocp_work() {
BOOL success;
DWORD bytes = 0;
DWORD flags = 0;
@@ -71,14 +72,14 @@ static int do_iocp_work() {
gpr_time_to_millis(wait_time));
if (!success && !overlapped) {
/* The deadline got attained. */
- return 0;
+ return;
}
GPR_ASSERT(completion_key && overlapped);
if (overlapped == &g_iocp_custom_overlap) {
if (completion_key == (ULONG_PTR) &g_iocp_kick_token) {
/* We were awoken from a kick. */
gpr_log(GPR_DEBUG, "do_iocp_work - got a kick");
- return 1;
+ return;
}
gpr_log(GPR_ERROR, "Unknown custom completion key.");
abort();
@@ -97,8 +98,13 @@ static int do_iocp_work() {
}
success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes,
FALSE, &flags);
- gpr_log(GPR_DEBUG, "bytes: %u, flags: %u - op %s", bytes, flags,
- success ? "succeeded" : "failed");
+ gpr_log(GPR_DEBUG, "bytes: %u, flags: %u - op %s %s", bytes, flags,
+ success ? "succeeded" : "failed", socket->orphan ? "orphan" : "");
+ if (socket->orphan) {
+ grpc_winsocket_destroy(socket);
+ gpr_atm_full_fetch_add(&g_orphans, -1);
+ return;
+ }
info->bytes_transfered = bytes;
info->wsa_error = success ? 0 : WSAGetLastError();
GPR_ASSERT(overlapped == &info->overlapped);
@@ -113,12 +119,10 @@ static int do_iocp_work() {
}
gpr_mu_unlock(&socket->state_mu);
if (f) f(opaque, 1);
-
- return 1;
}
static void iocp_loop(void *p) {
- while (!gpr_event_get(&g_shutdown_iocp)) {
+ while (gpr_atm_acq_load(&g_orphans) || !gpr_event_get(&g_shutdown_iocp)) {
grpc_maybe_call_delayed_callbacks(NULL, 1);
do_iocp_work();
}
@@ -138,13 +142,19 @@ void grpc_iocp_init(void) {
gpr_thd_new(&id, iocp_loop, NULL, NULL);
}
-void grpc_iocp_shutdown(void) {
+void grpc_iocp_kick(void) {
BOOL success;
- gpr_event_set(&g_shutdown_iocp, (void *)1);
+
success = PostQueuedCompletionStatus(g_iocp, 0,
(ULONG_PTR) &g_iocp_kick_token,
&g_iocp_custom_overlap);
GPR_ASSERT(success);
+}
+
+void grpc_iocp_shutdown(void) {
+ BOOL success;
+ gpr_event_set(&g_shutdown_iocp, (void *)1);
+ grpc_iocp_kick();
gpr_event_wait(&g_iocp_done, gpr_inf_future);
success = CloseHandle(g_iocp);
GPR_ASSERT(success);
@@ -166,6 +176,10 @@ void grpc_iocp_add_socket(grpc_winsocket *socket) {
GPR_ASSERT(ret == g_iocp);
}
+void grpc_iocp_socket_orphan(grpc_winsocket *socket) {
+ gpr_atm_full_fetch_add(&g_orphans, 1);
+}
+
static void socket_notify_on_iocp(grpc_winsocket *socket,
void(*cb)(void *, int), void *opaque,
grpc_winsocket_callback_info *info) {
diff --git a/src/core/iomgr/iocp_windows.h b/src/core/iomgr/iocp_windows.h
index 33133193a1..fa3f5eee10 100644
--- a/src/core/iomgr/iocp_windows.h
+++ b/src/core/iomgr/iocp_windows.h
@@ -42,6 +42,7 @@
void grpc_iocp_init(void);
void grpc_iocp_shutdown(void);
void grpc_iocp_add_socket(grpc_winsocket *);
+void grpc_iocp_socket_orphan(grpc_winsocket *);
void grpc_socket_notify_on_write(grpc_winsocket *, void(*cb)(void *, int success),
void *opaque);
diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c
index 058685b295..d0e6706fbd 100644
--- a/src/core/iomgr/iomgr.c
+++ b/src/core/iomgr/iomgr.c
@@ -117,7 +117,16 @@ void grpc_iomgr_shutdown(void) {
gpr_mu_lock(&g_mu);
}
if (g_refs) {
- if (gpr_cv_wait(&g_rcv, &g_mu, shutdown_deadline) && g_cbs_head == NULL) {
+ int timeout = 0;
+ gpr_timespec short_deadline = gpr_time_add(gpr_now(),
+ gpr_time_from_millis(100));
+ while (gpr_cv_wait(&g_rcv, &g_mu, short_deadline) && g_cbs_head == NULL) {
+ if (gpr_time_cmp(gpr_now(), shutdown_deadline) > 0) {
+ timeout = 1;
+ break;
+ }
+ }
+ if (timeout) {
gpr_log(GPR_DEBUG,
"Failed to free %d iomgr objects before shutdown deadline: "
"memory leaks are likely",
diff --git a/src/core/iomgr/socket_windows.c b/src/core/iomgr/socket_windows.c
index 99f38b0e03..22dad41783 100644
--- a/src/core/iomgr/socket_windows.c
+++ b/src/core/iomgr/socket_windows.c
@@ -55,7 +55,7 @@ grpc_winsocket *grpc_winsocket_create(SOCKET socket) {
return r;
}
-void shutdown_op(grpc_winsocket_callback_info *info) {
+static void shutdown_op(grpc_winsocket_callback_info *info) {
if (!info->cb) return;
grpc_iomgr_add_delayed_callback(info->cb, info->opaque, 0);
}
@@ -68,8 +68,13 @@ void grpc_winsocket_shutdown(grpc_winsocket *socket) {
void grpc_winsocket_orphan(grpc_winsocket *socket) {
gpr_log(GPR_DEBUG, "grpc_winsocket_orphan");
+ grpc_iocp_socket_orphan(socket);
+ socket->orphan = 1;
grpc_iomgr_unref();
closesocket(socket->socket);
+}
+
+void grpc_winsocket_destroy(grpc_winsocket *socket) {
gpr_mu_destroy(&socket->state_mu);
gpr_free(socket);
}
diff --git a/src/core/iomgr/socket_windows.h b/src/core/iomgr/socket_windows.h
index d4776ab10f..cbae91692c 100644
--- a/src/core/iomgr/socket_windows.h
+++ b/src/core/iomgr/socket_windows.h
@@ -57,12 +57,13 @@ typedef struct grpc_winsocket_callback_info {
typedef struct grpc_winsocket {
SOCKET socket;
- int added_to_iocp;
-
grpc_winsocket_callback_info write_info;
grpc_winsocket_callback_info read_info;
gpr_mu state_mu;
+
+ int added_to_iocp;
+ int orphan;
} grpc_winsocket;
/* Create a wrapped windows handle.
@@ -71,5 +72,6 @@ grpc_winsocket *grpc_winsocket_create(SOCKET socket);
void grpc_winsocket_shutdown(grpc_winsocket *socket);
void grpc_winsocket_orphan(grpc_winsocket *socket);
+void grpc_winsocket_destroy(grpc_winsocket *socket);
#endif /* GRPC_INTERNAL_CORE_IOMGR_SOCKET_WINDOWS_H */
diff --git a/src/core/iomgr/tcp_server.h b/src/core/iomgr/tcp_server.h
index 68ee85c5a7..66bb3ef701 100644
--- a/src/core/iomgr/tcp_server.h
+++ b/src/core/iomgr/tcp_server.h
@@ -71,6 +71,8 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
up when grpc_tcp_server_destroy is called. */
int grpc_tcp_server_get_fd(grpc_tcp_server *s, unsigned index);
-void grpc_tcp_server_destroy(grpc_tcp_server *server);
+void grpc_tcp_server_destroy(grpc_tcp_server *server,
+ void (*shutdown_done)(void *shutdown_done_arg),
+ void *shutdown_done_arg);
-#endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H */
+#endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H */
diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c
index 90b7eb451d..895f85fc68 100644
--- a/src/core/iomgr/tcp_server_posix.c
+++ b/src/core/iomgr/tcp_server_posix.c
@@ -102,12 +102,18 @@ struct grpc_tcp_server {
gpr_cv cv;
/* active port count: how many ports are actually still listening */
- int active_ports;
+ size_t active_ports;
+ /* destroyed port count: how many ports are completely destroyed */
+ size_t destroyed_ports;
/* all listening ports */
server_port *ports;
size_t nports;
size_t port_capacity;
+
+ /* shutdown callback */
+ void (*shutdown_complete)(void *);
+ void *shutdown_complete_arg;
};
grpc_tcp_server *grpc_tcp_server_create(void) {
@@ -115,6 +121,7 @@ grpc_tcp_server *grpc_tcp_server_create(void) {
gpr_mu_init(&s->mu);
gpr_cv_init(&s->cv);
s->active_ports = 0;
+ s->destroyed_ports = 0;
s->cb = NULL;
s->cb_arg = NULL;
s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP);
@@ -123,29 +130,64 @@ grpc_tcp_server *grpc_tcp_server_create(void) {
return s;
}
-void grpc_tcp_server_destroy(grpc_tcp_server *s) {
+static void finish_shutdown(grpc_tcp_server *s) {
+ s->shutdown_complete(s->shutdown_complete_arg);
+
+ gpr_mu_destroy(&s->mu);
+ gpr_cv_destroy(&s->cv);
+
+ gpr_free(s->ports);
+ gpr_free(s);
+}
+
+static void destroyed_port(void *server, int success) {
+ grpc_tcp_server *s = server;
+ gpr_mu_lock(&s->mu);
+ s->destroyed_ports++;
+ if (s->destroyed_ports == s->nports) {
+ gpr_mu_unlock(&s->mu);
+ finish_shutdown(s);
+ } else {
+ gpr_mu_unlock(&s->mu);
+ }
+}
+
+static void dont_care_about_shutdown_completion(void *ignored) {}
+
+void grpc_tcp_server_destroy(
+ grpc_tcp_server *s, void (*shutdown_complete)(void *shutdown_complete_arg),
+ void *shutdown_complete_arg) {
size_t i;
gpr_mu_lock(&s->mu);
+
+ s->shutdown_complete = shutdown_complete
+ ? shutdown_complete
+ : dont_care_about_shutdown_completion;
+ s->shutdown_complete_arg = shutdown_complete_arg;
+
/* shutdown all fd's */
for (i = 0; i < s->nports; i++) {
grpc_fd_shutdown(s->ports[i].emfd);
}
/* wait while that happens */
+ /* TODO(ctiller): make this asynchronous also */
while (s->active_ports) {
gpr_cv_wait(&s->cv, &s->mu, gpr_inf_future);
}
gpr_mu_unlock(&s->mu);
/* delete ALL the things */
- for (i = 0; i < s->nports; i++) {
- server_port *sp = &s->ports[i];
- if (sp->addr.sockaddr.sa_family == AF_UNIX) {
- unlink_if_unix_domain_socket(&sp->addr.un);
+ if (s->nports) {
+ for (i = 0; i < s->nports; i++) {
+ server_port *sp = &s->ports[i];
+ if (sp->addr.sockaddr.sa_family == AF_UNIX) {
+ unlink_if_unix_domain_socket(&sp->addr.un);
+ }
+ grpc_fd_orphan(sp->emfd, destroyed_port, s);
}
- grpc_fd_orphan(sp->emfd, NULL, NULL);
+ } else {
+ finish_shutdown(s);
}
- gpr_free(s->ports);
- gpr_free(s);
}
/* get max listen queue size on linux */
diff --git a/src/core/iomgr/tcp_server_windows.c b/src/core/iomgr/tcp_server_windows.c
index 0c3ab1dc91..a43d5670a4 100644
--- a/src/core/iomgr/tcp_server_windows.c
+++ b/src/core/iomgr/tcp_server_windows.c
@@ -92,7 +92,9 @@ grpc_tcp_server *grpc_tcp_server_create(void) {
return s;
}
-void grpc_tcp_server_destroy(grpc_tcp_server *s) {
+void grpc_tcp_server_destroy(grpc_tcp_server *s,
+ void (*shutdown_done)(void *shutdown_done_arg),
+ void *shutdown_done_arg) {
size_t i;
gpr_mu_lock(&s->mu);
/* shutdown all fd's */
@@ -112,11 +114,15 @@ void grpc_tcp_server_destroy(grpc_tcp_server *s) {
}
gpr_free(s->ports);
gpr_free(s);
+
+ if (shutdown_done) {
+ shutdown_done(shutdown_done_arg);
+ }
}
/* Prepare a recently-created socket for listening. */
-static int prepare_socket(SOCKET sock,
- const struct sockaddr *addr, int addr_len) {
+static int prepare_socket(SOCKET sock, const struct sockaddr *addr,
+ int addr_len) {
struct sockaddr_storage sockname_temp;
socklen_t sockname_len;
@@ -147,15 +153,15 @@ static int prepare_socket(SOCKET sock,
}
sockname_len = sizeof(sockname_temp);
- if (getsockname(sock, (struct sockaddr *) &sockname_temp, &sockname_len)
- == SOCKET_ERROR) {
+ if (getsockname(sock, (struct sockaddr *)&sockname_temp, &sockname_len) ==
+ SOCKET_ERROR) {
char *utf8_message = gpr_format_message(WSAGetLastError());
gpr_log(GPR_ERROR, "getsockname: %s", utf8_message);
gpr_free(utf8_message);
goto error;
}
- return grpc_sockaddr_get_port((struct sockaddr *) &sockname_temp);
+ return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
error:
if (sock != INVALID_SOCKET) closesocket(sock);
@@ -221,8 +227,7 @@ static void on_accept(void *arg, int success) {
DWORD transfered_bytes = 0;
DWORD flags;
BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped,
- &transfered_bytes, FALSE,
- &flags);
+ &transfered_bytes, FALSE, &flags);
if (!wsa_success) {
char *utf8_message = gpr_format_message(WSAGetLastError());
gpr_log(GPR_ERROR, "on_accept error: %s", utf8_message);
@@ -257,9 +262,9 @@ static int add_socket_to_server(grpc_tcp_server *s, SOCKET sock,
if (sock == INVALID_SOCKET) return -1;
- status = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
- &guid, sizeof(guid), &AcceptEx, sizeof(AcceptEx),
- &ioctl_num_bytes, NULL, NULL);
+ status =
+ WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid),
+ &AcceptEx, sizeof(AcceptEx), &ioctl_num_bytes, NULL, NULL);
if (status != 0) {
char *utf8_message = gpr_format_message(WSAGetLastError());
@@ -307,9 +312,8 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
for (i = 0; i < s->nports; i++) {
sockname_len = sizeof(sockname_temp);
if (0 == getsockname(s->ports[i].socket->socket,
- (struct sockaddr *) &sockname_temp,
- &sockname_len)) {
- port = grpc_sockaddr_get_port((struct sockaddr *) &sockname_temp);
+ (struct sockaddr *)&sockname_temp, &sockname_len)) {
+ port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
if (port > 0) {
allocated_addr = malloc(addr_len);
memcpy(allocated_addr, addr, addr_len);
@@ -330,7 +334,7 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
if (grpc_sockaddr_is_wildcard(addr, &port)) {
grpc_sockaddr_make_wildcard6(port, &wildcard);
- addr = (struct sockaddr *) &wildcard;
+ addr = (struct sockaddr *)&wildcard;
addr_len = sizeof(wildcard);
}
@@ -369,4 +373,4 @@ void grpc_tcp_server_start(grpc_tcp_server *s, grpc_pollset **pollset,
gpr_mu_unlock(&s->mu);
}
-#endif /* GPR_WINSOCK_SOCKET */
+#endif /* GPR_WINSOCK_SOCKET */
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index c155b80b7e..081272724c 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -85,10 +85,10 @@ static void on_secure_transport_setup_done(void *statep,
if (status == GRPC_SECURITY_OK) {
gpr_mu_lock(&state->mu);
if (!state->is_shutdown) {
- grpc_create_chttp2_transport(
- setup_transport, state->server,
- grpc_server_get_channel_args(state->server),
- secure_endpoint, NULL, 0, grpc_mdctx_create(), 0);
+ grpc_create_chttp2_transport(setup_transport, state->server,
+ grpc_server_get_channel_args(state->server),
+ secure_endpoint, NULL, 0,
+ grpc_mdctx_create(), 0);
} else {
/* We need to consume this here, because the server may already have gone
* away. */
@@ -104,7 +104,8 @@ static void on_secure_transport_setup_done(void *statep,
static void on_accept(void *statep, grpc_endpoint *tcp) {
grpc_server_secure_state *state = statep;
state_ref(state);
- grpc_setup_secure_transport(state->ctx, tcp, on_secure_transport_setup_done, state);
+ grpc_setup_secure_transport(state->ctx, tcp, on_secure_transport_setup_done,
+ state);
}
/* Server callback: start listening on our ports */
@@ -120,12 +121,14 @@ static void destroy(grpc_server *server, void *statep) {
grpc_server_secure_state *state = statep;
gpr_mu_lock(&state->mu);
state->is_shutdown = 1;
- grpc_tcp_server_destroy(state->tcp);
+ grpc_tcp_server_destroy(state->tcp, grpc_server_listener_destroy_done,
+ server);
gpr_mu_unlock(&state->mu);
state_unref(state);
}
-int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, grpc_server_credentials *creds) {
+int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
+ grpc_server_credentials *creds) {
grpc_resolved_addresses *resolved = NULL;
grpc_tcp_server *tcp = NULL;
grpc_server_secure_state *state = NULL;
@@ -213,7 +216,7 @@ error:
grpc_resolved_addresses_destroy(resolved);
}
if (tcp) {
- grpc_tcp_server_destroy(tcp);
+ grpc_tcp_server_destroy(tcp, NULL, NULL);
}
if (state) {
gpr_free(state);
diff --git a/src/core/support/thd.c b/src/core/support/thd.c
new file mode 100644
index 0000000000..ec308f3119
--- /dev/null
+++ b/src/core/support/thd.c
@@ -0,0 +1,66 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Posix implementation for gpr threads. */
+
+#include <memory.h>
+
+#include <grpc/support/thd.h>
+
+enum {
+ GPR_THD_JOINABLE = 1
+};
+
+gpr_thd_options gpr_thd_options_default(void) {
+ gpr_thd_options options;
+ memset(&options, 0, sizeof(options));
+ return options;
+}
+
+void gpr_thd_options_set_detached(gpr_thd_options *options) {
+ options->flags &= ~GPR_THD_JOINABLE;
+}
+
+void gpr_thd_options_set_joinable(gpr_thd_options *options) {
+ options->flags |= GPR_THD_JOINABLE;
+}
+
+int gpr_thd_options_is_detached(const gpr_thd_options *options) {
+ if (!options) return 1;
+ return (options->flags & GPR_THD_JOINABLE) == 0;
+}
+
+int gpr_thd_options_is_joinable(const gpr_thd_options *options) {
+ if (!options) return 0;
+ return (options->flags & GPR_THD_JOINABLE) == GPR_THD_JOINABLE;
+}
diff --git a/src/core/support/thd_posix.c b/src/core/support/thd_posix.c
index f50ea58335..fa4eb50556 100644
--- a/src/core/support/thd_posix.c
+++ b/src/core/support/thd_posix.c
@@ -68,7 +68,11 @@ int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg,
a->arg = arg;
GPR_ASSERT(pthread_attr_init(&attr) == 0);
- GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0);
+ if (gpr_thd_options_is_detached(options)) {
+ GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0);
+ } else {
+ GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == 0);
+ }
thread_started = (pthread_create(&p, &attr, &thread_body, a) == 0);
GPR_ASSERT(pthread_attr_destroy(&attr) == 0);
if (!thread_started) {
@@ -78,14 +82,12 @@ int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg,
return thread_started;
}
-gpr_thd_options gpr_thd_options_default(void) {
- gpr_thd_options options;
- memset(&options, 0, sizeof(options));
- return options;
-}
-
gpr_thd_id gpr_thd_currentid(void) {
return (gpr_thd_id)pthread_self();
}
+void gpr_thd_join(gpr_thd_id t) {
+ pthread_join((pthread_t)t, NULL);
+}
+
#endif /* GPR_POSIX_SYNC */
diff --git a/src/core/support/thd_win32.c b/src/core/support/thd_win32.c
index 347cad57e3..3cc798293a 100644
--- a/src/core/support/thd_win32.c
+++ b/src/core/support/thd_win32.c
@@ -31,7 +31,7 @@
*
*/
-/* Posix implementation for gpr threads. */
+/* Windows implementation for gpr threads. */
#include <grpc/support/port_platform.h>
@@ -40,47 +40,81 @@
#include <windows.h>
#include <string.h>
#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
#include <grpc/support/thd.h>
-struct thd_arg {
+#if defined(_MSC_VER)
+#define thread_local __declspec(thread)
+#elif defined(__GNUC__)
+#define thread_local __thread
+#else
+#error "Unknown compiler - please file a bug report"
+#endif
+
+struct thd_info {
void (*body)(void *arg); /* body of a thread */
void *arg; /* argument to a thread */
+ HANDLE join_event; /* if joinable, the join event */
+ int joinable; /* true if not detached */
};
+static thread_local struct thd_info *g_thd_info;
+
+/* Destroys a thread info */
+static void destroy_thread(struct thd_info *t) {
+ if (t->joinable) CloseHandle(t->join_event);
+ gpr_free(t);
+}
+
/* Body of every thread started via gpr_thd_new. */
static DWORD WINAPI thread_body(void *v) {
- struct thd_arg a = *(struct thd_arg *)v;
- gpr_free(v);
- (*a.body)(a.arg);
+ g_thd_info = (struct thd_info *)v;
+ g_thd_info->body(g_thd_info->arg);
+ if (g_thd_info->joinable) {
+ BOOL ret = SetEvent(g_thd_info->join_event);
+ GPR_ASSERT(ret);
+ } else {
+ destroy_thread(g_thd_info);
+ }
return 0;
}
int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg,
const gpr_thd_options *options) {
HANDLE handle;
- DWORD thread_id;
- struct thd_arg *a = gpr_malloc(sizeof(*a));
- a->body = thd_body;
- a->arg = arg;
+ struct thd_info *info = gpr_malloc(sizeof(*info));
+ info->body = thd_body;
+ info->arg = arg;
*t = 0;
- handle = CreateThread(NULL, 64 * 1024, thread_body, a, 0, &thread_id);
+ if (gpr_thd_options_is_joinable(options)) {
+ info->joinable = 1;
+ info->join_event = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (info->join_event == NULL) {
+ gpr_free(info);
+ return 0;
+ }
+ } else {
+ info->joinable = 0;
+ }
+ handle = CreateThread(NULL, 64 * 1024, thread_body, info, 0, NULL);
if (handle == NULL) {
- gpr_free(a);
+ destroy_thread(info);
} else {
- CloseHandle(handle); /* threads are "detached" */
+ *t = (gpr_thd_id)info;
+ CloseHandle(handle);
}
- *t = (gpr_thd_id)thread_id;
return handle != NULL;
}
-gpr_thd_options gpr_thd_options_default(void) {
- gpr_thd_options options;
- memset(&options, 0, sizeof(options));
- return options;
+gpr_thd_id gpr_thd_currentid(void) {
+ return (gpr_thd_id)g_thd_info;
}
-gpr_thd_id gpr_thd_currentid(void) {
- return (gpr_thd_id)GetCurrentThreadId();
+void gpr_thd_join(gpr_thd_id t) {
+ struct thd_info *info = (struct thd_info *)t;
+ DWORD ret = WaitForSingleObject(info->join_event, INFINITE);
+ GPR_ASSERT(ret == WAIT_OBJECT_0);
+ destroy_thread(info);
}
#endif /* GPR_WIN32 */
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index cfce943794..dba63058b8 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -1006,6 +1006,8 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
const grpc_op *op;
grpc_ioreq *req;
+ GRPC_CALL_LOG_BATCH(GPR_INFO, call, ops, nops, tag);
+
if (nops == 0) {
grpc_cq_begin_op(call->cq, call, GRPC_OP_COMPLETE);
grpc_cq_end_op_complete(call->cq, tag, call, do_nothing, NULL, GRPC_OP_OK);
diff --git a/src/core/surface/call.h b/src/core/surface/call.h
index cb81cb52c2..06434f87ac 100644
--- a/src/core/surface/call.h
+++ b/src/core/surface/call.h
@@ -119,4 +119,13 @@ grpc_call_stack *grpc_call_get_call_stack(grpc_call *call);
/* Given the top call_element, get the call object. */
grpc_call *grpc_call_from_top_element(grpc_call_element *surface_element);
+extern int grpc_trace_batch;
+
+void grpc_call_log_batch(char *file, int line, gpr_log_severity severity,
+ grpc_call *call, const grpc_op *ops, size_t nops,
+ void *tag);
+
+#define GRPC_CALL_LOG_BATCH(sev, call, ops, nops, tag) \
+ if (grpc_trace_batch) grpc_call_log_batch(sev, call, ops, nops, tag)
+
#endif /* GRPC_INTERNAL_CORE_SURFACE_CALL_H */
diff --git a/src/core/surface/call_log_batch.c b/src/core/surface/call_log_batch.c
new file mode 100644
index 0000000000..a33583a12d
--- /dev/null
+++ b/src/core/surface/call_log_batch.c
@@ -0,0 +1,121 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/surface/call.h"
+
+#include "src/core/support/string.h"
+#include <grpc/support/alloc.h>
+
+int grpc_trace_batch = 0;
+
+static void add_metadata(gpr_strvec *b, const grpc_metadata *md, size_t count) {
+ size_t i;
+ for(i = 0; i < count; i++) {
+ gpr_strvec_add(b, gpr_strdup("\nkey="));
+ gpr_strvec_add(b, gpr_strdup(md[i].key));
+
+ gpr_strvec_add(b, gpr_strdup(" value="));
+ gpr_strvec_add(b, gpr_hexdump(md[i].value, md[i].value_length,
+ GPR_HEXDUMP_PLAINTEXT));
+ }
+}
+
+char *grpc_op_string(const grpc_op *op) {
+ char *tmp;
+ char *out;
+
+ gpr_strvec b;
+ gpr_strvec_init(&b);
+
+ switch (op->op) {
+ case GRPC_OP_SEND_INITIAL_METADATA:
+ gpr_strvec_add(&b, gpr_strdup("SEND_INITIAL_METADATA"));
+ add_metadata(&b, op->data.send_initial_metadata.metadata,
+ op->data.send_initial_metadata.count);
+ break;
+ case GRPC_OP_SEND_MESSAGE:
+ gpr_asprintf(&tmp, "SEND_MESSAGE ptr=%p", op->data.send_message);
+ gpr_strvec_add(&b, tmp);
+ break;
+ case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
+ gpr_strvec_add(&b, gpr_strdup("SEND_CLOSE_FROM_CLIENT"));
+ break;
+ case GRPC_OP_SEND_STATUS_FROM_SERVER:
+ gpr_asprintf(&tmp, "SEND_STATUS_FROM_SERVER status=%d details=%s",
+ op->data.send_status_from_server.status,
+ op->data.send_status_from_server.status_details);
+ gpr_strvec_add(&b, tmp);
+ add_metadata(&b, op->data.send_status_from_server.trailing_metadata,
+ op->data.send_status_from_server.trailing_metadata_count);
+ break;
+ case GRPC_OP_RECV_INITIAL_METADATA:
+ gpr_asprintf(&tmp, "RECV_INITIAL_METADATA ptr=%p",
+ op->data.recv_initial_metadata);
+ gpr_strvec_add(&b, tmp);
+ break;
+ case GRPC_OP_RECV_MESSAGE:
+ gpr_asprintf(&tmp, "RECV_MESSAGE ptr=%p", op->data.recv_message);
+ gpr_strvec_add(&b, tmp);
+ break;
+ case GRPC_OP_RECV_STATUS_ON_CLIENT:
+ gpr_asprintf(&tmp,
+ "RECV_STATUS_ON_CLIENT metadata=%p status=%p details=%p",
+ op->data.recv_status_on_client.trailing_metadata,
+ op->data.recv_status_on_client.status,
+ op->data.recv_status_on_client.status_details);
+ gpr_strvec_add(&b, tmp);
+ break;
+ case GRPC_OP_RECV_CLOSE_ON_SERVER:
+ gpr_asprintf(&tmp, "RECV_CLOSE_ON_SERVER cancelled=%p",
+ op->data.recv_close_on_server.cancelled);
+ gpr_strvec_add(&b, tmp);
+ }
+ out = gpr_strvec_flatten(&b, NULL);
+ gpr_strvec_destroy(&b);
+
+ return out;
+}
+
+void grpc_call_log_batch(char *file, int line, gpr_log_severity severity,
+ grpc_call *call, const grpc_op *ops, size_t nops,
+ void *tag) {
+ char *tmp;
+ size_t i;
+ gpr_log(file, line, severity,
+ "grpc_call_start_batch(%p, %p, %d, 0x%x)", call, ops, nops, tag);
+ for(i = 0; i < nops; i++) {
+ tmp = grpc_op_string(&ops[i]);
+ gpr_log(file, line, severity, "ops[%d]: %s", i, tmp);
+ gpr_free(tmp);
+ }
+}
diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c
index 6a1d83ce5d..24f4a05071 100644
--- a/src/core/surface/completion_queue.c
+++ b/src/core/surface/completion_queue.c
@@ -432,3 +432,11 @@ void grpc_cq_dump_pending_ops(grpc_completion_queue *cc) {
grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc) {
return &cc->pollset;
}
+
+void grpc_cq_hack_spin_pollset(grpc_completion_queue *cc) {
+ gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
+ grpc_pollset_kick(&cc->pollset);
+ grpc_pollset_work(&cc->pollset,
+ gpr_time_add(gpr_now(), gpr_time_from_millis(100)));
+ gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+}
diff --git a/src/core/surface/completion_queue.h b/src/core/surface/completion_queue.h
index 3054264cad..3a7cc99dda 100644
--- a/src/core/surface/completion_queue.h
+++ b/src/core/surface/completion_queue.h
@@ -114,4 +114,6 @@ void grpc_cq_dump_pending_ops(grpc_completion_queue *cc);
grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc);
-#endif /* GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H */
+void grpc_cq_hack_spin_pollset(grpc_completion_queue *cc);
+
+#endif /* GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H */
diff --git a/src/core/surface/init.c b/src/core/surface/init.c
index e48c4202e5..d4f0eb40e8 100644
--- a/src/core/surface/init.c
+++ b/src/core/surface/init.c
@@ -36,6 +36,7 @@
#include "src/core/debug/trace.h"
#include "src/core/statistics/census_interface.h"
#include "src/core/channel/channel_stack.h"
+#include "src/core/surface/call.h"
#include "src/core/surface/init.h"
#include "src/core/surface/surface_trace.h"
#include "src/core/transport/chttp2_transport.h"
@@ -57,6 +58,7 @@ void grpc_init(void) {
grpc_register_tracer("channel", &grpc_trace_channel);
grpc_register_tracer("surface", &grpc_surface_trace);
grpc_register_tracer("http", &grpc_http_trace);
+ grpc_register_tracer("batch", &grpc_trace_batch);
grpc_security_pre_init();
grpc_tracer_init("GRPC_TRACE");
grpc_iomgr_init();
@@ -82,4 +84,3 @@ int grpc_is_initialized(void) {
gpr_mu_unlock(&g_init_mu);
return r;
}
-
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index 424734c54c..17cba9a505 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -137,6 +137,7 @@ struct grpc_server {
size_t cq_count;
gpr_mu mu;
+ gpr_cv cv;
registered_method *registered_methods;
requested_call_array requested_calls;
@@ -149,6 +150,7 @@ struct grpc_server {
channel_data root_channel_data;
listener *listeners;
+ int listeners_destroyed;
gpr_refcount internal_refcount;
};
@@ -263,6 +265,7 @@ static void server_unref(grpc_server *server) {
if (gpr_unref(&server->internal_refcount)) {
grpc_channel_args_destroy(server->channel_args);
gpr_mu_destroy(&server->mu);
+ gpr_cv_destroy(&server->cv);
gpr_free(server->channel_filters);
requested_call_array_destroy(&server->requested_calls);
while ((rm = server->registered_methods) != NULL) {
@@ -589,9 +592,8 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
static const grpc_channel_filter server_surface_filter = {
- call_op, channel_op, sizeof(call_data),
- init_call_elem, destroy_call_elem, sizeof(channel_data),
- init_channel_elem, destroy_channel_elem, "server",
+ call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem,
+ sizeof(channel_data), init_channel_elem, destroy_channel_elem, "server",
};
static void addcq(grpc_server *server, grpc_completion_queue *cq) {
@@ -620,6 +622,7 @@ grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq,
if (cq) addcq(server, cq);
gpr_mu_init(&server->mu);
+ gpr_cv_init(&server->cv);
server->unregistered_cq = cq;
/* decremented by grpc_server_destroy */
@@ -733,7 +736,8 @@ grpc_transport_setup_result grpc_server_setup_transport(
channel = grpc_channel_create_from_filters(filters, num_filters,
s->channel_args, mdctx, 0);
chand = (channel_data *)grpc_channel_stack_element(
- grpc_channel_get_channel_stack(channel), 0)->channel_data;
+ grpc_channel_get_channel_stack(channel), 0)
+ ->channel_data;
chand->server = s;
server_ref(s);
chand->channel = channel;
@@ -754,7 +758,7 @@ grpc_transport_setup_result grpc_server_setup_transport(
method = grpc_mdstr_from_string(mdctx, rm->method);
hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
for (probes = 0; chand->registered_methods[(hash + probes) % slots]
- .server_registered_method != NULL;
+ .server_registered_method != NULL;
probes++)
;
if (probes > max_probes) max_probes = probes;
@@ -781,6 +785,15 @@ grpc_transport_setup_result grpc_server_setup_transport(
return result;
}
+static int num_listeners(grpc_server *server) {
+ listener *l;
+ int n = 0;
+ for (l = server->listeners; l; l = l->next) {
+ n++;
+ }
+ return n;
+}
+
static void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag,
void *shutdown_tag) {
listener *l;
@@ -878,11 +891,6 @@ static void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag,
for (l = server->listeners; l; l = l->next) {
l->destroy(server, l->arg);
}
- while (server->listeners) {
- l = server->listeners;
- server->listeners = l->next;
- gpr_free(l);
- }
}
void grpc_server_shutdown(grpc_server *server) {
@@ -893,8 +901,18 @@ void grpc_server_shutdown_and_notify(grpc_server *server, void *tag) {
shutdown_internal(server, 1, tag);
}
+void grpc_server_listener_destroy_done(void *s) {
+ grpc_server *server = s;
+ gpr_mu_lock(&server->mu);
+ server->listeners_destroyed++;
+ gpr_cv_signal(&server->cv);
+ gpr_mu_unlock(&server->mu);
+}
+
void grpc_server_destroy(grpc_server *server) {
channel_data *c;
+ listener *l;
+ size_t i;
gpr_mu_lock(&server->mu);
if (!server->shutdown) {
gpr_mu_unlock(&server->mu);
@@ -902,6 +920,23 @@ void grpc_server_destroy(grpc_server *server) {
gpr_mu_lock(&server->mu);
}
+ while (server->listeners_destroyed != num_listeners(server)) {
+ for (i = 0; i < server->cq_count; i++) {
+ gpr_mu_unlock(&server->mu);
+ grpc_cq_hack_spin_pollset(server->cqs[i]);
+ gpr_mu_lock(&server->mu);
+ }
+
+ gpr_cv_wait(&server->cv, &server->mu,
+ gpr_time_add(gpr_now(), gpr_time_from_millis(100)));
+ }
+
+ while (server->listeners) {
+ l = server->listeners;
+ server->listeners = l->next;
+ gpr_free(l);
+ }
+
for (c = server->root_channel_data.next; c != &server->root_channel_data;
c = c->next) {
shutdown_channel(c);
diff --git a/src/core/surface/server.h b/src/core/surface/server.h
index e33f69b8c7..2cfa38fa43 100644
--- a/src/core/surface/server.h
+++ b/src/core/surface/server.h
@@ -48,9 +48,12 @@ grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq,
and when it shuts down, it will call destroy */
void grpc_server_add_listener(grpc_server *server, void *listener,
void (*start)(grpc_server *server, void *arg,
- grpc_pollset **pollsets, size_t npollsets),
+ grpc_pollset **pollsets,
+ size_t npollsets),
void (*destroy)(grpc_server *server, void *arg));
+void grpc_server_listener_destroy_done(void *server);
+
/* Setup a transport - creates a channel stack, binds the transport to the
server */
grpc_transport_setup_result grpc_server_setup_transport(
@@ -60,4 +63,4 @@ grpc_transport_setup_result grpc_server_setup_transport(
const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server);
-#endif /* GRPC_INTERNAL_CORE_SURFACE_SERVER_H */
+#endif /* GRPC_INTERNAL_CORE_SURFACE_SERVER_H */
diff --git a/src/core/surface/server_chttp2.c b/src/core/surface/server_chttp2.c
index 27434b39e2..f3b9219f8b 100644
--- a/src/core/surface/server_chttp2.c
+++ b/src/core/surface/server_chttp2.c
@@ -66,7 +66,8 @@ static void new_transport(void *server, grpc_endpoint *tcp) {
}
/* Server callback: start listening on our ports */
-static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets, size_t pollset_count) {
+static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets,
+ size_t pollset_count) {
grpc_tcp_server *tcp = tcpp;
grpc_tcp_server_start(tcp, pollsets, pollset_count, new_transport, server);
}
@@ -75,7 +76,7 @@ static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets, size
callbacks) */
static void destroy(grpc_server *server, void *tcpp) {
grpc_tcp_server *tcp = tcpp;
- grpc_tcp_server_destroy(tcp);
+ grpc_tcp_server_destroy(tcp, grpc_server_listener_destroy_done, server);
}
int grpc_server_add_http2_port(grpc_server *server, const char *addr) {
@@ -131,7 +132,7 @@ error:
grpc_resolved_addresses_destroy(resolved);
}
if (tcp) {
- grpc_tcp_server_destroy(tcp);
+ grpc_tcp_server_destroy(tcp, NULL, NULL);
}
return 0;
}
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index 2b15b2a812..4c0394d46f 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -1710,6 +1710,8 @@ static int process_read(transport *t, gpr_slice slice) {
gpr_log(GPR_ERROR, "should never reach here");
abort();
+
+ return 0;
}
/* tcp read callback */
diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c
index 1c15716fad..066cc263a1 100644
--- a/src/core/transport/metadata.c
+++ b/src/core/transport/metadata.c
@@ -97,7 +97,7 @@ static void internal_string_ref(internal_string *s);
static void internal_string_unref(internal_string *s);
static void discard_metadata(grpc_mdctx *ctx);
static void gc_mdtab(grpc_mdctx *ctx);
-static void metadata_context_destroy(grpc_mdctx *ctx);
+static void metadata_context_destroy_locked(grpc_mdctx *ctx);
static void lock(grpc_mdctx *ctx) { gpr_mu_lock(&ctx->mu); }
@@ -122,8 +122,7 @@ static void unlock(grpc_mdctx *ctx) {
discard_metadata(ctx);
}
if (ctx->strtab_count == 0) {
- gpr_mu_unlock(&ctx->mu);
- metadata_context_destroy(ctx);
+ metadata_context_destroy_locked(ctx);
return;
}
}
@@ -185,8 +184,7 @@ static void discard_metadata(grpc_mdctx *ctx) {
}
}
-static void metadata_context_destroy(grpc_mdctx *ctx) {
- gpr_mu_lock(&ctx->mu);
+static void metadata_context_destroy_locked(grpc_mdctx *ctx) {
GPR_ASSERT(ctx->strtab_count == 0);
GPR_ASSERT(ctx->mdtab_count == 0);
GPR_ASSERT(ctx->mdtab_free == 0);
diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c
index 33645ca8b8..018ddc4456 100644
--- a/src/core/tsi/ssl_transport_security.c
+++ b/src/core/tsi/ssl_transport_security.c
@@ -567,7 +567,8 @@ static tsi_result populate_ssl_context(
EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
if (!SSL_CTX_set_tmp_ecdh(context, ecdh)) {
gpr_log(GPR_ERROR, "Could not set ephemeral ECDH key.");
- result = TSI_INTERNAL_ERROR;
+ EC_KEY_free(ecdh);
+ return TSI_INTERNAL_ERROR;
}
SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
EC_KEY_free(ecdh);
@@ -604,6 +605,7 @@ static tsi_result build_alpn_protocol_name_list(
unsigned char* current;
*protocol_name_list = NULL;
*protocol_name_list_length = 0;
+ if (num_alpn_protocols == 0) return TSI_INVALID_ARGUMENT;
for (i = 0; i < num_alpn_protocols; i++) {
if (alpn_protocols_lengths[i] == 0) {
gpr_log(GPR_ERROR, "Invalid 0-length protocol name.");
diff --git a/src/cpp/client/generic_stub.cc b/src/cpp/client/generic_stub.cc
new file mode 100644
index 0000000000..3bf7bdf45f
--- /dev/null
+++ b/src/cpp/client/generic_stub.cc
@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc++/generic_stub.h>
+
+#include <grpc++/impl/rpc_method.h>
+
+namespace grpc {
+
+// begin a call to a named method
+std::unique_ptr<GenericClientAsyncReaderWriter> GenericStub::Call(
+ ClientContext* context, const grpc::string& method,
+ CompletionQueue* cq, void* tag) {
+ return std::unique_ptr<GenericClientAsyncReaderWriter>(
+ new GenericClientAsyncReaderWriter(
+ channel_.get(), cq, RpcMethod(method.c_str()), context, tag));
+}
+
+
+} // namespace grpc
+
diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc
index f3ca430bd4..8945b038de 100644
--- a/src/cpp/client/insecure_credentials.cc
+++ b/src/cpp/client/insecure_credentials.cc
@@ -31,8 +31,6 @@
*
*/
-#include <string>
-
#include <grpc/grpc.h>
#include <grpc/support/log.h>
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index e3c6637623..0a73b2c0f6 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -31,40 +31,23 @@
*
*/
-#include <string>
-
-#include <grpc/grpc_security.h>
#include <grpc/support/log.h>
#include <grpc++/channel_arguments.h>
-#include <grpc++/config.h>
-#include <grpc++/credentials.h>
#include "src/cpp/client/channel.h"
+#include "src/cpp/client/secure_credentials.h"
namespace grpc {
-class SecureCredentials GRPC_FINAL : public Credentials {
- public:
- explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {}
- ~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); }
- grpc_credentials* GetRawCreds() { return c_creds_; }
-
- std::shared_ptr<grpc::ChannelInterface> CreateChannel(
- const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE {
- grpc_channel_args channel_args;
- args.SetChannelArgs(&channel_args);
- return std::shared_ptr<ChannelInterface>(new Channel(
- args.GetSslTargetNameOverride().empty()
- ? target
- : args.GetSslTargetNameOverride(),
- grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args)));
- }
-
- SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return this; }
-
- private:
- grpc_credentials* const c_creds_;
-};
+std::shared_ptr<grpc::ChannelInterface> SecureCredentials::CreateChannel(
+ const string& target, const grpc::ChannelArguments& args) {
+ grpc_channel_args channel_args;
+ args.SetChannelArgs(&channel_args);
+ return std::shared_ptr<ChannelInterface>(new Channel(
+ args.GetSslTargetNameOverride().empty() ? target
+ : args.GetSslTargetNameOverride(),
+ grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args)));
+}
namespace {
std::unique_ptr<Credentials> WrapCredentials(grpc_credentials* creds) {
diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h
new file mode 100644
index 0000000000..77d575813e
--- /dev/null
+++ b/src/cpp/client/secure_credentials.h
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H
+#define GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H
+
+#include <grpc/grpc_security.h>
+
+#include <grpc++/config.h>
+#include <grpc++/credentials.h>
+
+namespace grpc {
+
+class SecureCredentials GRPC_FINAL : public Credentials {
+ public:
+ explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {}
+ ~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); }
+ grpc_credentials* GetRawCreds() { return c_creds_; }
+
+ std::shared_ptr<grpc::ChannelInterface> CreateChannel(
+ const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE;
+ SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return this; }
+
+ private:
+ grpc_credentials* const c_creds_;
+};
+
+} // namespace grpc
+
+#endif // GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H
+
diff --git a/src/cpp/common/call.cc b/src/cpp/common/call.cc
index 5c26a1ad7c..e75e77e0b5 100644
--- a/src/cpp/common/call.cc
+++ b/src/cpp/common/call.cc
@@ -60,7 +60,8 @@ CallOpBuffer::CallOpBuffer()
status_code_(GRPC_STATUS_OK),
status_details_(nullptr),
status_details_capacity_(0),
- send_status_(nullptr),
+ send_status_available_(false),
+ send_status_code_(GRPC_STATUS_OK),
trailing_metadata_count_(0),
trailing_metadata_(nullptr),
cancelled_buf_(0),
@@ -104,7 +105,9 @@ void CallOpBuffer::Reset(void* next_return_tag) {
status_code_ = GRPC_STATUS_OK;
- send_status_ = nullptr;
+ send_status_available_ = false;
+ send_status_code_ = GRPC_STATUS_OK;
+ send_status_details_.clear();
trailing_metadata_count_ = 0;
trailing_metadata_ = nullptr;
@@ -148,7 +151,7 @@ void FillMetadataMap(grpc_metadata_array* arr,
// TODO(yangg) handle duplicates?
metadata->insert(std::pair<grpc::string, grpc::string>(
arr->metadata[i].key,
- {arr->metadata[i].value, arr->metadata[i].value_length}));
+ grpc::string(arr->metadata[i].value, arr->metadata[i].value_length)));
}
grpc_metadata_array_destroy(arr);
grpc_metadata_array_init(arr);
@@ -186,6 +189,7 @@ void CallOpBuffer::AddRecvMessage(grpc::protobuf::Message* message) {
void CallOpBuffer::AddRecvMessage(ByteBuffer* message) {
recv_message_buffer_ = message;
+ recv_message_buffer_->Clear();
}
void CallOpBuffer::AddClientSendClose() { client_send_close_ = true; }
@@ -207,7 +211,9 @@ void CallOpBuffer::AddServerSendStatus(
} else {
trailing_metadata_count_ = 0;
}
- send_status_ = &status;
+ send_status_available_ = true;
+ send_status_code_ = static_cast<grpc_status_code>(status.code());
+ send_status_details_ = status.details();
}
void CallOpBuffer::FillOps(grpc_op* ops, size_t* nops) {
@@ -256,16 +262,15 @@ void CallOpBuffer::FillOps(grpc_op* ops, size_t* nops) {
&status_details_capacity_;
(*nops)++;
}
- if (send_status_) {
+ if (send_status_available_) {
ops[*nops].op = GRPC_OP_SEND_STATUS_FROM_SERVER;
ops[*nops].data.send_status_from_server.trailing_metadata_count =
trailing_metadata_count_;
ops[*nops].data.send_status_from_server.trailing_metadata =
trailing_metadata_;
- ops[*nops].data.send_status_from_server.status =
- static_cast<grpc_status_code>(send_status_->code());
+ ops[*nops].data.send_status_from_server.status = send_status_code_;
ops[*nops].data.send_status_from_server.status_details =
- send_status_->details().c_str();
+ send_status_details_.empty() ? nullptr : send_status_details_.c_str();
(*nops)++;
}
if (recv_closed_) {
diff --git a/src/cpp/common/completion_queue.cc b/src/cpp/common/completion_queue.cc
index fede2da016..cea2d24831 100644
--- a/src/cpp/common/completion_queue.cc
+++ b/src/cpp/common/completion_queue.cc
@@ -36,7 +36,6 @@
#include <grpc/grpc.h>
#include <grpc/support/log.h>
-#include <grpc/support/time.h>
#include "src/cpp/util/time.h"
namespace grpc {
@@ -57,15 +56,12 @@ class EventDeleter {
}
};
-CompletionQueue::NextStatus
-CompletionQueue::AsyncNext(void** tag, bool* ok,
- std::chrono::system_clock::time_point deadline) {
+CompletionQueue::NextStatus CompletionQueue::AsyncNextInternal(
+ void** tag, bool* ok, gpr_timespec deadline) {
std::unique_ptr<grpc_event, EventDeleter> ev;
- gpr_timespec gpr_deadline;
- Timepoint2Timespec(deadline, &gpr_deadline);
for (;;) {
- ev.reset(grpc_completion_queue_next(cq_, gpr_deadline));
+ ev.reset(grpc_completion_queue_next(cq_, deadline));
if (!ev) { /* got a NULL back because deadline passed */
return TIMEOUT;
}
@@ -81,6 +77,13 @@ CompletionQueue::AsyncNext(void** tag, bool* ok,
}
}
+CompletionQueue::NextStatus CompletionQueue::AsyncNext(
+ void** tag, bool* ok, std::chrono::system_clock::time_point deadline) {
+ gpr_timespec gpr_deadline;
+ Timepoint2Timespec(deadline, &gpr_deadline);
+ return AsyncNextInternal(tag, ok, gpr_deadline);
+}
+
bool CompletionQueue::Pluck(CompletionQueueTag* tag) {
std::unique_ptr<grpc_event, EventDeleter> ev;
diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc
index 88f7a9b1a9..3e262dd74f 100644
--- a/src/cpp/server/secure_server_credentials.cc
+++ b/src/cpp/server/secure_server_credentials.cc
@@ -31,37 +31,23 @@
*
*/
-#include <grpc/grpc_security.h>
-
-#include <grpc++/server_credentials.h>
+#include "src/cpp/server/secure_server_credentials.h"
namespace grpc {
-namespace {
-class SecureServerCredentials GRPC_FINAL : public ServerCredentials {
- public:
- explicit SecureServerCredentials(grpc_server_credentials* creds)
- : creds_(creds) {}
- ~SecureServerCredentials() GRPC_OVERRIDE {
- grpc_server_credentials_release(creds_);
- }
-
- int AddPortToServer(const grpc::string& addr,
- grpc_server* server) GRPC_OVERRIDE {
- return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_);
- }
-
- private:
- grpc_server_credentials* const creds_;
-};
-} // namespace
+int SecureServerCredentials::AddPortToServer(
+ const grpc::string& addr, grpc_server* server) {
+ return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_);
+}
std::shared_ptr<ServerCredentials> SslServerCredentials(
const SslServerCredentialsOptions& options) {
std::vector<grpc_ssl_pem_key_cert_pair> pem_key_cert_pairs;
- for (const auto& key_cert_pair : options.pem_key_cert_pairs) {
- pem_key_cert_pairs.push_back(
- {key_cert_pair.private_key.c_str(), key_cert_pair.cert_chain.c_str()});
+ for (auto key_cert_pair = options.pem_key_cert_pairs.begin();
+ key_cert_pair != options.pem_key_cert_pairs.end(); key_cert_pair++) {
+ grpc_ssl_pem_key_cert_pair p = {key_cert_pair->private_key.c_str(),
+ key_cert_pair->cert_chain.c_str()};
+ pem_key_cert_pairs.push_back(p);
}
grpc_server_credentials* c_creds = grpc_ssl_server_credentials_create(
options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
diff --git a/src/cpp/server/secure_server_credentials.h b/src/cpp/server/secure_server_credentials.h
new file mode 100644
index 0000000000..b9803f107e
--- /dev/null
+++ b/src/cpp/server/secure_server_credentials.h
@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H
+#define GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H
+
+#include <grpc/grpc_security.h>
+
+#include <grpc++/server_credentials.h>
+
+namespace grpc {
+
+class SecureServerCredentials GRPC_FINAL : public ServerCredentials {
+ public:
+ explicit SecureServerCredentials(grpc_server_credentials* creds)
+ : creds_(creds) {}
+ ~SecureServerCredentials() GRPC_OVERRIDE {
+ grpc_server_credentials_release(creds_);
+ }
+
+ int AddPortToServer(const grpc::string& addr,
+ grpc_server* server) GRPC_OVERRIDE;
+
+ private:
+ grpc_server_credentials* const creds_;
+};
+
+} // namespace grpc
+
+#endif // GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index 5a4ca6915a..046133c5eb 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -107,6 +107,7 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag {
request_payload_(mrd->request_payload_),
method_(mrd->method_) {
ctx_.call_ = mrd->call_;
+ ctx_.cq_ = &cq_;
GPR_ASSERT(mrd->in_flight_);
mrd->in_flight_ = false;
mrd->request_metadata_.count = 0;
@@ -182,7 +183,7 @@ Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned)
Server::~Server() {
{
- std::unique_lock<std::mutex> lock(mu_);
+ grpc::unique_lock<grpc::mutex> lock(mu_);
if (started_ && !shutdown_) {
lock.unlock();
Shutdown();
@@ -247,8 +248,8 @@ bool Server::Start() {
// Start processing rpcs.
if (!sync_methods_.empty()) {
- for (auto& m : sync_methods_) {
- m.Request(server_);
+ for (auto m = sync_methods_.begin(); m != sync_methods_.end(); m++) {
+ m->Request(server_);
}
ScheduleCallback();
@@ -258,7 +259,7 @@ bool Server::Start() {
}
void Server::Shutdown() {
- std::unique_lock<std::mutex> lock(mu_);
+ grpc::unique_lock<grpc::mutex> lock(mu_);
if (started_ && !shutdown_) {
shutdown_ = true;
grpc_server_shutdown(server_);
@@ -272,7 +273,7 @@ void Server::Shutdown() {
}
void Server::Wait() {
- std::unique_lock<std::mutex> lock(mu_);
+ grpc::unique_lock<grpc::mutex> lock(mu_);
while (num_running_cb_ != 0) {
callback_cv_.wait(lock);
}
@@ -364,6 +365,7 @@ class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag {
}
}
ctx->call_ = call_;
+ ctx->cq_ = cq_;
Call call(call_, server_, cq_);
if (orig_status && call_) {
ctx->BeginCompletionOp(&call);
@@ -403,7 +405,7 @@ void Server::RequestAsyncGenericCall(GenericServerContext* context,
void Server::ScheduleCallback() {
{
- std::unique_lock<std::mutex> lock(mu_);
+ grpc::unique_lock<grpc::mutex> lock(mu_);
num_running_cb_++;
}
thread_pool_->ScheduleCallback(std::bind(&Server::RunRpc, this));
@@ -424,7 +426,7 @@ void Server::RunRpc() {
}
{
- std::unique_lock<std::mutex> lock(mu_);
+ grpc::unique_lock<grpc::mutex> lock(mu_);
num_running_cb_--;
if (shutdown_) {
callback_cv_.notify_all();
diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc
index 58bf9d937f..c5e115f396 100644
--- a/src/cpp/server/server_builder.cc
+++ b/src/cpp/server/server_builder.cc
@@ -86,24 +86,26 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
thread_pool_owned = true;
}
std::unique_ptr<Server> server(new Server(thread_pool_, thread_pool_owned));
- for (auto* service : services_) {
- if (!server->RegisterService(service)) {
+ for (auto service = services_.begin(); service != services_.end();
+ service++) {
+ if (!server->RegisterService(*service)) {
return nullptr;
}
}
- for (auto* service : async_services_) {
- if (!server->RegisterAsyncService(service)) {
+ for (auto service = async_services_.begin();
+ service != async_services_.end(); service++) {
+ if (!server->RegisterAsyncService(*service)) {
return nullptr;
}
}
if (generic_service_) {
server->RegisterAsyncGenericService(generic_service_);
}
- for (auto& port : ports_) {
- int r = server->AddListeningPort(port.addr, port.creds.get());
+ for (auto port = ports_.begin(); port != ports_.end(); port++) {
+ int r = server->AddListeningPort(port->addr, port->creds.get());
if (!r) return nullptr;
- if (port.selected_port != nullptr) {
- *port.selected_port = r;
+ if (port->selected_port != nullptr) {
+ *port->selected_port = r;
}
}
if (!server->Start()) {
diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc
index bb3c2d1405..ffd6d30d5d 100644
--- a/src/cpp/server/server_context.cc
+++ b/src/cpp/server/server_context.cc
@@ -33,9 +33,8 @@
#include <grpc++/server_context.h>
-#include <mutex>
-
#include <grpc++/impl/call.h>
+#include <grpc++/impl/sync.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include "src/cpp/util/time.h"
@@ -57,14 +56,14 @@ class ServerContext::CompletionOp GRPC_FINAL : public CallOpBuffer {
void Unref();
private:
- std::mutex mu_;
+ grpc::mutex mu_;
int refs_;
bool finalized_;
bool cancelled_;
};
void ServerContext::CompletionOp::Unref() {
- std::unique_lock<std::mutex> lock(mu_);
+ grpc::unique_lock<grpc::mutex> lock(mu_);
if (--refs_ == 0) {
lock.unlock();
delete this;
@@ -73,13 +72,13 @@ void ServerContext::CompletionOp::Unref() {
bool ServerContext::CompletionOp::CheckCancelled(CompletionQueue* cq) {
cq->TryPluck(this);
- std::lock_guard<std::mutex> g(mu_);
+ grpc::lock_guard<grpc::mutex> g(mu_);
return finalized_ ? cancelled_ : false;
}
bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) {
GPR_ASSERT(CallOpBuffer::FinalizeResult(tag, status));
- std::unique_lock<std::mutex> lock(mu_);
+ grpc::unique_lock<grpc::mutex> lock(mu_);
finalized_ = true;
if (!*status) cancelled_ = true;
if (--refs_ == 0) {
diff --git a/src/cpp/server/thread_pool.cc b/src/cpp/server/thread_pool.cc
index d3013b806c..e8d0e89ed2 100644
--- a/src/cpp/server/thread_pool.cc
+++ b/src/cpp/server/thread_pool.cc
@@ -31,48 +31,52 @@
*
*/
+#include <grpc++/impl/sync.h>
+#include <grpc++/impl/thd.h>
+
#include "src/cpp/server/thread_pool.h"
namespace grpc {
+void ThreadPool::ThreadFunc() {
+ for (;;) {
+ // Wait until work is available or we are shutting down.
+ grpc::unique_lock<grpc::mutex> lock(mu_);
+ if (!shutdown_ && callbacks_.empty()) {
+ cv_.wait(lock);
+ }
+ // Drain callbacks before considering shutdown to ensure all work
+ // gets completed.
+ if (!callbacks_.empty()) {
+ auto cb = callbacks_.front();
+ callbacks_.pop();
+ lock.unlock();
+ cb();
+ } else if (shutdown_) {
+ return;
+ }
+ }
+}
+
ThreadPool::ThreadPool(int num_threads) : shutdown_(false) {
for (int i = 0; i < num_threads; i++) {
- threads_.push_back(std::thread([this]() {
- for (;;) {
- // Wait until work is available or we are shutting down.
- auto have_work = [this]() { return shutdown_ || !callbacks_.empty(); };
- std::unique_lock<std::mutex> lock(mu_);
- if (!have_work()) {
- cv_.wait(lock, have_work);
- }
- // Drain callbacks before considering shutdown to ensure all work
- // gets completed.
- if (!callbacks_.empty()) {
- auto cb = callbacks_.front();
- callbacks_.pop();
- lock.unlock();
- cb();
- } else if (shutdown_) {
- return;
- }
- }
- }));
+ threads_.push_back(grpc::thread(&ThreadPool::ThreadFunc, this));
}
}
ThreadPool::~ThreadPool() {
{
- std::lock_guard<std::mutex> lock(mu_);
+ grpc::lock_guard<grpc::mutex> lock(mu_);
shutdown_ = true;
cv_.notify_all();
}
- for (auto& t : threads_) {
- t.join();
+ for (auto t = threads_.begin(); t != threads_.end(); t++) {
+ t->join();
}
}
void ThreadPool::ScheduleCallback(const std::function<void()>& callback) {
- std::lock_guard<std::mutex> lock(mu_);
+ grpc::lock_guard<grpc::mutex> lock(mu_);
callbacks_.push(callback);
cv_.notify_one();
}
diff --git a/src/cpp/server/thread_pool.h b/src/cpp/server/thread_pool.h
index 6225d82a0b..0f24d6e9b3 100644
--- a/src/cpp/server/thread_pool.h
+++ b/src/cpp/server/thread_pool.h
@@ -35,11 +35,11 @@
#define GRPC_INTERNAL_CPP_SERVER_THREAD_POOL_H
#include <grpc++/config.h>
+
+#include <grpc++/impl/sync.h>
+#include <grpc++/impl/thd.h>
#include <grpc++/thread_pool_interface.h>
-#include <condition_variable>
-#include <thread>
-#include <mutex>
#include <queue>
#include <vector>
@@ -53,11 +53,13 @@ class ThreadPool GRPC_FINAL : public ThreadPoolInterface {
void ScheduleCallback(const std::function<void()>& callback) GRPC_OVERRIDE;
private:
- std::mutex mu_;
- std::condition_variable cv_;
+ grpc::mutex mu_;
+ grpc::condition_variable cv_;
bool shutdown_;
std::queue<std::function<void()>> callbacks_;
- std::vector<std::thread> threads_;
+ std::vector<grpc::thread> threads_;
+
+ void ThreadFunc();
};
} // namespace grpc
diff --git a/src/cpp/util/time.cc b/src/cpp/util/time.cc
index 44d2283e76..059ea72abf 100644
--- a/src/cpp/util/time.cc
+++ b/src/cpp/util/time.cc
@@ -42,11 +42,15 @@ using std::chrono::system_clock;
namespace grpc {
-// TODO(yangg) prevent potential overflow.
void Timepoint2Timespec(const system_clock::time_point& from,
gpr_timespec* to) {
system_clock::duration deadline = from.time_since_epoch();
seconds secs = duration_cast<seconds>(deadline);
+ if (from == system_clock::time_point::max() ||
+ secs.count() >= gpr_inf_future.tv_sec || secs.count() < 0) {
+ *to = gpr_inf_future;
+ return;
+ }
nanoseconds nsecs = duration_cast<nanoseconds>(deadline - secs);
to->tv_sec = secs.count();
to->tv_nsec = nsecs.count();
diff --git a/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs
index e4328806ad..e0f0474245 100644
--- a/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs
@@ -9,4 +9,4 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-[assembly: AssemblyVersion("0.1.*")]
+[assembly: AssemblyVersion("0.2.*")]
diff --git a/src/csharp/Grpc.Core/Grpc.Core.nuspec b/src/csharp/Grpc.Core/Grpc.Core.nuspec
index af8a8869ca..f2032522c9 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.nuspec
+++ b/src/csharp/Grpc.Core/Grpc.Core.nuspec
@@ -7,7 +7,7 @@
<description>Core C# implementation of gRPC - an RPC library and framework. See project site for more info.
This is an experimental release, not ready to use.
</description>
- <version>0.1.0</version>
+ <version>0.2.0</version>
<authors>Google Inc.</authors>
<owners>jtattermusch</owners>
<licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl>
diff --git a/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
index 168939cf8c..81218cb67e 100644
--- a/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
@@ -9,6 +9,6 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-[assembly: AssemblyVersion("0.1.*")]
+[assembly: AssemblyVersion("0.2.*")]
[assembly: InternalsVisibleTo("Grpc.Core.Tests")]
diff --git a/src/csharp/Grpc.Examples.MathClient/MathClient.cs b/src/csharp/Grpc.Examples.MathClient/MathClient.cs
index f5956bd33e..ca7683d399 100644
--- a/src/csharp/Grpc.Examples.MathClient/MathClient.cs
+++ b/src/csharp/Grpc.Examples.MathClient/MathClient.cs
@@ -46,11 +46,15 @@ namespace math
MathGrpc.IMathServiceClient stub = new MathGrpc.MathServiceClientStub(channel);
MathExamples.DivExample(stub);
- MathExamples.FibExample(stub);
+ MathExamples.DivAsyncExample(stub).Wait();
- MathExamples.SumExample(stub);
+ MathExamples.FibExample(stub).Wait();
- MathExamples.DivManyExample(stub);
+ MathExamples.SumExample(stub).Wait();
+
+ MathExamples.DivManyExample(stub).Wait();
+
+ MathExamples.DependendRequestsExample(stub).Wait();
}
GrpcEnvironment.Shutdown();
diff --git a/src/csharp/Grpc.Examples.MathClient/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Examples.MathClient/Properties/AssemblyInfo.cs
index 11fc099a95..1989ca8430 100644
--- a/src/csharp/Grpc.Examples.MathClient/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.Examples.MathClient/Properties/AssemblyInfo.cs
@@ -9,4 +9,4 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-[assembly: AssemblyVersion("0.1.*")]
+[assembly: AssemblyVersion("0.2.*")]
diff --git a/src/csharp/Grpc.Examples.MathServer/.gitignore b/src/csharp/Grpc.Examples.MathServer/.gitignore
new file mode 100644
index 0000000000..1746e3269e
--- /dev/null
+++ b/src/csharp/Grpc.Examples.MathServer/.gitignore
@@ -0,0 +1,2 @@
+bin
+obj
diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj
new file mode 100644
index 0000000000..3f7e6c0768
--- /dev/null
+++ b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+ <ProductVersion>10.0.0</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{BF62FE08-373A-43D6-9D73-41CAA38B7011}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <RootNamespace>Grpc.Examples.MathServer</RootNamespace>
+ <AssemblyName>Grpc.Examples.MathServer</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug</OutputPath>
+ <DefineConstants>DEBUG;</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <Externalconsole>true</Externalconsole>
+ <PlatformTarget>x86</PlatformTarget>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <DebugType>full</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <Externalconsole>true</Externalconsole>
+ <PlatformTarget>x86</PlatformTarget>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="MathServer.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <ItemGroup>
+ <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
+ <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
+ <Name>Grpc.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Grpc.Examples\Grpc.Examples.csproj">
+ <Project>{7DC1433E-3225-42C7-B7EA-546D56E27A4B}</Project>
+ <Name>Grpc.Examples</Name>
+ </ProjectReference>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.Examples.MathServer/MathServer.cs b/src/csharp/Grpc.Examples.MathServer/MathServer.cs
new file mode 100644
index 0000000000..884a84d0a6
--- /dev/null
+++ b/src/csharp/Grpc.Examples.MathServer/MathServer.cs
@@ -0,0 +1,61 @@
+#region Copyright notice and license
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Grpc.Core;
+
+namespace math
+{
+ class MainClass
+ {
+ public static void Main(string[] args)
+ {
+ String host = "0.0.0.0";
+
+ GrpcEnvironment.Initialize();
+
+ Server server = new Server();
+ server.AddServiceDefinition(MathGrpc.BindService(new MathServiceImpl()));
+ int port = server.AddListeningPort(host + ":0");
+ server.Start();
+
+ Console.WriteLine("MathServer listening on port " + port);
+
+ Console.WriteLine("Press any key to stop the server...");
+ Console.ReadKey();
+
+ server.ShutdownAsync().Wait();
+ GrpcEnvironment.Shutdown();
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Examples.MathServer/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Examples.MathServer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..6b3d0516b9
--- /dev/null
+++ b/src/csharp/Grpc.Examples.MathServer/Properties/AssemblyInfo.cs
@@ -0,0 +1,12 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle("Grpc.Examples.MathServer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: AssemblyVersion("0.1.*")]
diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
index cf5a640079..f9c1caf700 100644
--- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
+++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
@@ -37,6 +37,18 @@
<Reference Include="Google.ProtocolBuffers">
<HintPath>..\packages\Google.ProtocolBuffers.2.4.1.521\lib\net40\Google.ProtocolBuffers.dll</HintPath>
</Reference>
+ <Reference Include="System.Reactive.Interfaces">
+ <HintPath>..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Reactive.Core">
+ <HintPath>..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Reactive.Linq">
+ <HintPath>..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Reactive.PlatformServices">
+ <HintPath>..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
+ </Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
diff --git a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
index 85f213cb39..fa5d6688a6 100644
--- a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
+++ b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
@@ -33,6 +33,7 @@
using System;
using System.Collections.Generic;
+using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;
@@ -120,14 +121,12 @@ namespace math.Tests
[Test]
public void Sum()
{
- var res = client.Sum();
- foreach (var num in new long[] { 10, 20, 30 })
- {
- res.Inputs.OnNext(Num.CreateBuilder().SetNum_(num).Build());
- }
- res.Inputs.OnCompleted();
+ var clientStreamingResult = client.Sum();
+ var numList = new List<long> { 10, 20, 30 }.ConvertAll(
+ n => Num.CreateBuilder().SetNum_(n).Build());
+ numList.Subscribe(clientStreamingResult.Inputs);
- Assert.AreEqual(60, res.Task.Result.Num_);
+ Assert.AreEqual(60, clientStreamingResult.Task.Result.Num_);
}
[Test]
@@ -142,13 +141,7 @@ namespace math.Tests
var recorder = new RecordingObserver<DivReply>();
var requestObserver = client.DivMany(recorder);
-
- foreach (var arg in divArgsList)
- {
- requestObserver.OnNext(arg);
- }
- requestObserver.OnCompleted();
-
+ divArgsList.Subscribe(requestObserver);
var result = recorder.ToList().Result;
CollectionAssert.AreEqual(new long[] { 3, 4, 3 }, result.ConvertAll((divReply) => divReply.Quotient));
diff --git a/src/csharp/Grpc.Examples.Tests/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Examples.Tests/Properties/AssemblyInfo.cs
index 43c7616ac3..d78e9210c0 100644
--- a/src/csharp/Grpc.Examples.Tests/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.Examples.Tests/Properties/AssemblyInfo.cs
@@ -9,4 +9,4 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-[assembly: AssemblyVersion("0.1.*")]
+[assembly: AssemblyVersion("0.2.*")]
diff --git a/src/csharp/Grpc.Examples.Tests/packages.config b/src/csharp/Grpc.Examples.Tests/packages.config
index 51c17bcd5e..06c5e6a4eb 100644
--- a/src/csharp/Grpc.Examples.Tests/packages.config
+++ b/src/csharp/Grpc.Examples.Tests/packages.config
@@ -1,5 +1,10 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="Google.ProtocolBuffers" version="2.4.1.521" targetFramework="net45" />
- <package id="NUnit" version="2.6.4" targetFramework="net45" />
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.ProtocolBuffers" version="2.4.1.521" targetFramework="net45" />
+ <package id="NUnit" version="2.6.4" targetFramework="net45" />
+ <package id="Rx-Core" version="2.2.5" targetFramework="net45" />
+ <package id="Rx-Interfaces" version="2.2.5" targetFramework="net45" />
+ <package id="Rx-Linq" version="2.2.5" targetFramework="net45" />
+ <package id="Rx-Main" version="2.2.5" targetFramework="net45" />
+ <package id="Rx-PlatformServices" version="2.2.5" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/src/csharp/Grpc.Examples/MathExamples.cs b/src/csharp/Grpc.Examples/MathExamples.cs
index b8bb7eacbd..032372b2a1 100644
--- a/src/csharp/Grpc.Examples/MathExamples.cs
+++ b/src/csharp/Grpc.Examples/MathExamples.cs
@@ -45,51 +45,45 @@ namespace math
Console.WriteLine("Div Result: " + result);
}
- public static void DivAsyncExample(MathGrpc.IMathServiceClient stub)
+ public static async Task DivAsyncExample(MathGrpc.IMathServiceClient stub)
{
- Task<DivReply> call = stub.DivAsync(new DivArgs.Builder { Dividend = 4, Divisor = 5 }.Build());
- DivReply result = call.Result;
- Console.WriteLine(result);
+ Task<DivReply> resultTask = stub.DivAsync(new DivArgs.Builder { Dividend = 4, Divisor = 5 }.Build());
+ DivReply result = await resultTask;
+ Console.WriteLine("DivAsync Result: " + result);
}
- public static void DivAsyncWithCancellationExample(MathGrpc.IMathServiceClient stub)
+ public static async Task DivAsyncWithCancellationExample(MathGrpc.IMathServiceClient stub)
{
- Task<DivReply> call = stub.DivAsync(new DivArgs.Builder { Dividend = 4, Divisor = 5 }.Build());
- DivReply result = call.Result;
+ Task<DivReply> resultTask = stub.DivAsync(new DivArgs.Builder { Dividend = 4, Divisor = 5 }.Build());
+ DivReply result = await resultTask;
Console.WriteLine(result);
}
- public static void FibExample(MathGrpc.IMathServiceClient stub)
+ public static async Task FibExample(MathGrpc.IMathServiceClient stub)
{
var recorder = new RecordingObserver<Num>();
stub.Fib(new FibArgs.Builder { Limit = 5 }.Build(), recorder);
-
- List<Num> numbers = recorder.ToList().Result;
- Console.WriteLine("Fib Result: " + string.Join("|", recorder.ToList().Result));
+ List<Num> result = await recorder.ToList();
+ Console.WriteLine("Fib Result: " + string.Join("|", result));
}
- public static void SumExample(MathGrpc.IMathServiceClient stub)
+ public static async Task SumExample(MathGrpc.IMathServiceClient stub)
{
- List<Num> numbers = new List<Num>
+ var numbers = new List<Num>
{
new Num.Builder { Num_ = 1 }.Build(),
new Num.Builder { Num_ = 2 }.Build(),
new Num.Builder { Num_ = 3 }.Build()
};
- var res = stub.Sum();
- foreach (var num in numbers)
- {
- res.Inputs.OnNext(num);
- }
- res.Inputs.OnCompleted();
-
- Console.WriteLine("Sum Result: " + res.Task.Result);
+ var clientStreamingResult = stub.Sum();
+ numbers.Subscribe(clientStreamingResult.Inputs);
+ Console.WriteLine("Sum Result: " + await clientStreamingResult.Task);
}
- public static void DivManyExample(MathGrpc.IMathServiceClient stub)
+ public static async Task DivManyExample(MathGrpc.IMathServiceClient stub)
{
- List<DivArgs> divArgsList = new List<DivArgs>
+ var divArgsList = new List<DivArgs>
{
new DivArgs.Builder { Dividend = 10, Divisor = 3 }.Build(),
new DivArgs.Builder { Dividend = 100, Divisor = 21 }.Build(),
@@ -97,26 +91,27 @@ namespace math
};
var recorder = new RecordingObserver<DivReply>();
-
var inputs = stub.DivMany(recorder);
- foreach (var input in divArgsList)
- {
- inputs.OnNext(input);
- }
- inputs.OnCompleted();
-
- Console.WriteLine("DivMany Result: " + string.Join("|", recorder.ToList().Result));
+ divArgsList.Subscribe(inputs);
+ var result = await recorder.ToList();
+ Console.WriteLine("DivMany Result: " + string.Join("|", result));
}
- public static void DependendRequestsExample(MathGrpc.IMathServiceClient stub)
+ public static async Task DependendRequestsExample(MathGrpc.IMathServiceClient stub)
{
- var numberList = new List<Num>
+ var numbers = new List<Num>
{
- new Num.Builder { Num_ = 1 }.Build(),
- new Num.Builder { Num_ = 2 }.Build(), new Num.Builder { Num_ = 3 }.Build()
+ new Num.Builder { Num_ = 1 }.Build(),
+ new Num.Builder { Num_ = 2 }.Build(),
+ new Num.Builder { Num_ = 3 }.Build()
};
- numberList.ToObservable();
+ var clientStreamingResult = stub.Sum();
+ numbers.Subscribe(clientStreamingResult.Inputs);
+ Num sum = await clientStreamingResult.Task;
+
+ DivReply result = await stub.DivAsync(new DivArgs.Builder { Dividend = sum.Num_, Divisor = numbers.Count }.Build());
+ Console.WriteLine("Avg Result: " + result);
}
}
}
diff --git a/src/csharp/Grpc.Examples/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Examples/Properties/AssemblyInfo.cs
index b55d24166c..fd1cdbbc1c 100644
--- a/src/csharp/Grpc.Examples/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.Examples/Properties/AssemblyInfo.cs
@@ -9,4 +9,4 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-[assembly: AssemblyVersion("0.1.*")]
+[assembly: AssemblyVersion("0.2.*")]
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs b/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs
index c93dd1eb2f..d9d36f03e4 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs
@@ -9,4 +9,4 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-[assembly: AssemblyVersion("0.1.*")]
+[assembly: AssemblyVersion("0.2.*")]
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs b/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs
index f3def1aea4..b0b163b883 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs
@@ -9,4 +9,4 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-[assembly: AssemblyVersion("0.1.*")]
+[assembly: AssemblyVersion("0.2.*")]
diff --git a/src/csharp/Grpc.IntegrationTesting/Properties/AssemblyInfo.cs b/src/csharp/Grpc.IntegrationTesting/Properties/AssemblyInfo.cs
index f09a448e9e..fe6c8a8aed 100644
--- a/src/csharp/Grpc.IntegrationTesting/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Properties/AssemblyInfo.cs
@@ -9,4 +9,4 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-[assembly: AssemblyVersion("0.1.*")]
+[assembly: AssemblyVersion("0.2.*")]
diff --git a/src/csharp/Grpc.nuspec b/src/csharp/Grpc.nuspec
index 96a6aaf6b7..4c106a2ca2 100644
--- a/src/csharp/Grpc.nuspec
+++ b/src/csharp/Grpc.nuspec
@@ -7,7 +7,7 @@
<description>C# implementation of gRPC - an RPC library and framework. See project site for more info.
This is an experimental release, not ready to use.
</description>
- <version>0.1.0</version>
+ <version>0.2.0</version>
<authors>Google Inc.</authors>
<owners>jtattermusch</owners>
<licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl>
@@ -17,7 +17,7 @@
<copyright>Copyright 2015, Google Inc.</copyright>
<tags>gRPC RPC Protocol HTTP/2</tags>
<dependencies>
- <dependency id="Grpc.Core" version="0.1.0" />
+ <dependency id="Grpc.Core" version="0.2.0" />
</dependencies>
</metadata>
</package>
diff --git a/src/csharp/Grpc.sln b/src/csharp/Grpc.sln
index 2e6d288699..2f8c2e1719 100644
--- a/src/csharp/Grpc.sln
+++ b/src/csharp/Grpc.sln
@@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.Cli
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.Server", "Grpc.IntegrationTesting.Server\Grpc.IntegrationTesting.Server.csproj", "{A654F3B8-E859-4E6A-B30D-227527DBEF0D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Examples.MathServer", "Grpc.Examples.MathServer\Grpc.Examples.MathServer.csproj", "{BF62FE08-373A-43D6-9D73-41CAA38B7011}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
@@ -47,6 +49,10 @@ Global
{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Debug|x86.Build.0 = Debug|x86
{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|x86.ActiveCfg = Release|x86
{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|x86.Build.0 = Release|x86
+ {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|x86.ActiveCfg = Debug|x86
+ {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|x86.Build.0 = Debug|x86
+ {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|x86.ActiveCfg = Release|x86
+ {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|x86.Build.0 = Release|x86
{C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|x86.ActiveCfg = Debug|x86
{C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|x86.Build.0 = Debug|x86
{C61154BA-DD4A-4838-8420-0162A28925E0}.Release|x86.ActiveCfg = Release|x86
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 9a1c908d11..e182468d9b 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -731,7 +731,7 @@ grpcsharp_ssl_credentials_create(const char *pem_root_certs,
}
}
-GPR_EXPORT void grpcsharp_credentials_release(grpc_credentials *creds) {
+GPR_EXPORT void GPR_CALLTYPE grpcsharp_credentials_release(grpc_credentials *creds) {
grpc_credentials_release(creds);
}
@@ -765,7 +765,7 @@ grpcsharp_ssl_server_credentials_create(
return creds;
}
-GPR_EXPORT void grpcsharp_server_credentials_release(
+GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_credentials_release(
grpc_server_credentials *creds) {
grpc_server_credentials_release(creds);
}
diff --git a/src/node/binding.gyp b/src/node/binding.gyp
index 7ef3bdf4bd..83f72fabca 100644
--- a/src/node/binding.gyp
+++ b/src/node/binding.gyp
@@ -18,12 +18,29 @@
],
'link_settings': {
'libraries': [
- '-lrt',
'-lpthread',
'-lgrpc',
'-lgpr'
- ],
+ ]
},
+ "conditions": [
+ ['OS == "mac"', {
+ 'xcode_settings': {
+ 'MACOSX_DEPLOYMENT_TARGET': '10.9',
+ 'OTHER_CFLAGS': [
+ '-std=c++11',
+ '-stdlib=libc++'
+ ]
+ }
+ }],
+ ['OS != "mac"', {
+ 'link_settings': {
+ 'libraries': [
+ '-lrt'
+ ]
+ }
+ }]
+ ],
"target_name": "grpc",
"sources": [
"ext/byte_buffer.cc",
diff --git a/src/node/examples/qps_test.js b/src/node/examples/qps_test.js
new file mode 100644
index 0000000000..00293b464a
--- /dev/null
+++ b/src/node/examples/qps_test.js
@@ -0,0 +1,136 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * This script runs a QPS test. It sends requests for a specified length of time
+ * with a specified number pending at any one time. It then outputs the measured
+ * QPS. Usage:
+ * node qps_test.js [--concurrent=count] [--time=seconds]
+ * concurrent defaults to 100 and time defaults to 10
+ */
+
+'use strict';
+
+var async = require('async');
+var parseArgs = require('minimist');
+
+var grpc = require('..');
+var testProto = grpc.load(__dirname + '/../interop/test.proto').grpc.testing;
+var interop_server = require('../interop/interop_server.js');
+
+/**
+ * Runs the QPS test. Sends requests constantly for the given number of seconds,
+ * and keeps concurrent_calls requests pending at all times. When the test ends,
+ * the callback is called with the number of calls that completed within the
+ * time limit.
+ * @param {number} concurrent_calls The number of calls to have pending
+ * simultaneously
+ * @param {number} seconds The number of seconds to run the test for
+ * @param {function(Error, number)} callback Callback for test completion
+ */
+function runTest(concurrent_calls, seconds, callback) {
+ var testServer = interop_server.getServer(0, false);
+ testServer.server.listen();
+ var client = new testProto.TestService('localhost:' + testServer.port);
+
+ var warmup_num = 100;
+
+ /**
+ * Warms up the client to avoid counting startup time in the test result
+ * @param {function(Error)} callback Called when warmup is complete
+ */
+ function warmUp(callback) {
+ var pending = warmup_num;
+ function startCall() {
+ client.emptyCall({}, function(err, resp) {
+ if (err) {
+ callback(err);
+ return;
+ }
+ pending--;
+ if (pending === 0) {
+ callback(null);
+ }
+ });
+ }
+ for (var i = 0; i < warmup_num; i++) {
+ startCall();
+ }
+ }
+ /**
+ * Run the QPS test. Starts concurrent_calls requests, then starts a new
+ * request whenever one completes until time runs out.
+ * @param {function(Error, number)} callback Called when the test is complete.
+ * The second argument is the number of calls that finished within the
+ * time limit
+ */
+ function run(callback) {
+ var running = 0;
+ var count = 0;
+ var start = process.hrtime();
+ function responseCallback(err, resp) {
+ if (process.hrtime(start)[0] < seconds) {
+ count += 1;
+ client.emptyCall({}, responseCallback);
+ } else {
+ running -= 1;
+ if (running <= 0) {
+ callback(null, count);
+ }
+ }
+ }
+ for (var i = 0; i < concurrent_calls; i++) {
+ running += 1;
+ client.emptyCall({}, responseCallback);
+ }
+ }
+ async.waterfall([warmUp, run], function(err, count) {
+ testServer.server.shutdown();
+ callback(err, count);
+ });
+}
+
+if (require.main === module) {
+ var argv = parseArgs(process.argv.slice(2), {
+ default: {'concurrent': 100,
+ 'time': 10}
+ });
+ runTest(argv.concurrent, argv.time, function(err, count) {
+ if (err) {
+ throw err;
+ }
+ console.log('Concurrent calls:', argv.concurrent);
+ console.log('Time:', argv.time, 'seconds');
+ console.log('QPS:', (count/argv.time));
+ });
+}
diff --git a/src/node/ext/byte_buffer.cc b/src/node/ext/byte_buffer.cc
index 82b54b518c..01bd92ea52 100644
--- a/src/node/ext/byte_buffer.cc
+++ b/src/node/ext/byte_buffer.cc
@@ -32,7 +32,6 @@
*/
#include <string.h>
-#include <malloc.h>
#include <node.h>
#include <nan.h>
diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc
index 787e274973..d37bf763dd 100644
--- a/src/node/ext/channel.cc
+++ b/src/node/ext/channel.cc
@@ -31,8 +31,6 @@
*
*/
-#include <malloc.h>
-
#include <vector>
#include <node.h>
diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc
index e47bac833b..3c2396b810 100644
--- a/src/node/ext/server.cc
+++ b/src/node/ext/server.cc
@@ -38,8 +38,6 @@
#include <node.h>
#include <nan.h>
-#include <malloc.h>
-
#include <vector>
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
diff --git a/src/node/index.js b/src/node/index.js
index ad3dd96af7..0b768edc6b 100644
--- a/src/node/index.js
+++ b/src/node/index.js
@@ -56,7 +56,7 @@ function loadObject(value) {
});
return result;
} else if (value.className === 'Service') {
- return client.makeClientConstructor(value);
+ return client.makeProtobufClientConstructor(value);
} else if (value.className === 'Message' || value.className === 'Enum') {
return value.build();
} else {
@@ -119,7 +119,7 @@ exports.load = load;
/**
* See docs for server.makeServerConstructor
*/
-exports.buildServer = server.makeServerConstructor;
+exports.buildServer = server.makeProtobufServerConstructor;
/**
* Status name to code number mapping
@@ -141,3 +141,7 @@ exports.Credentials = grpc.Credentials;
exports.ServerCredentials = grpc.ServerCredentials;
exports.getGoogleAuthDelegate = getGoogleAuthDelegate;
+
+exports.makeGenericClientConstructor = client.makeClientConstructor;
+
+exports.makeGenericServerConstructor = server.makeServerConstructor;
diff --git a/src/node/interop/interop_client.js b/src/node/interop/interop_client.js
index 8060baf827..3341486b9e 100644
--- a/src/node/interop/interop_client.js
+++ b/src/node/interop/interop_client.js
@@ -35,6 +35,7 @@
var fs = require('fs');
var path = require('path');
+var _ = require('underscore');
var grpc = require('..');
var testProto = grpc.load(__dirname + '/test.proto').grpc.testing;
var GoogleAuth = require('google-auth-library');
@@ -45,6 +46,8 @@ var AUTH_SCOPE = 'https://www.googleapis.com/auth/xapi.zoo';
var AUTH_SCOPE_RESPONSE = 'xapi.zoo';
var AUTH_USER = ('155450119199-3psnrh1sdr3d8cpj1v46naggf81mhdnk' +
'@developer.gserviceaccount.com');
+var COMPUTE_ENGINE_USER = ('155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel' +
+ '@developer.gserviceaccount.com');
/**
* Create a buffer filled with size zeroes
@@ -265,11 +268,12 @@ function cancelAfterFirstResponse(client, done) {
/**
* Run one of the authentication tests.
+ * @param {string} expected_user The expected username in the response
* @param {Client} client The client to test against
* @param {function} done Callback to call when the test is completed. Included
* primarily for use with mocha
*/
-function authTest(client, done) {
+function authTest(expected_user, client, done) {
(new GoogleAuth()).getApplicationDefault(function(err, credential) {
assert.ifError(err);
if (credential.createScopedRequired()) {
@@ -290,7 +294,7 @@ function authTest(client, done) {
assert.strictEqual(resp.payload.type, testProto.PayloadType.COMPRESSABLE);
assert.strictEqual(resp.payload.body.limit - resp.payload.body.offset,
314159);
- assert.strictEqual(resp.username, AUTH_USER);
+ assert.strictEqual(resp.username, expected_user);
assert.strictEqual(resp.oauth_scope, AUTH_SCOPE_RESPONSE);
});
call.on('status', function(status) {
@@ -314,8 +318,8 @@ var test_cases = {
empty_stream: emptyStream,
cancel_after_begin: cancelAfterBegin,
cancel_after_first_response: cancelAfterFirstResponse,
- compute_engine_creds: authTest,
- service_account_creds: authTest
+ compute_engine_creds: _.partial(authTest, COMPUTE_ENGINE_USER),
+ service_account_creds: _.partial(authTest, AUTH_USER)
};
/**
diff --git a/src/node/src/client.js b/src/node/src/client.js
index 54b8dbdc9c..fad369c2f8 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -35,9 +35,6 @@
var _ = require('underscore');
-var capitalize = require('underscore.string/capitalize');
-var decapitalize = require('underscore.string/decapitalize');
-
var grpc = require('bindings')('grpc.node');
var common = require('./common.js');
@@ -244,13 +241,13 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
callback(err);
return;
}
+ emitter.emit('status', response.status);
if (response.status.code !== grpc.status.OK) {
var error = new Error(response.status.details);
error.code = response.status.code;
callback(error);
return;
}
- emitter.emit('status', response.status);
emitter.emit('metadata', response.metadata);
callback(null, deserialize(response.read));
});
@@ -315,13 +312,13 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) {
callback(err);
return;
}
+ stream.emit('status', response.status);
if (response.status.code !== grpc.status.OK) {
var error = new Error(response.status.details);
error.code = response.status.code;
callback(error);
return;
}
- stream.emit('status', response.status);
callback(null, deserialize(response.read));
});
});
@@ -463,13 +460,18 @@ var requester_makers = {
};
/**
- * Creates a constructor for clients for the given service
- * @param {ProtoBuf.Reflect.Service} service The service to generate a client
- * for
+ * Creates a constructor for a client with the given methods. The methods object
+ * maps method name to an object with the following keys:
+ * path: The path on the server for accessing the method. For example, for
+ * protocol buffers, we use "/service_name/method_name"
+ * requestStream: bool indicating whether the client sends a stream
+ * resonseStream: bool indicating whether the server sends a stream
+ * requestSerialize: function to serialize request objects
+ * responseDeserialize: function to deserialize response objects
+ * @param {Object} methods An object mapping method names to method attributes
* @return {function(string, Object)} New client constructor
*/
-function makeClientConstructor(service) {
- var prefix = '/' + common.fullyQualifiedName(service) + '/';
+function makeClientConstructor(methods) {
/**
* Create a client with the given methods
* @constructor
@@ -489,30 +491,41 @@ function makeClientConstructor(service) {
this.channel = new grpc.Channel(address, options);
}
- _.each(service.children, function(method) {
+ _.each(methods, function(attrs, name) {
var method_type;
- if (method.requestStream) {
- if (method.responseStream) {
+ if (attrs.requestStream) {
+ if (attrs.responseStream) {
method_type = 'bidi';
} else {
method_type = 'client_stream';
}
} else {
- if (method.responseStream) {
+ if (attrs.responseStream) {
method_type = 'server_stream';
} else {
method_type = 'unary';
}
}
- var serialize = common.serializeCls(method.resolvedRequestType.build());
- var deserialize = common.deserializeCls(
- method.resolvedResponseType.build());
- Client.prototype[decapitalize(method.name)] = requester_makers[method_type](
- prefix + capitalize(method.name), serialize, deserialize);
- Client.prototype[decapitalize(method.name)].serialize = serialize;
- Client.prototype[decapitalize(method.name)].deserialize = deserialize;
+ var serialize = attrs.requestSerialize;
+ var deserialize = attrs.responseDeserialize;
+ Client.prototype[name] = requester_makers[method_type](
+ attrs.path, serialize, deserialize);
+ Client.prototype[name].serialize = serialize;
+ Client.prototype[name].deserialize = deserialize;
});
+ return Client;
+}
+
+/**
+ * Creates a constructor for clients for the given service
+ * @param {ProtoBuf.Reflect.Service} service The service to generate a client
+ * for
+ * @return {function(string, Object)} New client constructor
+ */
+function makeProtobufClientConstructor(service) {
+ var method_attrs = common.getProtobufServiceAttrs(service);
+ var Client = makeClientConstructor(method_attrs);
Client.service = service;
return Client;
@@ -520,6 +533,8 @@ function makeClientConstructor(service) {
exports.makeClientConstructor = makeClientConstructor;
+exports.makeProtobufClientConstructor = makeProtobufClientConstructor;
+
/**
* See docs for client.status
*/
diff --git a/src/node/src/common.js b/src/node/src/common.js
index eec8f0f987..55a6b13782 100644
--- a/src/node/src/common.js
+++ b/src/node/src/common.js
@@ -36,6 +36,7 @@
var _ = require('underscore');
var capitalize = require('underscore.string/capitalize');
+var decapitalize = require('underscore.string/decapitalize');
/**
* Get a function that deserializes a specific type of protobuf.
@@ -110,6 +111,26 @@ function wrapIgnoreNull(func) {
}
/**
+ * Return a map from method names to method attributes for the service.
+ * @param {ProtoBuf.Reflect.Service} service The service to get attributes for
+ * @return {Object} The attributes map
+ */
+function getProtobufServiceAttrs(service) {
+ var prefix = '/' + fullyQualifiedName(service) + '/';
+ return _.object(_.map(service.children, function(method) {
+ return [decapitalize(method.name), {
+ path: prefix + capitalize(method.name),
+ requestStream: method.requestStream,
+ responseStream: method.responseStream,
+ requestSerialize: serializeCls(method.resolvedRequestType.build()),
+ requestDeserialize: deserializeCls(method.resolvedRequestType.build()),
+ responseSerialize: serializeCls(method.resolvedResponseType.build()),
+ responseDeserialize: deserializeCls(method.resolvedResponseType.build())
+ }];
+ }));
+}
+
+/**
* See docs for deserializeCls
*/
exports.deserializeCls = deserializeCls;
@@ -128,3 +149,5 @@ exports.fullyQualifiedName = fullyQualifiedName;
* See docs for wrapIgnoreNull
*/
exports.wrapIgnoreNull = wrapIgnoreNull;
+
+exports.getProtobufServiceAttrs = getProtobufServiceAttrs;
diff --git a/src/node/src/server.js b/src/node/src/server.js
index b72d110666..05de16294d 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -35,9 +35,6 @@
var _ = require('underscore');
-var capitalize = require('underscore.string/capitalize');
-var decapitalize = require('underscore.string/decapitalize');
-
var grpc = require('bindings')('grpc.node');
var common = require('./common');
@@ -73,6 +70,9 @@ function handleError(call, error) {
status.details = error.details;
}
}
+ if (error.hasOwnProperty('metadata')) {
+ status.metadata = error.metadata;
+ }
var error_batch = {};
error_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = status;
call.startBatch(error_batch, function(){});
@@ -105,15 +105,20 @@ function waitForCancel(call, emitter) {
* @param {*} value The value to respond with
* @param {function(*):Buffer=} serialize Serialization function for the
* response
+ * @param {Object=} metadata Optional trailing metadata to send with status
*/
-function sendUnaryResponse(call, value, serialize) {
+function sendUnaryResponse(call, value, serialize, metadata) {
var end_batch = {};
- end_batch[grpc.opType.SEND_MESSAGE] = serialize(value);
- end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
+ var status = {
code: grpc.status.OK,
details: 'OK',
metadata: {}
};
+ if (metadata) {
+ status.metadata = metadata;
+ }
+ end_batch[grpc.opType.SEND_MESSAGE] = serialize(value);
+ end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = status;
call.startBatch(end_batch, function (){});
}
@@ -146,6 +151,7 @@ function setUpWritable(stream, serialize) {
function setStatus(err) {
var code = grpc.status.INTERNAL;
var details = 'Unknown Error';
+ var metadata = {};
if (err.hasOwnProperty('message')) {
details = err.message;
}
@@ -155,7 +161,10 @@ function setUpWritable(stream, serialize) {
details = err.details;
}
}
- stream.status = {code: code, details: details, metadata: {}};
+ if (err.hasOwnProperty('metadata')) {
+ metadata = err.metadata;
+ }
+ stream.status = {code: code, details: details, metadata: metadata};
}
/**
* Terminate the call. This includes indicating that reads are done, draining
@@ -169,6 +178,17 @@ function setUpWritable(stream, serialize) {
stream.end();
}
stream.on('error', terminateCall);
+ /**
+ * Override of Writable#end method that allows for sending metadata with a
+ * success status.
+ * @param {Object=} metadata Metadata to send with the status
+ */
+ stream.end = function(metadata) {
+ if (metadata) {
+ stream.status.metadata = metadata;
+ }
+ Writable.prototype.end.call(this);
+ };
}
/**
@@ -338,11 +358,13 @@ function handleUnary(call, handler, metadata) {
if (emitter.cancelled) {
return;
}
- handler.func(emitter, function sendUnaryData(err, value) {
+ handler.func(emitter, function sendUnaryData(err, value, trailer) {
if (err) {
+ err.metadata = trailer;
handleError(call, err);
+ } else {
+ sendUnaryResponse(call, value, handler.serialize, trailer);
}
- sendUnaryResponse(call, value, handler.serialize);
});
});
}
@@ -381,12 +403,14 @@ function handleClientStreaming(call, handler, metadata) {
var metadata_batch = {};
metadata_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
call.startBatch(metadata_batch, function() {});
- handler.func(stream, function(err, value) {
+ handler.func(stream, function(err, value, trailer) {
stream.terminate();
if (err) {
+ err.metadata = trailer;
handleError(call, err);
+ } else {
+ sendUnaryResponse(call, value, handler.serialize, trailer);
}
- sendUnaryResponse(call, value, handler.serialize);
});
}
@@ -532,26 +556,20 @@ Server.prototype.bind = function(port, creds) {
};
/**
- * Creates a constructor for servers with a service defined by the methods
- * object. The methods object has string keys and values of this form:
- * {serialize: function, deserialize: function, client_stream: bool,
- * server_stream: bool}
- * @param {Object} methods Method descriptor for each method the server should
- * expose
- * @param {string} prefix The prefex to prepend to each method name
- * @return {function(Object, Object)} New server constructor
+ * Create a constructor for servers with services defined by service_attr_map.
+ * That is an object that maps (namespaced) service names to objects that in
+ * turn map method names to objects with the following keys:
+ * path: The path on the server for accessing the method. For example, for
+ * protocol buffers, we use "/service_name/method_name"
+ * requestStream: bool indicating whether the client sends a stream
+ * resonseStream: bool indicating whether the server sends a stream
+ * requestDeserialize: function to deserialize request objects
+ * responseSerialize: function to serialize response objects
+ * @param {Object} service_attr_map An object mapping service names to method
+ * attribute map objects
+ * @return {function(Object, function, Object=)} New server constructor
*/
-function makeServerConstructor(services) {
- var qual_names = [];
- _.each(services, function(service) {
- _.each(service.children, function(method) {
- var name = common.fullyQualifiedName(method);
- if (_.indexOf(qual_names, name) !== -1) {
- throw new Error('Method ' + name + ' exposed by more than one service');
- }
- qual_names.push(name);
- });
- });
+function makeServerConstructor(service_attr_map) {
/**
* Create a server with the given handlers for all of the methods.
* @constructor
@@ -565,41 +583,34 @@ function makeServerConstructor(services) {
function SurfaceServer(service_handlers, getMetadata, options) {
var server = new Server(getMetadata, options);
this.inner_server = server;
- _.each(services, function(service) {
- var service_name = common.fullyQualifiedName(service);
+ _.each(service_attr_map, function(service_attrs, service_name) {
if (service_handlers[service_name] === undefined) {
throw new Error('Handlers for service ' +
service_name + ' not provided.');
}
- var prefix = '/' + common.fullyQualifiedName(service) + '/';
- _.each(service.children, function(method) {
+ _.each(service_attrs, function(attrs, name) {
var method_type;
- if (method.requestStream) {
- if (method.responseStream) {
+ if (attrs.requestStream) {
+ if (attrs.responseStream) {
method_type = 'bidi';
} else {
method_type = 'client_stream';
}
} else {
- if (method.responseStream) {
+ if (attrs.responseStream) {
method_type = 'server_stream';
} else {
method_type = 'unary';
}
}
- if (service_handlers[service_name][decapitalize(method.name)] ===
- undefined) {
- throw new Error('Method handler for ' +
- common.fullyQualifiedName(method) + ' not provided.');
+ if (service_handlers[service_name][name] === undefined) {
+ throw new Error('Method handler for ' + attrs.path +
+ ' not provided.');
}
- var serialize = common.serializeCls(
- method.resolvedResponseType.build());
- var deserialize = common.deserializeCls(
- method.resolvedRequestType.build());
- server.register(
- prefix + capitalize(method.name),
- service_handlers[service_name][decapitalize(method.name)],
- serialize, deserialize, method_type);
+ var serialize = attrs.responseSerialize;
+ var deserialize = attrs.requestDeserialize;
+ server.register(attrs.path, service_handlers[service_name][name],
+ serialize, deserialize, method_type);
});
}, this);
}
@@ -636,6 +647,39 @@ function makeServerConstructor(services) {
}
/**
+ * Create a constructor for servers that serve the given services.
+ * @param {Array<ProtoBuf.Reflect.Service>} services The services that the
+ * servers will serve
+ * @return {function(Object, function, Object=)} New server constructor
+ */
+function makeProtobufServerConstructor(services) {
+ var qual_names = [];
+ var service_attr_map = {};
+ _.each(services, function(service) {
+ var service_name = common.fullyQualifiedName(service);
+ _.each(service.children, function(method) {
+ var name = common.fullyQualifiedName(method);
+ if (_.indexOf(qual_names, name) !== -1) {
+ throw new Error('Method ' + name + ' exposed by more than one service');
+ }
+ qual_names.push(name);
+ });
+ var method_attrs = common.getProtobufServiceAttrs(service);
+ if (!service_attr_map.hasOwnProperty(service_name)) {
+ service_attr_map[service_name] = {};
+ }
+ service_attr_map[service_name] = _.extend(service_attr_map[service_name],
+ method_attrs);
+ });
+ return makeServerConstructor(service_attr_map);
+}
+
+/**
* See documentation for makeServerConstructor
*/
exports.makeServerConstructor = makeServerConstructor;
+
+/**
+ * See documentation for makeProtobufServerConstructor
+ */
+exports.makeProtobufServerConstructor = makeProtobufServerConstructor;
diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js
index 91d8197bee..590c644c71 100644
--- a/src/node/test/surface_test.js
+++ b/src/node/test/surface_test.js
@@ -45,6 +45,8 @@ var math_proto = ProtoBuf.loadProtoFile(__dirname + '/../examples/math.proto');
var mathService = math_proto.lookup('math.Math');
+var capitalize = require('underscore.string/capitalize');
+
describe('Surface server constructor', function() {
it('Should fail with conflicting method names', function() {
assert.throws(function() {
@@ -75,6 +77,216 @@ describe('Surface server constructor', function() {
}, /math.Math/);
});
});
+describe('Generic client and server', function() {
+ function toString(val) {
+ return val.toString();
+ }
+ function toBuffer(str) {
+ return new Buffer(str);
+ }
+ var string_service_attrs = {
+ 'capitalize' : {
+ path: '/string/capitalize',
+ requestStream: false,
+ responseStream: false,
+ requestSerialize: toBuffer,
+ requestDeserialize: toString,
+ responseSerialize: toBuffer,
+ responseDeserialize: toString
+ }
+ };
+ describe('String client and server', function() {
+ var client;
+ var server;
+ before(function() {
+ var Server = grpc.makeGenericServerConstructor({
+ string: string_service_attrs
+ });
+ server = new Server({
+ string: {
+ capitalize: function(call, callback) {
+ callback(null, capitalize(call.request));
+ }
+ }
+ });
+ var port = server.bind('localhost:0');
+ server.listen();
+ var Client = grpc.makeGenericClientConstructor(string_service_attrs);
+ client = new Client('localhost:' + port);
+ });
+ after(function() {
+ server.shutdown();
+ });
+ it('Should respond with a capitalized string', function(done) {
+ client.capitalize('abc', function(err, response) {
+ assert.ifError(err);
+ assert.strictEqual(response, 'Abc');
+ done();
+ });
+ });
+ });
+});
+describe('Trailing metadata', function() {
+ var client;
+ var server;
+ before(function() {
+ var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto');
+ var test_service = test_proto.lookup('TestService');
+ var Server = grpc.buildServer([test_service]);
+ server = new Server({
+ TestService: {
+ unary: function(call, cb) {
+ var req = call.request;
+ if (req.error) {
+ cb(new Error('Requested error'), null, {metadata: ['yes']});
+ } else {
+ cb(null, {count: 1}, {metadata: ['yes']});
+ }
+ },
+ clientStream: function(stream, cb){
+ var count = 0;
+ var errored;
+ stream.on('data', function(data) {
+ if (data.error) {
+ errored = true;
+ cb(new Error('Requested error'), null, {metadata: ['yes']});
+ } else {
+ count += 1;
+ }
+ });
+ stream.on('end', function() {
+ if (!errored) {
+ cb(null, {count: count}, {metadata: ['yes']});
+ }
+ });
+ },
+ serverStream: function(stream) {
+ var req = stream.request;
+ if (req.error) {
+ var err = new Error('Requested error');
+ err.metadata = {metadata: ['yes']};
+ stream.emit('error', err);
+ } else {
+ for (var i = 0; i < 5; i++) {
+ stream.write({count: i});
+ }
+ stream.end({metadata: ['yes']});
+ }
+ },
+ bidiStream: function(stream) {
+ var count = 0;
+ stream.on('data', function(data) {
+ if (data.error) {
+ var err = new Error('Requested error');
+ err.metadata = {
+ metadata: ['yes'],
+ count: ['' + count]
+ };
+ stream.emit('error', err);
+ } else {
+ stream.write({count: count});
+ count += 1;
+ }
+ });
+ stream.on('end', function() {
+ stream.end({metadata: ['yes']});
+ });
+ }
+ }
+ });
+ var port = server.bind('localhost:0');
+ var Client = surface_client.makeProtobufClientConstructor(test_service);
+ client = new Client('localhost:' + port);
+ server.listen();
+ });
+ after(function() {
+ server.shutdown();
+ });
+ it('should be present when a unary call succeeds', function(done) {
+ var call = client.unary({error: false}, function(err, data) {
+ assert.ifError(err);
+ });
+ call.on('status', function(status) {
+ assert.deepEqual(status.metadata.metadata, ['yes']);
+ done();
+ });
+ });
+ it('should be present when a unary call fails', function(done) {
+ var call = client.unary({error: true}, function(err, data) {
+ assert(err);
+ });
+ call.on('status', function(status) {
+ assert.deepEqual(status.metadata.metadata, ['yes']);
+ done();
+ });
+ });
+ it('should be present when a client stream call succeeds', function(done) {
+ var call = client.clientStream(function(err, data) {
+ assert.ifError(err);
+ });
+ call.write({error: false});
+ call.write({error: false});
+ call.end();
+ call.on('status', function(status) {
+ assert.deepEqual(status.metadata.metadata, ['yes']);
+ done();
+ });
+ });
+ it('should be present when a client stream call fails', function(done) {
+ var call = client.clientStream(function(err, data) {
+ assert(err);
+ });
+ call.write({error: false});
+ call.write({error: true});
+ call.end();
+ call.on('status', function(status) {
+ assert.deepEqual(status.metadata.metadata, ['yes']);
+ done();
+ });
+ });
+ it('should be present when a server stream call succeeds', function(done) {
+ var call = client.serverStream({error: false});
+ call.on('data', function(){});
+ call.on('status', function(status) {
+ assert.strictEqual(status.code, grpc.status.OK);
+ assert.deepEqual(status.metadata.metadata, ['yes']);
+ done();
+ });
+ });
+ it('should be present when a server stream call fails', function(done) {
+ var call = client.serverStream({error: true});
+ call.on('data', function(){});
+ call.on('status', function(status) {
+ assert.notStrictEqual(status.code, grpc.status.OK);
+ assert.deepEqual(status.metadata.metadata, ['yes']);
+ done();
+ });
+ });
+ it('should be present when a bidi stream succeeds', function(done) {
+ var call = client.bidiStream();
+ call.write({error: false});
+ call.write({error: false});
+ call.end();
+ call.on('data', function(){});
+ call.on('status', function(status) {
+ assert.strictEqual(status.code, grpc.status.OK);
+ assert.deepEqual(status.metadata.metadata, ['yes']);
+ done();
+ });
+ });
+ it('should be present when a bidi stream fails', function(done) {
+ var call = client.bidiStream();
+ call.write({error: false});
+ call.write({error: true});
+ call.end();
+ call.on('data', function(){});
+ call.on('status', function(status) {
+ assert.notStrictEqual(status.code, grpc.status.OK);
+ assert.deepEqual(status.metadata.metadata, ['yes']);
+ done();
+ });
+ });
+});
describe('Cancelling surface client', function() {
var client;
var server;
@@ -89,7 +301,7 @@ describe('Cancelling surface client', function() {
}
});
var port = server.bind('localhost:0');
- var Client = surface_client.makeClientConstructor(mathService);
+ var Client = surface_client.makeProtobufClientConstructor(mathService);
client = new Client('localhost:' + port);
});
after(function() {
diff --git a/src/node/test/test_service.proto b/src/node/test/test_service.proto
new file mode 100644
index 0000000000..5d3d891841
--- /dev/null
+++ b/src/node/test/test_service.proto
@@ -0,0 +1,52 @@
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+
+message Request {
+ optional bool error = 1;
+}
+
+message Response {
+ optional int32 count = 1;
+}
+
+service TestService {
+ rpc Unary (Request) returns (Response) {
+ }
+
+ rpc ClientStream (stream Request) returns (Response) {
+ }
+
+ rpc ServerStream (Request) returns (stream Response) {
+ }
+
+ rpc BidiStream (stream Request) returns (stream Response) {
+ }
+} \ No newline at end of file
diff --git a/src/php/bin/generate_proto_php.sh b/src/php/bin/generate_proto_php.sh
new file mode 100755
index 0000000000..16f93747ab
--- /dev/null
+++ b/src/php/bin/generate_proto_php.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+set +e
+cd $(dirname $0)
+
+gen_code='../tests/generated_code'
+interop='../tests/interop'
+
+protoc-gen-php -i $gen_code -o $gen_code $gen_code/math.proto
+
+protoc-gen-php -i $interop -o $interop $interop/test.proto
diff --git a/src/php/bin/interop_client.sh b/src/php/bin/interop_client.sh
index 2c61ea8aa0..22e4a493c4 100755
--- a/src/php/bin/interop_client.sh
+++ b/src/php/bin/interop_client.sh
@@ -31,5 +31,8 @@
set +e
cd $(dirname $0)
-php -d extension_dir=../ext/grpc/modules/ -d extension=grpc.so \
+
+module_dir=`php --version | grep -q 'PHP 5.6' && echo '../ext/grpc' || echo '../ext/grpc/modules'`
+
+php -d extension_dir=$module_dir -d extension=grpc.so \
../tests/interop/interop_client.php $@ 1>&2
diff --git a/src/php/bin/run_tests.sh b/src/php/bin/run_tests.sh
index c3358ed899..1335672e9e 100755
--- a/src/php/bin/run_tests.sh
+++ b/src/php/bin/run_tests.sh
@@ -34,13 +34,15 @@ set -e
cd $(dirname $0)
default_extension_dir=`php -i | grep extension_dir | sed 's/.*=> //g'`
+module_dir=`php --version | grep -q 'PHP 5.6' && echo '../ext/grpc' || echo '../ext/grpc/modules'`
+
# sym-link in system supplied extensions
for f in $default_extension_dir/*.so
do
- ln -s $f ../ext/grpc/modules/$(basename $f) &> /dev/null || true
+ ln -s $f $module_dir/$(basename $f) &> /dev/null || true
done
php \
- -d extension_dir=../ext/grpc/modules/ \
+ -d extension_dir=$module_dir \
-d extension=grpc.so \
`which phpunit` -v --debug --strict ../tests/unit_tests
diff --git a/src/php/composer.json b/src/php/composer.json
new file mode 100644
index 0000000000..3c0cb37231
--- /dev/null
+++ b/src/php/composer.json
@@ -0,0 +1,15 @@
+{
+ "name": "grpc/grpc",
+ "description": "gRPC library for PHP",
+ "version": "0.5.0",
+ "homepage": "http://grpc.io",
+ "license": "BSD-3-Clause",
+ "require": {
+ "php": ">=5.5.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Grpc\\": "lib/Grpc/"
+ }
+ }
+}
diff --git a/src/php/composer.lock b/src/php/composer.lock
new file mode 100644
index 0000000000..47fc70fd2d
--- /dev/null
+++ b/src/php/composer.lock
@@ -0,0 +1,19 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "hash": "65467a098f5fd8b8fe5f7f6e10226f8a",
+ "packages": [],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=5.5.0"
+ },
+ "platform-dev": []
+}
diff --git a/src/php/ext/grpc/byte_buffer.c b/src/php/ext/grpc/byte_buffer.c
index 1ced1bf3f0..4f3e6b67af 100644
--- a/src/php/ext/grpc/byte_buffer.c
+++ b/src/php/ext/grpc/byte_buffer.c
@@ -35,18 +35,18 @@
#include "config.h"
#endif
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "ext/spl/spl_exceptions.h"
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
+#include <ext/spl/spl_exceptions.h>
#include "php_grpc.h"
#include <string.h>
#include "byte_buffer.h"
-#include "grpc/grpc.h"
-#include "grpc/support/slice.h"
+#include <grpc/grpc.h>
+#include <grpc/support/slice.h>
grpc_byte_buffer *string_to_byte_buffer(char *string, size_t length) {
gpr_slice slice = gpr_slice_from_copied_buffer(string, length);
@@ -57,6 +57,11 @@ grpc_byte_buffer *string_to_byte_buffer(char *string, size_t length) {
void byte_buffer_to_string(grpc_byte_buffer *buffer, char **out_string,
size_t *out_length) {
+ if (buffer == NULL) {
+ *out_string = NULL;
+ *out_length = 0;
+ return;
+ }
size_t length = grpc_byte_buffer_length(buffer);
char *string = ecalloc(length + 1, sizeof(char));
size_t offset = 0;
diff --git a/src/php/ext/grpc/byte_buffer.h b/src/php/ext/grpc/byte_buffer.h
index 7a40638591..0e9d1e7145 100644
--- a/src/php/ext/grpc/byte_buffer.h
+++ b/src/php/ext/grpc/byte_buffer.h
@@ -34,7 +34,7 @@
#ifndef NET_GRPC_PHP_GRPC_BYTE_BUFFER_H_
#define NET_GRPC_PHP_GRPC_BYTE_BUFFER_H_
-#include "grpc/grpc.h"
+#include <grpc/grpc.h>
grpc_byte_buffer *string_to_byte_buffer(char *string, size_t length);
diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index 798747109a..b1525e9246 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -37,23 +37,23 @@
#include "config.h"
#endif
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "ext/spl/spl_exceptions.h"
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
+#include <ext/spl/spl_exceptions.h>
#include "php_grpc.h"
-#include "zend_exceptions.h"
-#include "zend_hash.h"
+#include <zend_exceptions.h>
+#include <zend_hash.h>
#include <stdbool.h>
-#include "grpc/support/log.h"
-#include "grpc/grpc.h"
+#include <grpc/support/log.h>
+#include <grpc/support/alloc.h>
+#include <grpc/grpc.h>
#include "timeval.h"
#include "channel.h"
-#include "completion_queue.h"
#include "byte_buffer.h"
zend_class_entry *grpc_ce_call;
@@ -61,7 +61,19 @@ zend_class_entry *grpc_ce_call;
/* Frees and destroys an instance of wrapped_grpc_call */
void free_wrapped_grpc_call(void *object TSRMLS_DC) {
wrapped_grpc_call *call = (wrapped_grpc_call *)object;
+ grpc_event *event;
if (call->owned && call->wrapped != NULL) {
+ if (call->queue != NULL) {
+ grpc_completion_queue_shutdown(call->queue);
+ event = grpc_completion_queue_next(call->queue, gpr_inf_future);
+ while (event != NULL) {
+ if (event->type == GRPC_QUEUE_SHUTDOWN) {
+ break;
+ }
+ event = grpc_completion_queue_next(call->queue, gpr_inf_future);
+ }
+ grpc_completion_queue_destroy(call->queue);
+ }
grpc_call_destroy(call->wrapped);
}
efree(call);
@@ -88,17 +100,23 @@ zend_object_value create_wrapped_grpc_call(zend_class_entry *class_type
/* Wraps a grpc_call struct in a PHP object. Owned indicates whether the struct
should be destroyed at the end of the object's lifecycle */
-zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned) {
+zval *grpc_php_wrap_call(grpc_call *wrapped, grpc_completion_queue *queue,
+ bool owned) {
zval *call_object;
MAKE_STD_ZVAL(call_object);
object_init_ex(call_object, grpc_ce_call);
wrapped_grpc_call *call =
(wrapped_grpc_call *)zend_object_store_get_object(call_object TSRMLS_CC);
call->wrapped = wrapped;
+ call->queue = queue;
return call_object;
}
-zval *grpc_call_create_metadata_array(int count, grpc_metadata *elements) {
+/* Creates and returns a PHP array object with the data in a
+ * grpc_metadata_array. Returns NULL on failure */
+zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array) {
+ int count = metadata_array->count;
+ grpc_metadata *elements = metadata_array->metadata;
int i;
zval *array;
zval **data = NULL;
@@ -139,6 +157,64 @@ zval *grpc_call_create_metadata_array(int count, grpc_metadata *elements) {
return array;
}
+/* Populates a grpc_metadata_array with the data in a PHP array object.
+ Returns true on success and false on failure */
+bool create_metadata_array(zval *array, grpc_metadata_array *metadata) {
+ zval **inner_array;
+ zval **value;
+ HashTable *array_hash;
+ HashPosition array_pointer;
+ HashTable *inner_array_hash;
+ HashPosition inner_array_pointer;
+ char *key;
+ uint key_len;
+ ulong index;
+ if (Z_TYPE_P(array) != IS_ARRAY) {
+ return false;
+ }
+ grpc_metadata_array_init(metadata);
+ array_hash = Z_ARRVAL_P(array);
+ for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer);
+ zend_hash_get_current_data_ex(array_hash, (void**)&inner_array,
+ &array_pointer) == SUCCESS;
+ zend_hash_move_forward_ex(array_hash, &array_pointer)) {
+ if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0,
+ &array_pointer) != HASH_KEY_IS_STRING) {
+ return false;
+ }
+ if (Z_TYPE_P(*inner_array) != IS_ARRAY) {
+ return false;
+ }
+ inner_array_hash = Z_ARRVAL_P(*inner_array);
+ metadata->capacity += zend_hash_num_elements(inner_array_hash);
+ }
+ metadata->metadata = gpr_malloc(metadata->capacity * sizeof(grpc_metadata));
+ for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer);
+ zend_hash_get_current_data_ex(array_hash, (void**)&inner_array,
+ &array_pointer) == SUCCESS;
+ zend_hash_move_forward_ex(array_hash, &array_pointer)) {
+ if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0,
+ &array_pointer) != HASH_KEY_IS_STRING) {
+ return false;
+ }
+ inner_array_hash = Z_ARRVAL_P(*inner_array);
+ for (zend_hash_internal_pointer_reset_ex(inner_array_hash,
+ &inner_array_pointer);
+ zend_hash_get_current_data_ex(inner_array_hash, (void**)&value,
+ &inner_array_pointer) == SUCCESS;
+ zend_hash_move_forward_ex(inner_array_hash, &inner_array_pointer)) {
+ if (Z_TYPE_P(*value) != IS_STRING) {
+ return false;
+ }
+ metadata->metadata[metadata->count].key = key;
+ metadata->metadata[metadata->count].value = Z_STRVAL_P(*value);
+ metadata->metadata[metadata->count].value_length = Z_STRLEN_P(*value);
+ metadata->count += 1;
+ }
+ }
+ return true;
+}
+
/**
* Constructs a new instance of the Call class.
* @param Channel $channel The channel to associate the call with. Must not be
@@ -157,9 +233,10 @@ PHP_METHOD(Call, __construct) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OsO", &channel_obj,
grpc_ce_channel, &method, &method_len,
&deadline_obj, grpc_ce_timeval) == FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "Call expects a Channel, a String, and a Timeval",
- 1 TSRMLS_CC);
+ zend_throw_exception(
+ spl_ce_InvalidArgumentException,
+ "Call expects a Channel, a String, and a Timeval",
+ 1 TSRMLS_CC);
return;
}
wrapped_grpc_channel *channel =
@@ -175,289 +252,253 @@ PHP_METHOD(Call, __construct) {
wrapped_grpc_timeval *deadline =
(wrapped_grpc_timeval *)zend_object_store_get_object(
deadline_obj TSRMLS_CC);
- call->wrapped = grpc_channel_create_call_old(
- channel->wrapped, method, channel->target, deadline->wrapped);
+ call->queue = grpc_completion_queue_create();
+ call->wrapped = grpc_channel_create_call(
+ channel->wrapped, call->queue, method, channel->target,
+ deadline->wrapped);
}
/**
- * Add metadata to the call. All array keys must be strings. If the value is a
- * string, it is added as a key/value pair. If it is an array, each value is
- * added paired with the same string
- * @param array $metadata The metadata to add
- * @param long $flags A bitwise combination of the Grpc\WRITE_* constants
- * (optional)
- * @return Void
+ * Start a batch of RPC actions.
+ * @param array batch Array of actions to take
+ * @return object Object with results of all actions
*/
-PHP_METHOD(Call, add_metadata) {
+PHP_METHOD(Call, startBatch) {
wrapped_grpc_call *call =
(wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- grpc_metadata metadata;
- grpc_call_error error_code;
+ grpc_op ops[8];
+ size_t op_num = 0;
zval *array;
- zval **inner_array;
zval **value;
+ zval **inner_value;
HashTable *array_hash;
HashPosition array_pointer;
- HashTable *inner_array_hash;
- HashPosition inner_array_pointer;
+ HashTable *status_hash;
char *key;
uint key_len;
ulong index;
- long flags = 0;
- /* "a|l" == 1 array, 1 optional long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &array, &flags) ==
+ grpc_metadata_array metadata;
+ grpc_metadata_array trailing_metadata;
+ grpc_metadata_array recv_metadata;
+ grpc_metadata_array recv_trailing_metadata;
+ grpc_status_code status;
+ char *status_details = NULL;
+ size_t status_details_capacity = 0;
+ grpc_byte_buffer *message;
+ int cancelled;
+ grpc_call_error error;
+ grpc_event *event;
+ zval *result;
+ char *message_str;
+ size_t message_len;
+ zval *recv_status;
+ grpc_metadata_array_init(&metadata);
+ grpc_metadata_array_init(&trailing_metadata);
+ grpc_metadata_array_init(&recv_metadata);
+ grpc_metadata_array_init(&recv_trailing_metadata);
+ MAKE_STD_ZVAL(result);
+ object_init(result);
+ /* "a" == 1 array */
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) ==
FAILURE) {
zend_throw_exception(spl_ce_InvalidArgumentException,
- "add_metadata expects an array and an optional long",
- 1 TSRMLS_CC);
- return;
+ "start_batch expects an array", 1 TSRMLS_CC);
+ goto cleanup;
}
array_hash = Z_ARRVAL_P(array);
for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer);
- zend_hash_get_current_data_ex(array_hash, (void**)&inner_array,
+ zend_hash_get_current_data_ex(array_hash, (void**)&value,
&array_pointer) == SUCCESS;
zend_hash_move_forward_ex(array_hash, &array_pointer)) {
if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0,
- &array_pointer) != HASH_KEY_IS_STRING) {
+ &array_pointer) != HASH_KEY_IS_LONG) {
zend_throw_exception(spl_ce_InvalidArgumentException,
- "metadata keys must be strings", 1 TSRMLS_CC);
- return;
+ "batch keys must be integers", 1 TSRMLS_CC);
+ goto cleanup;
}
- if (Z_TYPE_P(*inner_array) != IS_ARRAY) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "metadata values must be arrays",
- 1 TSRMLS_CC);
- return;
- }
- inner_array_hash = Z_ARRVAL_P(*inner_array);
- for (zend_hash_internal_pointer_reset_ex(inner_array_hash,
- &inner_array_pointer);
- zend_hash_get_current_data_ex(inner_array_hash, (void**)&value,
- &inner_array_pointer) == SUCCESS;
- zend_hash_move_forward_ex(inner_array_hash, &inner_array_pointer)) {
- if (Z_TYPE_P(*value) != IS_STRING) {
+ switch(index) {
+ case GRPC_OP_SEND_INITIAL_METADATA:
+ if (!create_metadata_array(*value, &metadata)) {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "Bad metadata value given", 1 TSRMLS_CC);
+ goto cleanup;
+ }
+ ops[op_num].data.send_initial_metadata.count =
+ metadata.count;
+ ops[op_num].data.send_initial_metadata.metadata =
+ metadata.metadata;
+ break;
+ case GRPC_OP_SEND_MESSAGE:
+ if (Z_TYPE_PP(value) != IS_STRING) {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "Expected a string for send message",
+ 1 TSRMLS_CC);
+ }
+ ops[op_num].data.send_message =
+ string_to_byte_buffer(Z_STRVAL_PP(value), Z_STRLEN_PP(value));
+ break;
+ case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
+ break;
+ case GRPC_OP_SEND_STATUS_FROM_SERVER:
+ status_hash = Z_ARRVAL_PP(value);
+ if (zend_hash_find(status_hash, "metadata", sizeof("metadata"),
+ (void **)&inner_value) == SUCCESS) {
+ if (!create_metadata_array(*inner_value, &trailing_metadata)) {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "Bad trailing metadata value given",
+ 1 TSRMLS_CC);
+ goto cleanup;
+ }
+ ops[op_num].data.send_status_from_server.trailing_metadata =
+ trailing_metadata.metadata;
+ ops[op_num].data.send_status_from_server.trailing_metadata_count =
+ trailing_metadata.count;
+ }
+ if (zend_hash_find(status_hash, "code", sizeof("code"),
+ (void**)&inner_value) == SUCCESS) {
+ if (Z_TYPE_PP(inner_value) != IS_LONG) {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "Status code must be an integer",
+ 1 TSRMLS_CC);
+ goto cleanup;
+ }
+ ops[op_num].data.send_status_from_server.status =
+ Z_LVAL_PP(inner_value);
+ } else {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "Integer status code is required",
+ 1 TSRMLS_CC);
+ goto cleanup;
+ }
+ if (zend_hash_find(status_hash, "details", sizeof("details"),
+ (void**)&inner_value) == SUCCESS) {
+ if (Z_TYPE_PP(inner_value) != IS_STRING) {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "Status details must be a string",
+ 1 TSRMLS_CC);
+ goto cleanup;
+ }
+ ops[op_num].data.send_status_from_server.status_details =
+ Z_STRVAL_PP(inner_value);
+ } else {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "String status details is required",
+ 1 TSRMLS_CC);
+ goto cleanup;
+ }
+ break;
+ case GRPC_OP_RECV_INITIAL_METADATA:
+ ops[op_num].data.recv_initial_metadata = &recv_metadata;
+ break;
+ case GRPC_OP_RECV_MESSAGE:
+ ops[op_num].data.recv_message = &message;
+ break;
+ case GRPC_OP_RECV_STATUS_ON_CLIENT:
+ ops[op_num].data.recv_status_on_client.trailing_metadata =
+ &recv_trailing_metadata;
+ ops[op_num].data.recv_status_on_client.status = &status;
+ ops[op_num].data.recv_status_on_client.status_details =
+ &status_details;
+ ops[op_num].data.recv_status_on_client.status_details_capacity =
+ &status_details_capacity;
+ break;
+ case GRPC_OP_RECV_CLOSE_ON_SERVER:
+ ops[op_num].data.recv_close_on_server.cancelled = &cancelled;
+ break;
+ default:
zend_throw_exception(spl_ce_InvalidArgumentException,
- "metadata values must be arrays of strings",
- 1 TSRMLS_CC);
- return;
- }
- metadata.key = key;
- metadata.value = Z_STRVAL_P(*value);
- metadata.value_length = Z_STRLEN_P(*value);
- error_code = grpc_call_add_metadata_old(call->wrapped, &metadata, 0u);
- MAYBE_THROW_CALL_ERROR(add_metadata, error_code);
+ "Unrecognized key in batch", 1 TSRMLS_CC);
+ goto cleanup;
}
+ ops[op_num].op = (grpc_op_type)index;
+ op_num++;
}
-}
-
-/**
- * Invoke the RPC. Starts sending metadata and request headers over the wire
- * @param CompletionQueue $queue The completion queue to use with this call
- * @param long $metadata_tag The tag to associate with returned metadata
- * @param long $finished_tag The tag to associate with the finished event
- * @param long $flags A bitwise combination of the Grpc\WRITE_* constants
- * (optional)
- * @return Void
- */
-PHP_METHOD(Call, invoke) {
- grpc_call_error error_code;
- long tag1;
- long tag2;
- zval *queue_obj;
- long flags = 0;
- /* "Oll|l" == 1 Object, 3 mandatory longs, 1 optional long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Oll|l", &queue_obj,
- grpc_ce_completion_queue, &tag1, &tag2,
- &flags) == FAILURE) {
- zend_throw_exception(
- spl_ce_InvalidArgumentException,
- "invoke needs a CompletionQueue, 2 longs, and an optional long",
- 1 TSRMLS_CC);
- return;
+ error = grpc_call_start_batch(call->wrapped, ops, op_num, call->wrapped);
+ if (error != GRPC_CALL_OK) {
+ zend_throw_exception(spl_ce_LogicException,
+ "start_batch was called incorrectly",
+ (long)error TSRMLS_CC);
+ goto cleanup;
}
- add_property_zval(getThis(), "completion_queue", queue_obj);
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- wrapped_grpc_completion_queue *queue =
- (wrapped_grpc_completion_queue *)zend_object_store_get_object(
- queue_obj TSRMLS_CC);
- error_code = grpc_call_invoke_old(call->wrapped, queue->wrapped, (void *)tag1,
- (void *)tag2, (gpr_uint32)flags);
- MAYBE_THROW_CALL_ERROR(invoke, error_code);
-}
-
-/**
- * Accept an incoming RPC, binding a completion queue to it. To be called after
- * adding metadata to the call, but before sending messages. Can only be called
- * on the server
- * @param CompletionQueue $queue The completion queue to use with this call
- * @param long $finished_tag The tag to associate with the finished event
- * @param long $flags A bitwise combination of the Grpc\WRITE_* constants
- * (optional)
- * @return Void
- */
-PHP_METHOD(Call, server_accept) {
- long tag;
- zval *queue_obj;
- grpc_call_error error_code;
- /* "Ol|l" == 1 Object, 1 long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol", &queue_obj,
- grpc_ce_completion_queue, &tag) == FAILURE) {
- zend_throw_exception(
- spl_ce_InvalidArgumentException,
- "server_accept expects a CompletionQueue, a long, and an optional long",
- 1 TSRMLS_CC);
- return;
- }
- add_property_zval(getThis(), "completion_queue", queue_obj);
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- wrapped_grpc_completion_queue *queue =
- (wrapped_grpc_completion_queue *)zend_object_store_get_object(
- queue_obj TSRMLS_CC);
- error_code =
- grpc_call_server_accept_old(call->wrapped, queue->wrapped, (void *)tag);
- MAYBE_THROW_CALL_ERROR(server_accept, error_code);
-}
-
-PHP_METHOD(Call, server_end_initial_metadata) {
- grpc_call_error error_code;
- long flags = 0;
- /* "|l" == 1 optional long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags) ==
- FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "server_end_initial_metadata expects an optional long",
- 1 TSRMLS_CC);
- }
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- error_code = grpc_call_server_end_initial_metadata_old(call->wrapped, flags);
- MAYBE_THROW_CALL_ERROR(server_end_initial_metadata, error_code);
-}
-
-/**
- * Called by clients to cancel an RPC on the server.
- * @return Void
- */
-PHP_METHOD(Call, cancel) {
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- grpc_call_error error_code = grpc_call_cancel(call->wrapped);
- MAYBE_THROW_CALL_ERROR(cancel, error_code);
-}
-
-/**
- * Queue a byte buffer for writing
- * @param string $buffer The buffer to queue for writing
- * @param long $tag The tag to associate with this write
- * @param long $flags A bitwise combination of the Grpc\WRITE_* constants
- * (optional)
- * @return Void
- */
-PHP_METHOD(Call, start_write) {
- grpc_call_error error_code;
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- char *buffer;
- int buffer_len;
- long tag;
- long flags = 0;
- /* "Ol|l" == 1 Object, 1 mandatory long, 1 optional long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &buffer,
- &buffer_len, &tag, &flags) == FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "start_write expects a string and an optional long",
+ event = grpc_completion_queue_pluck(call->queue, call->wrapped,
+ gpr_inf_future);
+ if (event->data.op_complete != GRPC_OP_OK) {
+ zend_throw_exception(spl_ce_LogicException,
+ "The batch failed for some reason",
1 TSRMLS_CC);
- return;
+ goto cleanup;
}
- error_code = grpc_call_start_write_old(
- call->wrapped, string_to_byte_buffer(buffer, buffer_len), (void *)tag,
- (gpr_uint32)flags);
- MAYBE_THROW_CALL_ERROR(start_write, error_code);
-}
-
-/**
- * Queue a status for writing
- * @param long $status_code The status code to send
- * @param string $status_details The status details to send
- * @param long $tag The tag to associate with this status
- * @return Void
- */
-PHP_METHOD(Call, start_write_status) {
- grpc_call_error error_code;
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- long status_code;
- int status_details_length;
- long tag;
- char *status_details;
- /* "lsl" == 1 long, 1 string, 1 long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsl", &status_code,
- &status_details, &status_details_length,
- &tag) == FAILURE) {
- zend_throw_exception(
- spl_ce_InvalidArgumentException,
- "start_write_status expects a long, a string, and a long", 1 TSRMLS_CC);
- return;
+ for (int i = 0; i < op_num; i++) {
+ switch(ops[i].op) {
+ case GRPC_OP_SEND_INITIAL_METADATA:
+ add_property_bool(result, "send_metadata", true);
+ break;
+ case GRPC_OP_SEND_MESSAGE:
+ add_property_bool(result, "send_message", true);
+ break;
+ case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
+ add_property_bool(result, "send_close", true);
+ break;
+ case GRPC_OP_SEND_STATUS_FROM_SERVER:
+ add_property_bool(result, "send_status", true);
+ break;
+ case GRPC_OP_RECV_INITIAL_METADATA:
+ array = grpc_parse_metadata_array(&recv_metadata);
+ add_property_zval(result, "metadata", array);
+ Z_DELREF_P(array);
+ break;
+ case GRPC_OP_RECV_MESSAGE:
+ byte_buffer_to_string(message, &message_str, &message_len);
+ if (message_str == NULL) {
+ add_property_null(result, "message");
+ } else {
+ add_property_stringl(result, "message", message_str, message_len,
+ false);
+ }
+ break;
+ case GRPC_OP_RECV_STATUS_ON_CLIENT:
+ MAKE_STD_ZVAL(recv_status);
+ object_init(recv_status);
+ array = grpc_parse_metadata_array(&recv_trailing_metadata);
+ add_property_zval(recv_status, "metadata", array);
+ Z_DELREF_P(array);
+ add_property_long(recv_status, "code", status);
+ add_property_string(recv_status, "details", status_details, true);
+ add_property_zval(result, "status", recv_status);
+ Z_DELREF_P(recv_status);
+ break;
+ case GRPC_OP_RECV_CLOSE_ON_SERVER:
+ add_property_bool(result, "cancelled", cancelled);
+ break;
+ default:
+ break;
+ }
}
- error_code = grpc_call_start_write_status_old(call->wrapped,
- (grpc_status_code)status_code,
- status_details, (void *)tag);
- MAYBE_THROW_CALL_ERROR(start_write_status, error_code);
-}
-
-/**
- * Indicate that there are no more messages to send
- * @return Void
- */
-PHP_METHOD(Call, writes_done) {
- grpc_call_error error_code;
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- long tag;
- /* "l" == 1 long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &tag) == FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "writes_done expects a long", 1 TSRMLS_CC);
- return;
+cleanup:
+ grpc_metadata_array_destroy(&metadata);
+ grpc_metadata_array_destroy(&trailing_metadata);
+ grpc_metadata_array_destroy(&recv_metadata);
+ grpc_metadata_array_destroy(&recv_trailing_metadata);
+ if (status_details != NULL) {
+ gpr_free(status_details);
}
- error_code = grpc_call_writes_done_old(call->wrapped, (void *)tag);
- MAYBE_THROW_CALL_ERROR(writes_done, error_code);
+ RETURN_DESTROY_ZVAL(result);
}
/**
- * Initiate a read on a call. Output event contains a byte buffer with the
- * result of the read
- * @param long $tag The tag to associate with this read
- * @return Void
+ * Cancel the call. This will cause the call to end with STATUS_CANCELLED if it
+ * has not already ended with another status.
*/
-PHP_METHOD(Call, start_read) {
- grpc_call_error error_code;
+PHP_METHOD(Call, cancel) {
wrapped_grpc_call *call =
(wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- long tag;
- /* "l" == 1 long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &tag) == FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "start_read expects a long", 1 TSRMLS_CC);
- return;
- }
- error_code = grpc_call_start_read_old(call->wrapped, (void *)tag);
- MAYBE_THROW_CALL_ERROR(start_read, error_code);
+ grpc_call_cancel(call->wrapped);
}
static zend_function_entry call_methods[] = {
PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
- PHP_ME(Call, server_accept, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, server_end_initial_metadata, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, add_metadata, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, invoke, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, start_read, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, start_write, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, start_write_status, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, writes_done, NULL, ZEND_ACC_PUBLIC) PHP_FE_END};
+ PHP_ME(Call, startBatch, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC) PHP_FE_END};
void grpc_init_call(TSRMLS_D) {
zend_class_entry ce;
diff --git a/src/php/ext/grpc/call.h b/src/php/ext/grpc/call.h
index bce5d82974..e7eb9a75e2 100644
--- a/src/php/ext/grpc/call.h
+++ b/src/php/ext/grpc/call.h
@@ -38,23 +38,12 @@
#include "config.h"
#endif
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
#include "php_grpc.h"
-#include "grpc/grpc.h"
-
-// Throw an exception if error_code is not OK
-#define MAYBE_THROW_CALL_ERROR(func_name, error_code) \
- do { \
- if (error_code != GRPC_CALL_OK) { \
- zend_throw_exception(spl_ce_LogicException, \
- #func_name " was called incorrectly", \
- (long)error_code TSRMLS_CC); \
- return; \
- } \
- } while (0)
+#include <grpc/grpc.h>
/* Class entry for the Call PHP class */
extern zend_class_entry *grpc_ce_call;
@@ -65,16 +54,18 @@ typedef struct wrapped_grpc_call {
bool owned;
grpc_call *wrapped;
+ grpc_completion_queue *queue;
} wrapped_grpc_call;
/* Initializes the Call PHP class */
void grpc_init_call(TSRMLS_D);
/* Creates a Call object that wraps the given grpc_call struct */
-zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned);
+zval *grpc_php_wrap_call(grpc_call *wrapped, grpc_completion_queue *queue,
+ bool owned);
/* Creates and returns a PHP associative array of metadata from a C array of
* call metadata */
-zval *grpc_call_create_metadata_array(int count, grpc_metadata *elements);
+zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array);
#endif /* NET_GRPC_PHP_GRPC_CHANNEL_H_ */
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index 5e99332fab..b8262db162 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -37,21 +37,20 @@
#include "config.h"
#endif
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "ext/spl/spl_exceptions.h"
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
+#include <ext/spl/spl_exceptions.h>
#include "php_grpc.h"
-#include "zend_exceptions.h"
+#include <zend_exceptions.h>
#include <stdbool.h>
-#include "grpc/grpc.h"
-#include "grpc/support/log.h"
-#include "grpc/grpc_security.h"
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpc/grpc_security.h>
-#include "completion_queue.h"
#include "server.h"
#include "credentials.h"
@@ -63,6 +62,7 @@ void free_wrapped_grpc_channel(void *object TSRMLS_DC) {
if (channel->wrapped != NULL) {
grpc_channel_destroy(channel->wrapped);
}
+ efree(channel->target);
efree(channel);
}
@@ -139,6 +139,9 @@ PHP_METHOD(Channel, __construct) {
HashTable *array_hash;
zval **creds_obj = NULL;
wrapped_grpc_credentials *creds = NULL;
+ zval **override_obj;
+ char *override;
+ int override_len;
/* "s|a" == 1 string, 1 optional array */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a", &target,
&target_length, &args_array) == FAILURE) {
@@ -146,6 +149,8 @@ PHP_METHOD(Channel, __construct) {
"Channel expects a string and an array", 1 TSRMLS_CC);
return;
}
+ override = target;
+ override_len = target_length;
if (args_array == NULL) {
channel->wrapped = grpc_channel_create(target, NULL);
} else {
@@ -162,6 +167,19 @@ PHP_METHOD(Channel, __construct) {
*creds_obj TSRMLS_CC);
zend_hash_del(array_hash, "credentials", 12);
}
+ if (zend_hash_find(array_hash, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
+ sizeof(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG),
+ (void **)&override_obj) == SUCCESS) {
+ if (Z_TYPE_PP(override_obj) != IS_STRING) {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ GRPC_SSL_TARGET_NAME_OVERRIDE_ARG
+ " must be a string",
+ 1 TSRMLS_CC);
+ return;
+ }
+ override = Z_STRVAL_PP(override_obj);
+ override_len = Z_STRLEN_PP(override_obj);
+ }
php_grpc_read_args_array(args_array, &args);
if (creds == NULL) {
channel->wrapped = grpc_channel_create(target, &args);
@@ -172,8 +190,8 @@ PHP_METHOD(Channel, __construct) {
}
efree(args.args);
}
- channel->target = ecalloc(target_length + 1, sizeof(char));
- memcpy(channel->target, target, target_length);
+ channel->target = ecalloc(override_len + 1, sizeof(char));
+ memcpy(channel->target, override, override_len);
}
/**
diff --git a/src/php/ext/grpc/channel.h b/src/php/ext/grpc/channel.h
index 2c79668a4d..c13fa4c6d7 100755
--- a/src/php/ext/grpc/channel.h
+++ b/src/php/ext/grpc/channel.h
@@ -38,12 +38,12 @@
#include "config.h"
#endif
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
#include "php_grpc.h"
-#include "grpc/grpc.h"
+#include <grpc/grpc.h>
/* Class entry for the PHP Channel class */
extern zend_class_entry *grpc_ce_channel;
diff --git a/src/php/ext/grpc/completion_queue.c b/src/php/ext/grpc/completion_queue.c
deleted file mode 100644
index 93abf5df36..0000000000
--- a/src/php/ext/grpc/completion_queue.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "completion_queue.h"
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "ext/spl/spl_exceptions.h"
-#include "php_grpc.h"
-
-#include "zend_exceptions.h"
-
-#include <stdbool.h>
-
-#include "grpc/grpc.h"
-
-#include "event.h"
-#include "timeval.h"
-
-zend_class_entry *grpc_ce_completion_queue;
-
-/* Frees and destroys a wrapped instance of grpc_completion_queue */
-void free_wrapped_grpc_completion_queue(void *object TSRMLS_DC) {
- wrapped_grpc_completion_queue *queue = NULL;
- grpc_event *event;
- queue = (wrapped_grpc_completion_queue *)object;
- if (queue->wrapped != NULL) {
- grpc_completion_queue_shutdown(queue->wrapped);
- event = grpc_completion_queue_next(queue->wrapped, gpr_inf_future);
- while (event != NULL) {
- if (event->type == GRPC_QUEUE_SHUTDOWN) {
- break;
- }
- event = grpc_completion_queue_next(queue->wrapped, gpr_inf_future);
- }
- grpc_completion_queue_destroy(queue->wrapped);
- }
- efree(queue);
-}
-
-/* Initializes an instance of wrapped_grpc_channel to be associated with an
- * object of a class specified by class_type */
-zend_object_value create_wrapped_grpc_completion_queue(
- zend_class_entry *class_type TSRMLS_DC) {
- zend_object_value retval;
- wrapped_grpc_completion_queue *intern;
-
- intern = (wrapped_grpc_completion_queue *)emalloc(
- sizeof(wrapped_grpc_completion_queue));
- memset(intern, 0, sizeof(wrapped_grpc_completion_queue));
-
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
- object_properties_init(&intern->std, class_type);
- retval.handle = zend_objects_store_put(
- intern, (zend_objects_store_dtor_t)zend_objects_destroy_object,
- free_wrapped_grpc_completion_queue, NULL TSRMLS_CC);
- retval.handlers = zend_get_std_object_handlers();
- return retval;
-}
-
-/**
- * Construct an instance of CompletionQueue
- */
-PHP_METHOD(CompletionQueue, __construct) {
- wrapped_grpc_completion_queue *queue =
- (wrapped_grpc_completion_queue *)zend_object_store_get_object(getThis()
- TSRMLS_CC);
- queue->wrapped = grpc_completion_queue_create();
-}
-
-/**
- * Blocks until an event is available, the completion queue is being shutdown,
- * or timeout is reached. Returns NULL on timeout, otherwise the event that
- * occurred. Callers should call event.finish once they have processed the
- * event.
- * @param Timeval $timeout The timeout for the event
- * @return Event The event that occurred
- */
-PHP_METHOD(CompletionQueue, next) {
- zval *timeout;
- /* "O" == 1 Object */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &timeout,
- grpc_ce_timeval) == FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "next needs a Timeval", 1 TSRMLS_CC);
- return;
- }
- wrapped_grpc_completion_queue *completion_queue =
- (wrapped_grpc_completion_queue *)zend_object_store_get_object(getThis()
- TSRMLS_CC);
- wrapped_grpc_timeval *wrapped_timeout =
- (wrapped_grpc_timeval *)zend_object_store_get_object(timeout TSRMLS_CC);
- grpc_event *event = grpc_completion_queue_next(completion_queue->wrapped,
- wrapped_timeout->wrapped);
- if (event == NULL) {
- RETURN_NULL();
- }
- zval *wrapped_event = grpc_php_convert_event(event);
- RETURN_DESTROY_ZVAL(wrapped_event);
-}
-
-PHP_METHOD(CompletionQueue, pluck) {
- long tag;
- zval *timeout;
- /* "lO" == 1 long, 1 Object */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lO", &tag, &timeout,
- grpc_ce_timeval) == FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "pluck needs a long and a Timeval", 1 TSRMLS_CC);
- }
- wrapped_grpc_completion_queue *completion_queue =
- (wrapped_grpc_completion_queue *)zend_object_store_get_object(getThis()
- TSRMLS_CC);
- wrapped_grpc_timeval *wrapped_timeout =
- (wrapped_grpc_timeval *)zend_object_store_get_object(timeout TSRMLS_CC);
- grpc_event *event = grpc_completion_queue_pluck(
- completion_queue->wrapped, (void *)tag, wrapped_timeout->wrapped);
- if (event == NULL) {
- RETURN_NULL();
- }
- zval *wrapped_event = grpc_php_convert_event(event);
- RETURN_DESTROY_ZVAL(wrapped_event);
-}
-
-static zend_function_entry completion_queue_methods[] = {
- PHP_ME(CompletionQueue, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
- PHP_ME(CompletionQueue, next, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(CompletionQueue, pluck, NULL, ZEND_ACC_PUBLIC) PHP_FE_END};
-
-void grpc_init_completion_queue(TSRMLS_D) {
- zend_class_entry ce;
- INIT_CLASS_ENTRY(ce, "Grpc\\CompletionQueue", completion_queue_methods);
- ce.create_object = create_wrapped_grpc_completion_queue;
- grpc_ce_completion_queue = zend_register_internal_class(&ce TSRMLS_CC);
-}
diff --git a/src/php/ext/grpc/config.m4 b/src/php/ext/grpc/config.m4
index 27c67781e7..11778e3bb6 100755
--- a/src/php/ext/grpc/config.m4
+++ b/src/php/ext/grpc/config.m4
@@ -66,5 +66,5 @@ if test "$PHP_GRPC" != "no"; then
PHP_SUBST(GRPC_SHARED_LIBADD)
- PHP_NEW_EXTENSION(grpc, byte_buffer.c call.c channel.c completion_queue.c credentials.c event.c timeval.c server.c server_credentials.c php_grpc.c, $ext_shared, , -Wall -Werror -pedantic -std=c99)
+ PHP_NEW_EXTENSION(grpc, byte_buffer.c call.c channel.c credentials.c timeval.c server.c server_credentials.c php_grpc.c, $ext_shared, , -Wall -Werror -std=c11)
fi
diff --git a/src/php/ext/grpc/credentials.c b/src/php/ext/grpc/credentials.c
index a94b0eac2d..a262b9981f 100644
--- a/src/php/ext/grpc/credentials.c
+++ b/src/php/ext/grpc/credentials.c
@@ -37,17 +37,17 @@
#include "config.h"
#endif
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "ext/spl/spl_exceptions.h"
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
+#include <ext/spl/spl_exceptions.h>
#include "php_grpc.h"
-#include "zend_exceptions.h"
-#include "zend_hash.h"
+#include <zend_exceptions.h>
+#include <zend_hash.h>
-#include "grpc/grpc.h"
-#include "grpc/grpc_security.h"
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
zend_class_entry *grpc_ce_credentials;
diff --git a/src/php/ext/grpc/event.c b/src/php/ext/grpc/event.c
deleted file mode 100644
index 452c4b8bcb..0000000000
--- a/src/php/ext/grpc/event.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "event.h"
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "php_grpc.h"
-
-#include <stdbool.h>
-
-#include "grpc/grpc.h"
-
-#include "byte_buffer.h"
-#include "call.h"
-#include "timeval.h"
-
-/* Create a new PHP object containing the event data in the event struct.
- event must not be used after this function is called */
-zval *grpc_php_convert_event(grpc_event *event) {
- zval *data_object;
- char *detail_string;
- size_t detail_len;
- char *method_string;
- size_t method_len;
- char *host_string;
- size_t host_len;
- char *read_string;
- size_t read_len;
-
- zval *event_object;
-
- if (event == NULL) {
- return NULL;
- }
-
- MAKE_STD_ZVAL(event_object);
- object_init(event_object);
-
- add_property_zval(
- event_object, "call",
- grpc_php_wrap_call(event->call, event->type == GRPC_SERVER_RPC_NEW));
- add_property_long(event_object, "type", event->type);
- add_property_long(event_object, "tag", (long)event->tag);
-
- switch (event->type) {
- case GRPC_QUEUE_SHUTDOWN:
- add_property_null(event_object, "data");
- break;
- case GRPC_READ:
- if (event->data.read == NULL) {
- add_property_null(event_object, "data");
- } else {
- byte_buffer_to_string(event->data.read, &read_string, &read_len);
- add_property_stringl(event_object, "data", read_string, read_len, true);
- }
- break;
- case GRPC_WRITE_ACCEPTED:
- add_property_long(event_object, "data", (long)event->data.write_accepted);
- break;
- case GRPC_FINISH_ACCEPTED:
- add_property_long(event_object, "data",
- (long)event->data.finish_accepted);
- break;
- case GRPC_CLIENT_METADATA_READ:
- data_object = grpc_call_create_metadata_array(
- event->data.client_metadata_read.count,
- event->data.client_metadata_read.elements);
- add_property_zval(event_object, "data", data_object);
- break;
- case GRPC_FINISHED:
- MAKE_STD_ZVAL(data_object);
- object_init(data_object);
- add_property_long(data_object, "code", event->data.finished.status);
- if (event->data.finished.details == NULL) {
- add_property_null(data_object, "details");
- } else {
- detail_len = strlen(event->data.finished.details);
- detail_string = ecalloc(detail_len + 1, sizeof(char));
- memcpy(detail_string, event->data.finished.details, detail_len);
- add_property_string(data_object, "details", detail_string, true);
- }
- add_property_zval(data_object, "metadata",
- grpc_call_create_metadata_array(
- event->data.finished.metadata_count,
- event->data.finished.metadata_elements));
- add_property_zval(event_object, "data", data_object);
- break;
- case GRPC_SERVER_RPC_NEW:
- MAKE_STD_ZVAL(data_object);
- object_init(data_object);
- method_len = strlen(event->data.server_rpc_new.method);
- method_string = ecalloc(method_len + 1, sizeof(char));
- memcpy(method_string, event->data.server_rpc_new.method, method_len);
- add_property_string(data_object, "method", method_string, false);
- host_len = strlen(event->data.server_rpc_new.host);
- host_string = ecalloc(host_len + 1, sizeof(char));
- memcpy(host_string, event->data.server_rpc_new.host, host_len);
- add_property_string(data_object, "host", host_string, false);
- add_property_zval(
- data_object, "absolute_timeout",
- grpc_php_wrap_timeval(event->data.server_rpc_new.deadline));
- add_property_zval(data_object, "metadata",
- grpc_call_create_metadata_array(
- event->data.server_rpc_new.metadata_count,
- event->data.server_rpc_new.metadata_elements));
- add_property_zval(event_object, "data", data_object);
- break;
- default:
- add_property_null(event_object, "data");
- break;
- }
- grpc_event_finish(event);
- return event_object;
-}
diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c
index 67e366c385..3e669ecd17 100644
--- a/src/php/ext/grpc/php_grpc.c
+++ b/src/php/ext/grpc/php_grpc.c
@@ -34,8 +34,6 @@
#include "call.h"
#include "channel.h"
#include "server.h"
-#include "completion_queue.h"
-#include "event.h"
#include "timeval.h"
#include "credentials.h"
#include "server_credentials.h"
@@ -44,9 +42,9 @@
#include "config.h"
#endif
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
#include "php_grpc.h"
// ZEND_DECLARE_MODULE_GLOBALS(grpc)
@@ -127,27 +125,12 @@ PHP_MINIT_FUNCTION(grpc) {
REGISTER_LONG_CONSTANT("Grpc\\CALL_ERROR_INVALID_FLAGS",
GRPC_CALL_ERROR_INVALID_FLAGS, CONST_CS);
- /* Register op error constants */
- REGISTER_LONG_CONSTANT("Grpc\\OP_OK", GRPC_OP_OK, CONST_CS);
- REGISTER_LONG_CONSTANT("Grpc\\OP_ERROR", GRPC_OP_ERROR, CONST_CS);
-
/* Register flag constants */
REGISTER_LONG_CONSTANT("Grpc\\WRITE_BUFFER_HINT", GRPC_WRITE_BUFFER_HINT,
CONST_CS);
REGISTER_LONG_CONSTANT("Grpc\\WRITE_NO_COMPRESS", GRPC_WRITE_NO_COMPRESS,
CONST_CS);
- /* Register completion type constants */
- REGISTER_LONG_CONSTANT("Grpc\\QUEUE_SHUTDOWN", GRPC_QUEUE_SHUTDOWN, CONST_CS);
- REGISTER_LONG_CONSTANT("Grpc\\READ", GRPC_READ, CONST_CS);
- REGISTER_LONG_CONSTANT("Grpc\\FINISH_ACCEPTED", GRPC_FINISH_ACCEPTED,
- CONST_CS);
- REGISTER_LONG_CONSTANT("Grpc\\WRITE_ACCEPTED", GRPC_WRITE_ACCEPTED, CONST_CS);
- REGISTER_LONG_CONSTANT("Grpc\\CLIENT_METADATA_READ",
- GRPC_CLIENT_METADATA_READ, CONST_CS);
- REGISTER_LONG_CONSTANT("Grpc\\FINISHED", GRPC_FINISHED, CONST_CS);
- REGISTER_LONG_CONSTANT("Grpc\\SERVER_RPC_NEW", GRPC_SERVER_RPC_NEW, CONST_CS);
-
/* Register status constants */
REGISTER_LONG_CONSTANT("Grpc\\STATUS_OK", GRPC_STATUS_OK, CONST_CS);
REGISTER_LONG_CONSTANT("Grpc\\STATUS_CANCELLED", GRPC_STATUS_CANCELLED,
@@ -181,10 +164,27 @@ PHP_MINIT_FUNCTION(grpc) {
REGISTER_LONG_CONSTANT("Grpc\\STATUS_DATA_LOSS", GRPC_STATUS_DATA_LOSS,
CONST_CS);
+ /* Register op type constants */
+ REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_INITIAL_METADATA",
+ GRPC_OP_SEND_INITIAL_METADATA, CONST_CS);
+ REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_MESSAGE",
+ GRPC_OP_SEND_MESSAGE, CONST_CS);
+ REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_CLOSE_FROM_CLIENT",
+ GRPC_OP_SEND_CLOSE_FROM_CLIENT, CONST_CS);
+ REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_STATUS_FROM_SERVER",
+ GRPC_OP_SEND_STATUS_FROM_SERVER, CONST_CS);
+ REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_INITIAL_METADATA",
+ GRPC_OP_RECV_INITIAL_METADATA, CONST_CS);
+ REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_MESSAGE",
+ GRPC_OP_RECV_MESSAGE, CONST_CS);
+ REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_STATUS_ON_CLIENT",
+ GRPC_OP_RECV_STATUS_ON_CLIENT, CONST_CS);
+ REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_CLOSE_ON_SERVER",
+ GRPC_OP_RECV_CLOSE_ON_SERVER, CONST_CS);
+
grpc_init_call(TSRMLS_C);
grpc_init_channel(TSRMLS_C);
grpc_init_server(TSRMLS_C);
- grpc_init_completion_queue(TSRMLS_C);
grpc_init_timeval(TSRMLS_C);
grpc_init_credentials(TSRMLS_C);
grpc_init_server_credentials(TSRMLS_C);
diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c
index a5cfd95287..dbb9425619 100644
--- a/src/php/ext/grpc/server.c
+++ b/src/php/ext/grpc/server.c
@@ -37,30 +37,42 @@
#include "config.h"
#endif
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "ext/spl/spl_exceptions.h"
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
+#include <ext/spl/spl_exceptions.h>
#include "php_grpc.h"
-#include "zend_exceptions.h"
+#include <zend_exceptions.h>
#include <stdbool.h>
-#include "grpc/grpc.h"
-#include "grpc/support/log.h"
-#include "grpc/grpc_security.h"
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpc/grpc_security.h>
#include "server.h"
-#include "completion_queue.h"
#include "channel.h"
#include "server_credentials.h"
+#include "timeval.h"
zend_class_entry *grpc_ce_server;
/* Frees and destroys an instance of wrapped_grpc_server */
void free_wrapped_grpc_server(void *object TSRMLS_DC) {
wrapped_grpc_server *server = (wrapped_grpc_server *)object;
+ grpc_event *event;
+ if (server->queue != NULL) {
+ grpc_completion_queue_shutdown(server->queue);
+ event = grpc_completion_queue_next(server->queue, gpr_inf_future);
+ while (event != NULL) {
+ if (event->type == GRPC_QUEUE_SHUTDOWN) {
+ break;
+ }
+ event = grpc_completion_queue_next(server->queue, gpr_inf_future);
+ }
+ grpc_completion_queue_destroy(server->queue);
+ }
if (server->wrapped != NULL) {
grpc_server_shutdown(server->wrapped);
grpc_server_destroy(server->wrapped);
@@ -95,26 +107,22 @@ zend_object_value create_wrapped_grpc_server(zend_class_entry *class_type
PHP_METHOD(Server, __construct) {
wrapped_grpc_server *server =
(wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC);
- zval *queue_obj;
zval *args_array = NULL;
grpc_channel_args args;
- /* "O|a" == 1 Object, 1 optional array */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|a", &queue_obj,
- grpc_ce_completion_queue, &args_array) == FAILURE) {
+ /* "|a" == 1 optional array */
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &args_array) ==
+ FAILURE) {
zend_throw_exception(spl_ce_InvalidArgumentException,
- "Server expects a CompletionQueue and an array",
+ "Server expects an array",
1 TSRMLS_CC);
return;
}
- add_property_zval(getThis(), "completion_queue", queue_obj);
- wrapped_grpc_completion_queue *queue =
- (wrapped_grpc_completion_queue *)zend_object_store_get_object(
- queue_obj TSRMLS_CC);
+ server->queue = grpc_completion_queue_create();
if (args_array == NULL) {
- server->wrapped = grpc_server_create(queue->wrapped, NULL);
+ server->wrapped = grpc_server_create(server->queue, NULL);
} else {
php_grpc_read_args_array(args_array, &args);
- server->wrapped = grpc_server_create(queue->wrapped, &args);
+ server->wrapped = grpc_server_create(server->queue, &args);
efree(args.args);
}
}
@@ -125,20 +133,44 @@ PHP_METHOD(Server, __construct) {
* @param long $tag_cancel The tag to use if the call is cancelled
* @return Void
*/
-PHP_METHOD(Server, request_call) {
+PHP_METHOD(Server, requestCall) {
grpc_call_error error_code;
wrapped_grpc_server *server =
(wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC);
- long tag_new;
- /* "l" == 1 long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &tag_new) ==
- FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "request_call expects a long", 1 TSRMLS_CC);
- return;
+ grpc_call *call;
+ grpc_call_details details;
+ grpc_metadata_array metadata;
+ zval *result;
+ grpc_event *event;
+ MAKE_STD_ZVAL(result);
+ object_init(result);
+ grpc_call_details_init(&details);
+ grpc_metadata_array_init(&metadata);
+ error_code = grpc_server_request_call(server->wrapped, &call, &details,
+ &metadata, server->queue, NULL);
+ if (error_code != GRPC_CALL_OK) {
+ zend_throw_exception(spl_ce_LogicException, "request_call failed",
+ (long)error_code TSRMLS_CC);
+ goto cleanup;
+ }
+ event = grpc_completion_queue_pluck(server->queue, NULL, gpr_inf_future);
+ if (event->data.op_complete != GRPC_OP_OK) {
+ zend_throw_exception(spl_ce_LogicException,
+ "Failed to request a call for some reason",
+ 1 TSRMLS_CC);
+ goto cleanup;
}
- error_code = grpc_server_request_call_old(server->wrapped, (void *)tag_new);
- MAYBE_THROW_CALL_ERROR(request_call, error_code);
+ add_property_zval(result, "call", grpc_php_wrap_call(call, server->queue,
+ true));
+ add_property_string(result, "method", details.method, true);
+ add_property_string(result, "host", details.host, true);
+ add_property_zval(result, "absolute_deadline",
+ grpc_php_wrap_timeval(details.deadline));
+ add_property_zval(result, "metadata", grpc_parse_metadata_array(&metadata));
+cleanup:
+ grpc_call_details_destroy(&details);
+ grpc_metadata_array_destroy(&metadata);
+ RETURN_DESTROY_ZVAL(result);
}
/**
@@ -146,7 +178,7 @@ PHP_METHOD(Server, request_call) {
* @param string $addr The address to add
* @return true on success, false on failure
*/
-PHP_METHOD(Server, add_http2_port) {
+PHP_METHOD(Server, addHttp2Port) {
wrapped_grpc_server *server =
(wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC);
const char *addr;
@@ -161,14 +193,14 @@ PHP_METHOD(Server, add_http2_port) {
RETURN_LONG(grpc_server_add_http2_port(server->wrapped, addr));
}
-PHP_METHOD(Server, add_secure_http2_port) {
+PHP_METHOD(Server, addSecureHttp2Port) {
wrapped_grpc_server *server =
(wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC);
const char *addr;
int addr_len;
zval *creds_obj;
/* "sO" == 1 string, 1 object */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len,
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO", &addr, &addr_len,
&creds_obj, grpc_ce_server_credentials) ==
FAILURE) {
zend_throw_exception(
@@ -195,9 +227,9 @@ PHP_METHOD(Server, start) {
static zend_function_entry server_methods[] = {
PHP_ME(Server, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
- PHP_ME(Server, request_call, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Server, add_http2_port, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Server, add_secure_http2_port, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Server, requestCall, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Server, addHttp2Port, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Server, addSecureHttp2Port, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Server, start, NULL, ZEND_ACC_PUBLIC) PHP_FE_END};
void grpc_init_server(TSRMLS_D) {
diff --git a/src/php/ext/grpc/server.h b/src/php/ext/grpc/server.h
index b55689c581..a2ee2ff5a9 100755
--- a/src/php/ext/grpc/server.h
+++ b/src/php/ext/grpc/server.h
@@ -38,12 +38,12 @@
#include "config.h"
#endif
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
#include "php_grpc.h"
-#include "grpc/grpc.h"
+#include <grpc/grpc.h>
/* Class entry for the Server PHP class */
extern zend_class_entry *grpc_ce_server;
@@ -53,6 +53,7 @@ typedef struct wrapped_grpc_server {
zend_object std;
grpc_server *wrapped;
+ grpc_completion_queue *queue;
} wrapped_grpc_server;
/* Initializes the Server class */
diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c
index df64e65986..c4c1fabb1a 100644
--- a/src/php/ext/grpc/server_credentials.c
+++ b/src/php/ext/grpc/server_credentials.c
@@ -37,17 +37,17 @@
#include "config.h"
#endif
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "ext/spl/spl_exceptions.h"
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
+#include <ext/spl/spl_exceptions.h>
#include "php_grpc.h"
-#include "zend_exceptions.h"
-#include "zend_hash.h"
+#include <zend_exceptions.h>
+#include <zend_hash.h>
-#include "grpc/grpc.h"
-#include "grpc/grpc_security.h"
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
zend_class_entry *grpc_ce_server_credentials;
diff --git a/src/php/ext/grpc/server_credentials.h b/src/php/ext/grpc/server_credentials.h
index 8ed3697150..7101d65000 100755
--- a/src/php/ext/grpc/server_credentials.h
+++ b/src/php/ext/grpc/server_credentials.h
@@ -38,13 +38,13 @@
#include "config.h"
#endif
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
#include "php_grpc.h"
-#include "grpc/grpc.h"
-#include "grpc/grpc_security.h"
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
/* Class entry for the Server_Credentials PHP class */
extern zend_class_entry *grpc_ce_server_credentials;
diff --git a/src/php/ext/grpc/timeval.c b/src/php/ext/grpc/timeval.c
index f90f0062ba..8a278d6760 100644
--- a/src/php/ext/grpc/timeval.c
+++ b/src/php/ext/grpc/timeval.c
@@ -37,18 +37,18 @@
#include "config.h"
#endif
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "ext/spl/spl_exceptions.h"
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
+#include <ext/spl/spl_exceptions.h>
#include "php_grpc.h"
-#include "zend_exceptions.h"
+#include <zend_exceptions.h>
#include <stdbool.h>
-#include "grpc/grpc.h"
-#include "grpc/support/time.h"
+#include <grpc/grpc.h>
+#include <grpc/support/time.h>
zend_class_entry *grpc_ce_timeval;
@@ -227,7 +227,7 @@ PHP_METHOD(Timeval, zero) {
* Returns the infinite future time value as a timeval object
* @return Timeval Infinite future time value
*/
-PHP_METHOD(Timeval, inf_future) {
+PHP_METHOD(Timeval, infFuture) {
zval *grpc_php_timeval_inf_future = grpc_php_wrap_timeval(gpr_inf_future);
RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_future);
}
@@ -236,7 +236,7 @@ PHP_METHOD(Timeval, inf_future) {
* Returns the infinite past time value as a timeval object
* @return Timeval Infinite past time value
*/
-PHP_METHOD(Timeval, inf_past) {
+PHP_METHOD(Timeval, infPast) {
zval *grpc_php_timeval_inf_past = grpc_php_wrap_timeval(gpr_inf_past);
RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_past);
}
@@ -245,7 +245,7 @@ PHP_METHOD(Timeval, inf_past) {
* Sleep until this time, interpreted as an absolute timeout
* @return void
*/
-PHP_METHOD(Timeval, sleep_until) {
+PHP_METHOD(Timeval, sleepUntil) {
wrapped_grpc_timeval *this =
(wrapped_grpc_timeval *)zend_object_store_get_object(getThis() TSRMLS_CC);
gpr_sleep_until(this->wrapped);
@@ -255,11 +255,11 @@ static zend_function_entry timeval_methods[] = {
PHP_ME(Timeval, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(Timeval, add, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Timeval, compare, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
- PHP_ME(Timeval, inf_future, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
- PHP_ME(Timeval, inf_past, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+ PHP_ME(Timeval, infFuture, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+ PHP_ME(Timeval, infPast, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Timeval, now, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Timeval, similar, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
- PHP_ME(Timeval, sleep_until, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Timeval, sleepUntil, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Timeval, subtract, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Timeval, zero, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END};
diff --git a/src/php/ext/grpc/timeval.h b/src/php/ext/grpc/timeval.h
index e3183f691d..07cef037cb 100755
--- a/src/php/ext/grpc/timeval.h
+++ b/src/php/ext/grpc/timeval.h
@@ -38,13 +38,13 @@
#include "config.h"
#endif
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
#include "php_grpc.h"
-#include "grpc/grpc.h"
-#include "grpc/support/time.h"
+#include <grpc/grpc.h>
+#include <grpc/support/time.h>
/* Class entry for the Timeval PHP Class */
extern zend_class_entry *grpc_ce_timeval;
diff --git a/src/php/lib/Grpc/BidiStreamingSurfaceActiveCall.php b/src/php/lib/Grpc/AbstractCall.php
index 0459f21e27..1add972589 100755..100644
--- a/src/php/lib/Grpc/BidiStreamingSurfaceActiveCall.php
+++ b/src/php/lib/Grpc/AbstractCall.php
@@ -32,44 +32,47 @@
*
*/
namespace Grpc;
-require_once realpath(dirname(__FILE__) . '/../autoload.php');
-/**
- * Represents an active call that allows for sending and recieving messages in
- * streams in any order.
- */
-class BidiStreamingSurfaceActiveCall extends AbstractSurfaceActiveCall {
+abstract class AbstractCall {
+
+ protected $call;
+ protected $deserialize;
+ protected $metadata;
/**
- * Reads the next value from the server.
- * @return The next value from the server, or null if there is none
+ * Create a new Call wrapper object.
+ * @param Channel $channel The channel to communicate on
+ * @param string $method The method to call on the remote server
*/
- public function read() {
- return $this->_read();
+ public function __construct(Channel $channel, $method, $deserialize) {
+ $this->call = new Call($channel, $method, Timeval::infFuture());
+ $this->deserialize = $deserialize;
+ $this->metadata = null;
}
/**
- * Writes a single message to the server. This cannot be called after
- * writesDone is called.
- * @param $value The message to send
+ * @return The metadata sent by the server.
*/
- public function write($value) {
- $this->_write($value);
+ public function getMetadata() {
+ return $this->metadata;
}
/**
- * Indicate that no more writes will be sent
+ * Cancels the call
*/
- public function writesDone() {
- $this->_writesDone();
+ public function cancel() {
+ $this->call->cancel();
}
/**
- * Wait for the server to send the status, and return it.
- * @return object The status object, with integer $code and string $details
- * members
+ * Deserialize a response value to an object.
+ * @param string $value The binary value to deserialize
+ * @return The deserialized value
*/
- public function getStatus() {
- return $this->_getStatus();
+ protected function deserializeResponse($value) {
+ if ($value === null) {
+ return null;
+ }
+ return call_user_func($this->deserialize, $value);
}
-}
+} \ No newline at end of file
diff --git a/src/php/lib/Grpc/ActiveCall.php b/src/php/lib/Grpc/ActiveCall.php
deleted file mode 100755
index f0d0d55582..0000000000
--- a/src/php/lib/Grpc/ActiveCall.php
+++ /dev/null
@@ -1,123 +0,0 @@
-<?php
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-namespace Grpc;
-require_once realpath(dirname(__FILE__) . '/../autoload.php');
-
-/**
- * Represents an active call that allows sending and recieving binary data
- */
-class ActiveCall {
- private $completion_queue;
- private $call;
- private $flags;
- private $metadata;
-
- /**
- * Create a new active call.
- * @param Channel $channel The channel to communicate on
- * @param string $method The method to call on the remote server
- * @param array $metadata Metadata to send with the call, if applicable
- * @param long $flags Write flags to use with this call
- */
- public function __construct(Channel $channel,
- $method,
- $metadata = array(),
- $flags = 0) {
- $this->completion_queue = new CompletionQueue();
- $this->call = new Call($channel, $method, Timeval::inf_future());
- $this->call->add_metadata($metadata, 0);
- $this->flags = $flags;
-
- // Invoke the call.
- $this->call->invoke($this->completion_queue,
- CLIENT_METADATA_READ,
- FINISHED, 0);
- $metadata_event = $this->completion_queue->pluck(CLIENT_METADATA_READ,
- Timeval::inf_future());
- $this->metadata = $metadata_event->data;
- }
-
- /**
- * @return The metadata sent by the server.
- */
- public function getMetadata() {
- return $this->metadata;
- }
-
- /**
- * Cancels the call
- */
- public function cancel() {
- $this->call->cancel();
- }
-
- /**
- * Read a single message from the server.
- * @return The next message from the server, or null if there is none.
- */
- public function read() {
- $this->call->start_read(READ);
- $read_event = $this->completion_queue->pluck(READ, Timeval::inf_future());
- return $read_event->data;
- }
-
- /**
- * Write a single message to the server. This cannot be called after
- * writesDone is called.
- * @param ByteBuffer $data The data to write
- */
- public function write($data) {
- $this->call->start_write($data, WRITE_ACCEPTED, $this->flags);
- $this->completion_queue->pluck(WRITE_ACCEPTED, Timeval::inf_future());
- }
-
- /**
- * Indicate that no more writes will be sent.
- */
- public function writesDone() {
- $this->call->writes_done(FINISH_ACCEPTED);
- $this->completion_queue->pluck(FINISH_ACCEPTED, Timeval::inf_future());
- }
-
- /**
- * Wait for the server to send the status, and return it.
- * @return object The status object, with integer $code, string $details,
- * and array $metadata members
- */
- public function getStatus() {
- $status_event = $this->completion_queue->pluck(FINISHED,
- Timeval::inf_future());
- return $status_event->data;
- }
-}
diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php
index fde055a3b3..fc83dace20 100755
--- a/src/php/lib/Grpc/BaseStub.php
+++ b/src/php/lib/Grpc/BaseStub.php
@@ -32,7 +32,6 @@
*
*/
namespace Grpc;
-require_once realpath(dirname(__FILE__) . '/../autoload.php');
/**
* Base class for generated client stubs. Stub methods are expected to call
@@ -69,11 +68,9 @@ class BaseStub {
$argument,
callable $deserialize,
$metadata = array()) {
- return new SimpleSurfaceActiveCall($this->channel,
- $method,
- $deserialize,
- $argument,
- $metadata);
+ $call = new UnaryCall($this->channel, $method, $deserialize);
+ $call->start($argument, $metadata);
+ return $call;
}
/**
@@ -91,11 +88,9 @@ class BaseStub {
$arguments,
callable $deserialize,
$metadata = array()) {
- return new ClientStreamingSurfaceActiveCall($this->channel,
- $method,
- $deserialize,
- $arguments,
- $metadata);
+ $call = new ClientStreamingCall($this->channel, $method, $deserialize);
+ $call->start($arguments, $metadata);
+ return $call;
}
/**
@@ -112,11 +107,9 @@ class BaseStub {
$argument,
callable $deserialize,
$metadata = array()) {
- return new ServerStreamingSurfaceActiveCall($this->channel,
- $method,
- $deserialize,
- $argument,
- $metadata);
+ $call = new ServerStreamingCall($this->channel, $method, $deserialize);
+ $call->start($argument, $metadata);
+ return $call;
}
/**
@@ -130,9 +123,8 @@ class BaseStub {
public function _bidiRequest($method,
callable $deserialize,
$metadata = array()) {
- return new BidiStreamingSurfaceActiveCall($this->channel,
- $method,
- $deserialize,
- $metadata);
+ $call = new BidiStreamingCall($this->channel, $method, $deserialize);
+ $call->start($metadata);
+ return $call;
}
}
diff --git a/src/php/lib/Grpc/AbstractSurfaceActiveCall.php b/src/php/lib/Grpc/BidiStreamingCall.php
index 9d0af090ce..76c642bef4 100755..100644
--- a/src/php/lib/Grpc/AbstractSurfaceActiveCall.php
+++ b/src/php/lib/Grpc/BidiStreamingCall.php
@@ -1,5 +1,4 @@
<?php
-
/*
*
* Copyright 2015, Google Inc.
@@ -32,67 +31,62 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-
namespace Grpc;
-require_once realpath(dirname(__FILE__) . '/../autoload.php');
-
/**
- * Represents an active call that allows sending and recieving messages.
- * Subclasses restrict how data can be sent and recieved.
+ * Represents an active call that allows for sending and recieving messages in
+ * streams in any order.
*/
-abstract class AbstractSurfaceActiveCall {
- private $active_call;
- private $deserialize;
-
+class BidiStreamingCall extends AbstractCall {
/**
- * Create a new surface active call.
- * @param Channel $channel The channel to communicate on
- * @param string $method The method to call on the remote server
- * @param callable $deserialize The function to deserialize a value
+ * Start the call
* @param array $metadata Metadata to send with the call, if applicable
- * @param long $flags Write flags to use with this call
*/
- public function __construct(Channel $channel,
- $method,
- callable $deserialize,
- $metadata = array(),
- $flags = 0) {
- $this->active_call = new ActiveCall($channel, $method, $metadata, $flags);
- $this->deserialize = $deserialize;
+ public function start($metadata) {
+ $this->call->startBatch([OP_SEND_INITIAL_METADATA => $metadata]);
}
/**
- * @return The metadata sent by the server
+ * Reads the next value from the server.
+ * @return The next value from the server, or null if there is none
*/
- public function getMetadata() {
- return $this->metadata();
+ public function read() {
+ $batch = [OP_RECV_MESSAGE => true];
+ if ($this->metadata === null) {
+ $batch[OP_RECV_INITIAL_METADATA] = true;
+ }
+ $read_event = $this->call->startBatch($batch);
+ if ($this->metadata === null) {
+ $this->metadata = $read_event->metadata;
+ }
+ return $this->deserializeResponse($read_event->message);
}
/**
- * Cancels the call
+ * Write a single message to the server. This cannot be called after
+ * writesDone is called.
+ * @param ByteBuffer $data The data to write
*/
- public function cancel() {
- $this->active_call->cancel();
+ public function write($data) {
+ $this->call->startBatch([OP_SEND_MESSAGE => $data->serialize()]);
}
- protected function _read() {
- $response = $this->active_call->read();
- if ($response === null) {
- return null;
- }
- return call_user_func($this->deserialize, $response);
- }
-
- protected function _write($value) {
- return $this->active_call->write($value->serialize());
- }
-
- protected function _writesDone() {
- $this->active_call->writesDone();
+ /**
+ * Indicate that no more writes will be sent.
+ */
+ public function writesDone() {
+ $this->call->startBatch([OP_SEND_CLOSE_FROM_CLIENT => true]);
}
- protected function _getStatus() {
- return $this->active_call->getStatus();
+ /**
+ * Wait for the server to send the status, and return it.
+ * @return object The status object, with integer $code, string $details,
+ * and array $metadata members
+ */
+ public function getStatus() {
+ $status_event = $this->call->startBatch([
+ OP_RECV_STATUS_ON_CLIENT => true
+ ]);
+ return $status_event->status;
}
-}
+} \ No newline at end of file
diff --git a/src/php/lib/Grpc/ClientStreamingSurfaceActiveCall.php b/src/php/lib/Grpc/ClientStreamingCall.php
index d33f09fbe4..61439d3f47 100755..100644
--- a/src/php/lib/Grpc/ClientStreamingSurfaceActiveCall.php
+++ b/src/php/lib/Grpc/ClientStreamingCall.php
@@ -32,31 +32,23 @@
*
*/
namespace Grpc;
-require_once realpath(dirname(__FILE__) . '/../autoload.php');
/**
* Represents an active call that sends a stream of messages and then gets a
* single response.
*/
-class ClientStreamingSurfaceActiveCall extends AbstractSurfaceActiveCall {
+class ClientStreamingCall extends AbstractCall {
/**
- * Create a new simple (single request/single response) active call.
- * @param Channel $channel The channel to communicate on
- * @param string $method The method to call on the remote server
- * @param callable $deserialize The function to deserialize a value
+ * Start the call.
* @param Traversable $arg_iter The iterator of arguments to send
* @param array $metadata Metadata to send with the call, if applicable
*/
- public function __construct(Channel $channel,
- $method,
- callable $deserialize,
- $arg_iter,
- $metadata = array()) {
- parent::__construct($channel, $method, $deserialize, $metadata, 0);
+ public function start($arg_iter, $metadata = array()) {
+ $event = $this->call->startBatch([OP_SEND_INITIAL_METADATA => $metadata]);
foreach($arg_iter as $arg) {
- $this->_write($arg);
+ $this->call->startBatch([OP_SEND_MESSAGE => $arg->serialize()]);
}
- $this->_writesDone();
+ $this->call->startBatch([OP_SEND_CLOSE_FROM_CLIENT => true]);
}
/**
@@ -64,8 +56,11 @@ class ClientStreamingSurfaceActiveCall extends AbstractSurfaceActiveCall {
* @return [response data, status]
*/
public function wait() {
- $response = $this->_read();
- $status = $this->_getStatus();
- return array($response, $status);
+ $event = $this->call->startBatch([
+ OP_RECV_INITIAL_METADATA => true,
+ OP_RECV_MESSAGE => true,
+ OP_RECV_STATUS_ON_CLIENT => true]);
+ $this->metadata = $event->metadata;
+ return array($this->deserializeResponse($event->message), $event->status);
}
-}
+} \ No newline at end of file
diff --git a/src/php/lib/Grpc/ServerStreamingSurfaceActiveCall.php b/src/php/lib/Grpc/ServerStreamingCall.php
index fd08e86e51..631c863345 100755..100644
--- a/src/php/lib/Grpc/ServerStreamingSurfaceActiveCall.php
+++ b/src/php/lib/Grpc/ServerStreamingCall.php
@@ -33,42 +33,45 @@
*/
namespace Grpc;
-require_once realpath(dirname(__FILE__) . '/../autoload.php');
-
/**
* Represents an active call that sends a single message and then gets a stream
* of reponses
*/
-class ServerStreamingSurfaceActiveCall extends AbstractSurfaceActiveCall {
+class ServerStreamingCall extends AbstractCall {
/**
- * Create a new simple (single request/single response) active call.
- * @param Channel $channel The channel to communicate on
- * @param string $method The method to call on the remote server
- * @param callable $deserialize The function to deserialize a value
+ * Start the call
* @param $arg The argument to send
* @param array $metadata Metadata to send with the call, if applicable
*/
- public function __construct(Channel $channel,
- $method,
- callable $deserialize,
- $arg,
- $metadata = array()) {
- parent::__construct($channel, $method, $deserialize, $metadata,
- \Grpc\WRITE_BUFFER_HINT);
- $this->_write($arg);
- $this->_writesDone();
+ public function start($arg, $metadata = array()) {
+ $event = $this->call->startBatch([
+ OP_SEND_INITIAL_METADATA => $metadata,
+ OP_RECV_INITIAL_METADATA => true,
+ OP_SEND_MESSAGE => $arg->serialize(),
+ OP_SEND_CLOSE_FROM_CLIENT => true]);
+ $this->metadata = $event->metadata;
}
/**
* @return An iterator of response values
*/
public function responses() {
- while(($response = $this->_read()) !== null) {
- yield $response;
+ $response = $this->call->startBatch([OP_RECV_MESSAGE => true])->message;
+ while($response !== null) {
+ yield $this->deserializeResponse($response);
+ $response = $this->call->startBatch([OP_RECV_MESSAGE => true])->message;
}
}
+ /**
+ * Wait for the server to send the status, and return it.
+ * @return object The status object, with integer $code, string $details,
+ * and array $metadata members
+ */
public function getStatus() {
- return $this->_getStatus();
+ $status_event = $this->call->startBatch([
+ OP_RECV_STATUS_ON_CLIENT => true
+ ]);
+ return $status_event->status;
}
-}
+} \ No newline at end of file
diff --git a/src/php/lib/Grpc/SimpleSurfaceActiveCall.php b/src/php/lib/Grpc/UnaryCall.php
index ba82f5704f..97a10a40f4 100755..100644
--- a/src/php/lib/Grpc/SimpleSurfaceActiveCall.php
+++ b/src/php/lib/Grpc/UnaryCall.php
@@ -33,30 +33,23 @@
*/
namespace Grpc;
-require_once realpath(dirname(__FILE__) . '/../autoload.php');
-
/**
* Represents an active call that sends a single message and then gets a single
* response.
*/
-class SimpleSurfaceActiveCall extends AbstractSurfaceActiveCall {
+class UnaryCall extends AbstractCall {
/**
- * Create a new simple (single request/single response) active call.
- * @param Channel $channel The channel to communicate on
- * @param string $method The method to call on the remote server
- * @param callable $deserialize The function to deserialize a value
+ * Start the call
* @param $arg The argument to send
* @param array $metadata Metadata to send with the call, if applicable
*/
- public function __construct(Channel $channel,
- $method,
- callable $deserialize,
- $arg,
- $metadata = array()) {
- parent::__construct($channel, $method, $deserialize, $metadata,
- \Grpc\WRITE_BUFFER_HINT);
- $this->_write($arg);
- $this->_writesDone();
+ public function start($arg, $metadata = array()) {
+ $event = $this->call->startBatch([
+ OP_SEND_INITIAL_METADATA => $metadata,
+ OP_RECV_INITIAL_METADATA => true,
+ OP_SEND_MESSAGE => $arg->serialize(),
+ OP_SEND_CLOSE_FROM_CLIENT => true]);
+ $this->metadata = $event->metadata;
}
/**
@@ -64,8 +57,9 @@ class SimpleSurfaceActiveCall extends AbstractSurfaceActiveCall {
* @return [response data, status]
*/
public function wait() {
- $response = $this->_read();
- $status = $this->_getStatus();
- return array($response, $status);
+ $event = $this->call->startBatch([
+ OP_RECV_MESSAGE => true,
+ OP_RECV_STATUS_ON_CLIENT => true]);
+ return array($this->deserializeResponse($event->message), $event->status);
}
-}
+} \ No newline at end of file
diff --git a/src/php/tests/generated_code/GeneratedCodeTest.php b/src/php/tests/generated_code/GeneratedCodeTest.php
index cb2c0e6d10..927d24ca63 100755
--- a/src/php/tests/generated_code/GeneratedCodeTest.php
+++ b/src/php/tests/generated_code/GeneratedCodeTest.php
@@ -31,7 +31,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-require_once realpath(dirname(__FILE__) . '/../../lib/autoload.php');
+require_once realpath(dirname(__FILE__) . '/../../vendor/autoload.php');
require 'DrSlump/Protobuf.php';
\DrSlump\Protobuf::autoload();
require 'math.php';
@@ -41,7 +41,8 @@ class GeneratedCodeTest extends PHPUnit_Framework_TestCase {
protected static $client;
protected static $timeout;
public static function setUpBeforeClass() {
- self::$client = new math\MathClient(getenv('GRPC_TEST_HOST'));
+ self::$client = new math\MathClient(new Grpc\BaseStub(
+ getenv('GRPC_TEST_HOST'), []));
}
public function testSimpleRequest() {
diff --git a/src/php/tests/generated_code/math.php b/src/php/tests/generated_code/math.php
deleted file mode 100755
index e97a5cf97e..0000000000
--- a/src/php/tests/generated_code/math.php
+++ /dev/null
@@ -1,479 +0,0 @@
-<?php
-// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin 1.0
-// Source: math.proto
-// Date: 2014-11-14 00:00:41
-
-namespace math {
-
- class DivArgs extends \DrSlump\Protobuf\Message {
-
- /** @var int */
- public $dividend = null;
-
- /** @var int */
- public $divisor = null;
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'math.DivArgs');
-
- // REQUIRED INT64 dividend = 1
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 1;
- $f->name = "dividend";
- $f->type = \DrSlump\Protobuf::TYPE_INT64;
- $f->rule = \DrSlump\Protobuf::RULE_REQUIRED;
- $descriptor->addField($f);
-
- // REQUIRED INT64 divisor = 2
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 2;
- $f->name = "divisor";
- $f->type = \DrSlump\Protobuf::TYPE_INT64;
- $f->rule = \DrSlump\Protobuf::RULE_REQUIRED;
- $descriptor->addField($f);
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
-
- /**
- * Check if <dividend> has a value
- *
- * @return boolean
- */
- public function hasDividend(){
- return $this->_has(1);
- }
-
- /**
- * Clear <dividend> value
- *
- * @return \math\DivArgs
- */
- public function clearDividend(){
- return $this->_clear(1);
- }
-
- /**
- * Get <dividend> value
- *
- * @return int
- */
- public function getDividend(){
- return $this->_get(1);
- }
-
- /**
- * Set <dividend> value
- *
- * @param int $value
- * @return \math\DivArgs
- */
- public function setDividend( $value){
- return $this->_set(1, $value);
- }
-
- /**
- * Check if <divisor> has a value
- *
- * @return boolean
- */
- public function hasDivisor(){
- return $this->_has(2);
- }
-
- /**
- * Clear <divisor> value
- *
- * @return \math\DivArgs
- */
- public function clearDivisor(){
- return $this->_clear(2);
- }
-
- /**
- * Get <divisor> value
- *
- * @return int
- */
- public function getDivisor(){
- return $this->_get(2);
- }
-
- /**
- * Set <divisor> value
- *
- * @param int $value
- * @return \math\DivArgs
- */
- public function setDivisor( $value){
- return $this->_set(2, $value);
- }
- }
-}
-
-namespace math {
-
- class DivReply extends \DrSlump\Protobuf\Message {
-
- /** @var int */
- public $quotient = null;
-
- /** @var int */
- public $remainder = null;
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'math.DivReply');
-
- // REQUIRED INT64 quotient = 1
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 1;
- $f->name = "quotient";
- $f->type = \DrSlump\Protobuf::TYPE_INT64;
- $f->rule = \DrSlump\Protobuf::RULE_REQUIRED;
- $descriptor->addField($f);
-
- // REQUIRED INT64 remainder = 2
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 2;
- $f->name = "remainder";
- $f->type = \DrSlump\Protobuf::TYPE_INT64;
- $f->rule = \DrSlump\Protobuf::RULE_REQUIRED;
- $descriptor->addField($f);
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
-
- /**
- * Check if <quotient> has a value
- *
- * @return boolean
- */
- public function hasQuotient(){
- return $this->_has(1);
- }
-
- /**
- * Clear <quotient> value
- *
- * @return \math\DivReply
- */
- public function clearQuotient(){
- return $this->_clear(1);
- }
-
- /**
- * Get <quotient> value
- *
- * @return int
- */
- public function getQuotient(){
- return $this->_get(1);
- }
-
- /**
- * Set <quotient> value
- *
- * @param int $value
- * @return \math\DivReply
- */
- public function setQuotient( $value){
- return $this->_set(1, $value);
- }
-
- /**
- * Check if <remainder> has a value
- *
- * @return boolean
- */
- public function hasRemainder(){
- return $this->_has(2);
- }
-
- /**
- * Clear <remainder> value
- *
- * @return \math\DivReply
- */
- public function clearRemainder(){
- return $this->_clear(2);
- }
-
- /**
- * Get <remainder> value
- *
- * @return int
- */
- public function getRemainder(){
- return $this->_get(2);
- }
-
- /**
- * Set <remainder> value
- *
- * @param int $value
- * @return \math\DivReply
- */
- public function setRemainder( $value){
- return $this->_set(2, $value);
- }
- }
-}
-
-namespace math {
-
- class FibArgs extends \DrSlump\Protobuf\Message {
-
- /** @var int */
- public $limit = null;
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'math.FibArgs');
-
- // OPTIONAL INT64 limit = 1
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 1;
- $f->name = "limit";
- $f->type = \DrSlump\Protobuf::TYPE_INT64;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $descriptor->addField($f);
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
-
- /**
- * Check if <limit> has a value
- *
- * @return boolean
- */
- public function hasLimit(){
- return $this->_has(1);
- }
-
- /**
- * Clear <limit> value
- *
- * @return \math\FibArgs
- */
- public function clearLimit(){
- return $this->_clear(1);
- }
-
- /**
- * Get <limit> value
- *
- * @return int
- */
- public function getLimit(){
- return $this->_get(1);
- }
-
- /**
- * Set <limit> value
- *
- * @param int $value
- * @return \math\FibArgs
- */
- public function setLimit( $value){
- return $this->_set(1, $value);
- }
- }
-}
-
-namespace math {
-
- class Num extends \DrSlump\Protobuf\Message {
-
- /** @var int */
- public $num = null;
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'math.Num');
-
- // REQUIRED INT64 num = 1
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 1;
- $f->name = "num";
- $f->type = \DrSlump\Protobuf::TYPE_INT64;
- $f->rule = \DrSlump\Protobuf::RULE_REQUIRED;
- $descriptor->addField($f);
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
-
- /**
- * Check if <num> has a value
- *
- * @return boolean
- */
- public function hasNum(){
- return $this->_has(1);
- }
-
- /**
- * Clear <num> value
- *
- * @return \math\Num
- */
- public function clearNum(){
- return $this->_clear(1);
- }
-
- /**
- * Get <num> value
- *
- * @return int
- */
- public function getNum(){
- return $this->_get(1);
- }
-
- /**
- * Set <num> value
- *
- * @param int $value
- * @return \math\Num
- */
- public function setNum( $value){
- return $this->_set(1, $value);
- }
- }
-}
-
-namespace math {
-
- class FibReply extends \DrSlump\Protobuf\Message {
-
- /** @var int */
- public $count = null;
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'math.FibReply');
-
- // REQUIRED INT64 count = 1
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 1;
- $f->name = "count";
- $f->type = \DrSlump\Protobuf::TYPE_INT64;
- $f->rule = \DrSlump\Protobuf::RULE_REQUIRED;
- $descriptor->addField($f);
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
-
- /**
- * Check if <count> has a value
- *
- * @return boolean
- */
- public function hasCount(){
- return $this->_has(1);
- }
-
- /**
- * Clear <count> value
- *
- * @return \math\FibReply
- */
- public function clearCount(){
- return $this->_clear(1);
- }
-
- /**
- * Get <count> value
- *
- * @return int
- */
- public function getCount(){
- return $this->_get(1);
- }
-
- /**
- * Set <count> value
- *
- * @param int $value
- * @return \math\FibReply
- */
- public function setCount( $value){
- return $this->_set(1, $value);
- }
- }
-}
-
-namespace math {
-
- class MathClient extends \Grpc\BaseStub {
- /**
- * @param math\DivArgs $input
- * @return math\DivReply
- */
- public function Div(\math\DivArgs $argument, $metadata = array()) {
- return $this->_simpleRequest('/Math/Div', $argument, '\math\DivReply::deserialize', $metadata);
- }
- /**
- * @param math\DivArgs $input
- * @return math\DivReply
- */
- public function DivMany($metadata = array()) {
- return $this->_bidiRequest('/Math/DivMany', '\math\DivReply::deserialize', $metadata);
- }
- /**
- * @param math\FibArgs $input
- * @return math\Num
- */
- public function Fib($argument, $metadata = array()) {
- return $this->_serverStreamRequest('/Math/Fib', $argument, '\math\Num::deserialize', $metadata);
- }
- /**
- * @param math\Num $input
- * @return math\Num
- */
- public function Sum($arguments, $metadata = array()) {
- return $this->_clientStreamRequest('/Math/Sum', $arguments, '\math\Num::deserialize', $metadata);
- }
- }
-}
diff --git a/src/php/tests/generated_code/math.proto b/src/php/tests/generated_code/math.proto
new file mode 100644
index 0000000000..e34ad5e967
--- /dev/null
+++ b/src/php/tests/generated_code/math.proto
@@ -0,0 +1,80 @@
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+package math;
+
+message DivArgs {
+ optional int64 dividend = 1;
+ optional int64 divisor = 2;
+}
+
+message DivReply {
+ optional int64 quotient = 1;
+ optional int64 remainder = 2;
+}
+
+message FibArgs {
+ optional int64 limit = 1;
+}
+
+message Num {
+ optional int64 num = 1;
+}
+
+message FibReply {
+ optional int64 count = 1;
+}
+
+service Math {
+ // Div divides args.dividend by args.divisor and returns the quotient and
+ // remainder.
+ rpc Div (DivArgs) returns (DivReply) {
+ }
+
+ // DivMany accepts an arbitrary number of division args from the client stream
+ // and sends back the results in the reply stream. The stream continues until
+ // the client closes its end; the server does the same after sending all the
+ // replies. The stream ends immediately if either end aborts.
+ rpc DivMany (stream DivArgs) returns (stream DivReply) {
+ }
+
+ // Fib generates numbers in the Fibonacci sequence. If args.limit > 0, Fib
+ // generates up to limit numbers; otherwise it continues until the call is
+ // canceled. Unlike Fib above, Fib has no final FibReply.
+ rpc Fib (FibArgs) returns (stream Num) {
+ }
+
+ // Sum sums a stream of numbers, returning the final result once the stream
+ // is closed.
+ rpc Sum (stream Num) returns (Num) {
+ }
+}
diff --git a/src/php/tests/interop/empty.php b/src/php/tests/interop/empty.php
deleted file mode 100755
index 22b11803b6..0000000000
--- a/src/php/tests/interop/empty.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin 1.0
-// Source: test/cpp/interop/empty.proto
-// Date: 2015-01-30 23:30:46
-
-namespace grpc\testing {
-
- class EmptyMessage extends \DrSlump\Protobuf\Message {
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.EmptyMessage');
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
- }
-}
diff --git a/src/php/tests/interop/empty.proto b/src/php/tests/interop/empty.proto
new file mode 100644
index 0000000000..4200d7b519
--- /dev/null
+++ b/src/php/tests/interop/empty.proto
@@ -0,0 +1,43 @@
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+
+package grpc.testing;
+
+// An empty message that you can re-use to avoid defining duplicated empty
+// messages in your project. A typical example is to use it as argument or the
+// return value of a service API. For instance:
+//
+// service Foo {
+// rpc Bar (grpc.testing.EmptyMessage) returns (grpc.testing.EmptyMessage) { };
+// };
+//
+message EmptyMessage {}
diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php
index 82ca438169..6f81bfa6cd 100755
--- a/src/php/tests/interop/interop_client.php
+++ b/src/php/tests/interop/interop_client.php
@@ -31,7 +31,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-require_once realpath(dirname(__FILE__) . '/../../lib/autoload.php');
+require_once realpath(dirname(__FILE__) . '/../../vendor/autoload.php');
require 'DrSlump/Protobuf.php';
\DrSlump\Protobuf::autoload();
require 'empty.php';
@@ -132,8 +132,6 @@ function serverStreaming($stub) {
}
$call = $stub->StreamingOutputCall($request);
- hardAssert($call->getStatus()->code === Grpc\STATUS_OK,
- 'Call did not complete successfully');
$i = 0;
foreach($call->responses() as $value) {
hardAssert($i < 4, 'Too many responses');
@@ -142,7 +140,10 @@ function serverStreaming($stub) {
'Payload ' . $i . ' had the wrong type');
hardAssert(strlen($payload->getBody()) === $sizes[$i],
'Response ' . $i . ' had the wrong length');
+ $i += 1;
}
+ hardAssert($call->getStatus()->code === Grpc\STATUS_OK,
+ 'Call did not complete successfully');
}
/**
@@ -240,4 +241,7 @@ switch($args['test_case']) {
break;
case 'cancel_after_first_response':
cancelAfterFirstResponse($stub);
+ break;
+ default:
+ exit(1);
}
diff --git a/src/php/tests/interop/messages.php b/src/php/tests/interop/messages.php
deleted file mode 100755
index a626a17ab3..0000000000
--- a/src/php/tests/interop/messages.php
+++ /dev/null
@@ -1,1074 +0,0 @@
-<?php
-// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin 1.0
-// Source: test/cpp/interop/messages.proto
-// Date: 2015-01-30 23:30:46
-
-namespace grpc\testing {
-
- class PayloadType extends \DrSlump\Protobuf\Enum {
- const COMPRESSABLE = 0;
- const UNCOMPRESSABLE = 1;
- const RANDOM = 2;
- }
-}
-namespace grpc\testing {
-
- class Payload extends \DrSlump\Protobuf\Message {
-
- /** @var int - \grpc\testing\PayloadType */
- public $type = null;
-
- /** @var string */
- public $body = null;
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.Payload');
-
- // OPTIONAL ENUM type = 1
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 1;
- $f->name = "type";
- $f->type = \DrSlump\Protobuf::TYPE_ENUM;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $f->reference = '\grpc\testing\PayloadType';
- $descriptor->addField($f);
-
- // OPTIONAL BYTES body = 2
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 2;
- $f->name = "body";
- $f->type = \DrSlump\Protobuf::TYPE_BYTES;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $descriptor->addField($f);
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
-
- /**
- * Check if <type> has a value
- *
- * @return boolean
- */
- public function hasType(){
- return $this->_has(1);
- }
-
- /**
- * Clear <type> value
- *
- * @return \grpc\testing\Payload
- */
- public function clearType(){
- return $this->_clear(1);
- }
-
- /**
- * Get <type> value
- *
- * @return int - \grpc\testing\PayloadType
- */
- public function getType(){
- return $this->_get(1);
- }
-
- /**
- * Set <type> value
- *
- * @param int - \grpc\testing\PayloadType $value
- * @return \grpc\testing\Payload
- */
- public function setType( $value){
- return $this->_set(1, $value);
- }
-
- /**
- * Check if <body> has a value
- *
- * @return boolean
- */
- public function hasBody(){
- return $this->_has(2);
- }
-
- /**
- * Clear <body> value
- *
- * @return \grpc\testing\Payload
- */
- public function clearBody(){
- return $this->_clear(2);
- }
-
- /**
- * Get <body> value
- *
- * @return string
- */
- public function getBody(){
- return $this->_get(2);
- }
-
- /**
- * Set <body> value
- *
- * @param string $value
- * @return \grpc\testing\Payload
- */
- public function setBody( $value){
- return $this->_set(2, $value);
- }
- }
-}
-
-namespace grpc\testing {
-
- class SimpleRequest extends \DrSlump\Protobuf\Message {
-
- /** @var int - \grpc\testing\PayloadType */
- public $response_type = null;
-
- /** @var int */
- public $response_size = null;
-
- /** @var \grpc\testing\Payload */
- public $payload = null;
-
- /** @var boolean */
- public $fill_username = null;
-
- /** @var boolean */
- public $fill_oauth_scope = null;
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.SimpleRequest');
-
- // OPTIONAL ENUM response_type = 1
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 1;
- $f->name = "response_type";
- $f->type = \DrSlump\Protobuf::TYPE_ENUM;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $f->reference = '\grpc\testing\PayloadType';
- $descriptor->addField($f);
-
- // OPTIONAL INT32 response_size = 2
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 2;
- $f->name = "response_size";
- $f->type = \DrSlump\Protobuf::TYPE_INT32;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $descriptor->addField($f);
-
- // OPTIONAL MESSAGE payload = 3
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 3;
- $f->name = "payload";
- $f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $f->reference = '\grpc\testing\Payload';
- $descriptor->addField($f);
-
- // OPTIONAL BOOL fill_username = 4
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 4;
- $f->name = "fill_username";
- $f->type = \DrSlump\Protobuf::TYPE_BOOL;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $descriptor->addField($f);
-
- // OPTIONAL BOOL fill_oauth_scope = 5
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 5;
- $f->name = "fill_oauth_scope";
- $f->type = \DrSlump\Protobuf::TYPE_BOOL;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $descriptor->addField($f);
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
-
- /**
- * Check if <response_type> has a value
- *
- * @return boolean
- */
- public function hasResponseType(){
- return $this->_has(1);
- }
-
- /**
- * Clear <response_type> value
- *
- * @return \grpc\testing\SimpleRequest
- */
- public function clearResponseType(){
- return $this->_clear(1);
- }
-
- /**
- * Get <response_type> value
- *
- * @return int - \grpc\testing\PayloadType
- */
- public function getResponseType(){
- return $this->_get(1);
- }
-
- /**
- * Set <response_type> value
- *
- * @param int - \grpc\testing\PayloadType $value
- * @return \grpc\testing\SimpleRequest
- */
- public function setResponseType( $value){
- return $this->_set(1, $value);
- }
-
- /**
- * Check if <response_size> has a value
- *
- * @return boolean
- */
- public function hasResponseSize(){
- return $this->_has(2);
- }
-
- /**
- * Clear <response_size> value
- *
- * @return \grpc\testing\SimpleRequest
- */
- public function clearResponseSize(){
- return $this->_clear(2);
- }
-
- /**
- * Get <response_size> value
- *
- * @return int
- */
- public function getResponseSize(){
- return $this->_get(2);
- }
-
- /**
- * Set <response_size> value
- *
- * @param int $value
- * @return \grpc\testing\SimpleRequest
- */
- public function setResponseSize( $value){
- return $this->_set(2, $value);
- }
-
- /**
- * Check if <payload> has a value
- *
- * @return boolean
- */
- public function hasPayload(){
- return $this->_has(3);
- }
-
- /**
- * Clear <payload> value
- *
- * @return \grpc\testing\SimpleRequest
- */
- public function clearPayload(){
- return $this->_clear(3);
- }
-
- /**
- * Get <payload> value
- *
- * @return \grpc\testing\Payload
- */
- public function getPayload(){
- return $this->_get(3);
- }
-
- /**
- * Set <payload> value
- *
- * @param \grpc\testing\Payload $value
- * @return \grpc\testing\SimpleRequest
- */
- public function setPayload(\grpc\testing\Payload $value){
- return $this->_set(3, $value);
- }
-
- /**
- * Check if <fill_username> has a value
- *
- * @return boolean
- */
- public function hasFillUsername(){
- return $this->_has(4);
- }
-
- /**
- * Clear <fill_username> value
- *
- * @return \grpc\testing\SimpleRequest
- */
- public function clearFillUsername(){
- return $this->_clear(4);
- }
-
- /**
- * Get <fill_username> value
- *
- * @return boolean
- */
- public function getFillUsername(){
- return $this->_get(4);
- }
-
- /**
- * Set <fill_username> value
- *
- * @param boolean $value
- * @return \grpc\testing\SimpleRequest
- */
- public function setFillUsername( $value){
- return $this->_set(4, $value);
- }
-
- /**
- * Check if <fill_oauth_scope> has a value
- *
- * @return boolean
- */
- public function hasFillOauthScope(){
- return $this->_has(5);
- }
-
- /**
- * Clear <fill_oauth_scope> value
- *
- * @return \grpc\testing\SimpleRequest
- */
- public function clearFillOauthScope(){
- return $this->_clear(5);
- }
-
- /**
- * Get <fill_oauth_scope> value
- *
- * @return boolean
- */
- public function getFillOauthScope(){
- return $this->_get(5);
- }
-
- /**
- * Set <fill_oauth_scope> value
- *
- * @param boolean $value
- * @return \grpc\testing\SimpleRequest
- */
- public function setFillOauthScope( $value){
- return $this->_set(5, $value);
- }
- }
-}
-
-namespace grpc\testing {
-
- class SimpleResponse extends \DrSlump\Protobuf\Message {
-
- /** @var \grpc\testing\Payload */
- public $payload = null;
-
- /** @var string */
- public $username = null;
-
- /** @var string */
- public $oauth_scope = null;
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.SimpleResponse');
-
- // OPTIONAL MESSAGE payload = 1
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 1;
- $f->name = "payload";
- $f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $f->reference = '\grpc\testing\Payload';
- $descriptor->addField($f);
-
- // OPTIONAL STRING username = 2
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 2;
- $f->name = "username";
- $f->type = \DrSlump\Protobuf::TYPE_STRING;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $descriptor->addField($f);
-
- // OPTIONAL STRING oauth_scope = 3
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 3;
- $f->name = "oauth_scope";
- $f->type = \DrSlump\Protobuf::TYPE_STRING;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $descriptor->addField($f);
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
-
- /**
- * Check if <payload> has a value
- *
- * @return boolean
- */
- public function hasPayload(){
- return $this->_has(1);
- }
-
- /**
- * Clear <payload> value
- *
- * @return \grpc\testing\SimpleResponse
- */
- public function clearPayload(){
- return $this->_clear(1);
- }
-
- /**
- * Get <payload> value
- *
- * @return \grpc\testing\Payload
- */
- public function getPayload(){
- return $this->_get(1);
- }
-
- /**
- * Set <payload> value
- *
- * @param \grpc\testing\Payload $value
- * @return \grpc\testing\SimpleResponse
- */
- public function setPayload(\grpc\testing\Payload $value){
- return $this->_set(1, $value);
- }
-
- /**
- * Check if <username> has a value
- *
- * @return boolean
- */
- public function hasUsername(){
- return $this->_has(2);
- }
-
- /**
- * Clear <username> value
- *
- * @return \grpc\testing\SimpleResponse
- */
- public function clearUsername(){
- return $this->_clear(2);
- }
-
- /**
- * Get <username> value
- *
- * @return string
- */
- public function getUsername(){
- return $this->_get(2);
- }
-
- /**
- * Set <username> value
- *
- * @param string $value
- * @return \grpc\testing\SimpleResponse
- */
- public function setUsername( $value){
- return $this->_set(2, $value);
- }
-
- /**
- * Check if <oauth_scope> has a value
- *
- * @return boolean
- */
- public function hasOauthScope(){
- return $this->_has(3);
- }
-
- /**
- * Clear <oauth_scope> value
- *
- * @return \grpc\testing\SimpleResponse
- */
- public function clearOauthScope(){
- return $this->_clear(3);
- }
-
- /**
- * Get <oauth_scope> value
- *
- * @return string
- */
- public function getOauthScope(){
- return $this->_get(3);
- }
-
- /**
- * Set <oauth_scope> value
- *
- * @param string $value
- * @return \grpc\testing\SimpleResponse
- */
- public function setOauthScope( $value){
- return $this->_set(3, $value);
- }
- }
-}
-
-namespace grpc\testing {
-
- class StreamingInputCallRequest extends \DrSlump\Protobuf\Message {
-
- /** @var \grpc\testing\Payload */
- public $payload = null;
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.StreamingInputCallRequest');
-
- // OPTIONAL MESSAGE payload = 1
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 1;
- $f->name = "payload";
- $f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $f->reference = '\grpc\testing\Payload';
- $descriptor->addField($f);
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
-
- /**
- * Check if <payload> has a value
- *
- * @return boolean
- */
- public function hasPayload(){
- return $this->_has(1);
- }
-
- /**
- * Clear <payload> value
- *
- * @return \grpc\testing\StreamingInputCallRequest
- */
- public function clearPayload(){
- return $this->_clear(1);
- }
-
- /**
- * Get <payload> value
- *
- * @return \grpc\testing\Payload
- */
- public function getPayload(){
- return $this->_get(1);
- }
-
- /**
- * Set <payload> value
- *
- * @param \grpc\testing\Payload $value
- * @return \grpc\testing\StreamingInputCallRequest
- */
- public function setPayload(\grpc\testing\Payload $value){
- return $this->_set(1, $value);
- }
- }
-}
-
-namespace grpc\testing {
-
- class StreamingInputCallResponse extends \DrSlump\Protobuf\Message {
-
- /** @var int */
- public $aggregated_payload_size = null;
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.StreamingInputCallResponse');
-
- // OPTIONAL INT32 aggregated_payload_size = 1
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 1;
- $f->name = "aggregated_payload_size";
- $f->type = \DrSlump\Protobuf::TYPE_INT32;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $descriptor->addField($f);
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
-
- /**
- * Check if <aggregated_payload_size> has a value
- *
- * @return boolean
- */
- public function hasAggregatedPayloadSize(){
- return $this->_has(1);
- }
-
- /**
- * Clear <aggregated_payload_size> value
- *
- * @return \grpc\testing\StreamingInputCallResponse
- */
- public function clearAggregatedPayloadSize(){
- return $this->_clear(1);
- }
-
- /**
- * Get <aggregated_payload_size> value
- *
- * @return int
- */
- public function getAggregatedPayloadSize(){
- return $this->_get(1);
- }
-
- /**
- * Set <aggregated_payload_size> value
- *
- * @param int $value
- * @return \grpc\testing\StreamingInputCallResponse
- */
- public function setAggregatedPayloadSize( $value){
- return $this->_set(1, $value);
- }
- }
-}
-
-namespace grpc\testing {
-
- class ResponseParameters extends \DrSlump\Protobuf\Message {
-
- /** @var int */
- public $size = null;
-
- /** @var int */
- public $interval_us = null;
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.ResponseParameters');
-
- // OPTIONAL INT32 size = 1
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 1;
- $f->name = "size";
- $f->type = \DrSlump\Protobuf::TYPE_INT32;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $descriptor->addField($f);
-
- // OPTIONAL INT32 interval_us = 2
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 2;
- $f->name = "interval_us";
- $f->type = \DrSlump\Protobuf::TYPE_INT32;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $descriptor->addField($f);
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
-
- /**
- * Check if <size> has a value
- *
- * @return boolean
- */
- public function hasSize(){
- return $this->_has(1);
- }
-
- /**
- * Clear <size> value
- *
- * @return \grpc\testing\ResponseParameters
- */
- public function clearSize(){
- return $this->_clear(1);
- }
-
- /**
- * Get <size> value
- *
- * @return int
- */
- public function getSize(){
- return $this->_get(1);
- }
-
- /**
- * Set <size> value
- *
- * @param int $value
- * @return \grpc\testing\ResponseParameters
- */
- public function setSize( $value){
- return $this->_set(1, $value);
- }
-
- /**
- * Check if <interval_us> has a value
- *
- * @return boolean
- */
- public function hasIntervalUs(){
- return $this->_has(2);
- }
-
- /**
- * Clear <interval_us> value
- *
- * @return \grpc\testing\ResponseParameters
- */
- public function clearIntervalUs(){
- return $this->_clear(2);
- }
-
- /**
- * Get <interval_us> value
- *
- * @return int
- */
- public function getIntervalUs(){
- return $this->_get(2);
- }
-
- /**
- * Set <interval_us> value
- *
- * @param int $value
- * @return \grpc\testing\ResponseParameters
- */
- public function setIntervalUs( $value){
- return $this->_set(2, $value);
- }
- }
-}
-
-namespace grpc\testing {
-
- class StreamingOutputCallRequest extends \DrSlump\Protobuf\Message {
-
- /** @var int - \grpc\testing\PayloadType */
- public $response_type = null;
-
- /** @var \grpc\testing\ResponseParameters[] */
- public $response_parameters = array();
-
- /** @var \grpc\testing\Payload */
- public $payload = null;
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.StreamingOutputCallRequest');
-
- // OPTIONAL ENUM response_type = 1
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 1;
- $f->name = "response_type";
- $f->type = \DrSlump\Protobuf::TYPE_ENUM;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $f->reference = '\grpc\testing\PayloadType';
- $descriptor->addField($f);
-
- // REPEATED MESSAGE response_parameters = 2
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 2;
- $f->name = "response_parameters";
- $f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
- $f->rule = \DrSlump\Protobuf::RULE_REPEATED;
- $f->reference = '\grpc\testing\ResponseParameters';
- $descriptor->addField($f);
-
- // OPTIONAL MESSAGE payload = 3
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 3;
- $f->name = "payload";
- $f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $f->reference = '\grpc\testing\Payload';
- $descriptor->addField($f);
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
-
- /**
- * Check if <response_type> has a value
- *
- * @return boolean
- */
- public function hasResponseType(){
- return $this->_has(1);
- }
-
- /**
- * Clear <response_type> value
- *
- * @return \grpc\testing\StreamingOutputCallRequest
- */
- public function clearResponseType(){
- return $this->_clear(1);
- }
-
- /**
- * Get <response_type> value
- *
- * @return int - \grpc\testing\PayloadType
- */
- public function getResponseType(){
- return $this->_get(1);
- }
-
- /**
- * Set <response_type> value
- *
- * @param int - \grpc\testing\PayloadType $value
- * @return \grpc\testing\StreamingOutputCallRequest
- */
- public function setResponseType( $value){
- return $this->_set(1, $value);
- }
-
- /**
- * Check if <response_parameters> has a value
- *
- * @return boolean
- */
- public function hasResponseParameters(){
- return $this->_has(2);
- }
-
- /**
- * Clear <response_parameters> value
- *
- * @return \grpc\testing\StreamingOutputCallRequest
- */
- public function clearResponseParameters(){
- return $this->_clear(2);
- }
-
- /**
- * Get <response_parameters> value
- *
- * @param int $idx
- * @return \grpc\testing\ResponseParameters
- */
- public function getResponseParameters($idx = NULL){
- return $this->_get(2, $idx);
- }
-
- /**
- * Set <response_parameters> value
- *
- * @param \grpc\testing\ResponseParameters $value
- * @return \grpc\testing\StreamingOutputCallRequest
- */
- public function setResponseParameters(\grpc\testing\ResponseParameters $value, $idx = NULL){
- return $this->_set(2, $value, $idx);
- }
-
- /**
- * Get all elements of <response_parameters>
- *
- * @return \grpc\testing\ResponseParameters[]
- */
- public function getResponseParametersList(){
- return $this->_get(2);
- }
-
- /**
- * Add a new element to <response_parameters>
- *
- * @param \grpc\testing\ResponseParameters $value
- * @return \grpc\testing\StreamingOutputCallRequest
- */
- public function addResponseParameters(\grpc\testing\ResponseParameters $value){
- return $this->_add(2, $value);
- }
-
- /**
- * Check if <payload> has a value
- *
- * @return boolean
- */
- public function hasPayload(){
- return $this->_has(3);
- }
-
- /**
- * Clear <payload> value
- *
- * @return \grpc\testing\StreamingOutputCallRequest
- */
- public function clearPayload(){
- return $this->_clear(3);
- }
-
- /**
- * Get <payload> value
- *
- * @return \grpc\testing\Payload
- */
- public function getPayload(){
- return $this->_get(3);
- }
-
- /**
- * Set <payload> value
- *
- * @param \grpc\testing\Payload $value
- * @return \grpc\testing\StreamingOutputCallRequest
- */
- public function setPayload(\grpc\testing\Payload $value){
- return $this->_set(3, $value);
- }
- }
-}
-
-namespace grpc\testing {
-
- class StreamingOutputCallResponse extends \DrSlump\Protobuf\Message {
-
- /** @var \grpc\testing\Payload */
- public $payload = null;
-
-
- /** @var \Closure[] */
- protected static $__extensions = array();
-
- public static function descriptor()
- {
- $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.StreamingOutputCallResponse');
-
- // OPTIONAL MESSAGE payload = 1
- $f = new \DrSlump\Protobuf\Field();
- $f->number = 1;
- $f->name = "payload";
- $f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
- $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
- $f->reference = '\grpc\testing\Payload';
- $descriptor->addField($f);
-
- foreach (self::$__extensions as $cb) {
- $descriptor->addField($cb(), true);
- }
-
- return $descriptor;
- }
-
- /**
- * Check if <payload> has a value
- *
- * @return boolean
- */
- public function hasPayload(){
- return $this->_has(1);
- }
-
- /**
- * Clear <payload> value
- *
- * @return \grpc\testing\StreamingOutputCallResponse
- */
- public function clearPayload(){
- return $this->_clear(1);
- }
-
- /**
- * Get <payload> value
- *
- * @return \grpc\testing\Payload
- */
- public function getPayload(){
- return $this->_get(1);
- }
-
- /**
- * Set <payload> value
- *
- * @param \grpc\testing\Payload $value
- * @return \grpc\testing\StreamingOutputCallResponse
- */
- public function setPayload(\grpc\testing\Payload $value){
- return $this->_set(1, $value);
- }
- }
-}
-
diff --git a/src/php/tests/interop/messages.proto b/src/php/tests/interop/messages.proto
new file mode 100644
index 0000000000..de0b1a2320
--- /dev/null
+++ b/src/php/tests/interop/messages.proto
@@ -0,0 +1,132 @@
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Message definitions to be used by integration test service definitions.
+
+syntax = "proto2";
+
+package grpc.testing;
+
+// The type of payload that should be returned.
+enum PayloadType {
+ // Compressable text format.
+ COMPRESSABLE = 0;
+
+ // Uncompressable binary format.
+ UNCOMPRESSABLE = 1;
+
+ // Randomly chosen from all other formats defined in this enum.
+ RANDOM = 2;
+}
+
+// A block of data, to simply increase gRPC message size.
+message Payload {
+ // The type of data in body.
+ optional PayloadType type = 1 [default = COMPRESSABLE];
+ // Primary contents of payload.
+ optional bytes body = 2;
+}
+
+// Unary request.
+message SimpleRequest {
+ // Desired payload type in the response from the server.
+ // If response_type is RANDOM, server randomly chooses one from other formats.
+ optional PayloadType response_type = 1 [default = COMPRESSABLE];
+
+ // Desired payload size in the response from the server.
+ // If response_type is COMPRESSABLE, this denotes the size before compression.
+ optional int32 response_size = 2;
+
+ // Optional input payload sent along with the request.
+ optional Payload payload = 3;
+
+ // Whether SimpleResponse should include username.
+ optional bool fill_username = 4;
+
+ // Whether SimpleResponse should include OAuth scope.
+ optional bool fill_oauth_scope = 5;
+}
+
+// Unary response, as configured by the request.
+message SimpleResponse {
+ // Payload to increase message size.
+ optional Payload payload = 1;
+ // The user the request came from, for verifying authentication was
+ // successful when the client expected it.
+ optional string username = 2;
+ // OAuth scope.
+ optional string oauth_scope = 3;
+}
+
+// Client-streaming request.
+message StreamingInputCallRequest {
+ // Optional input payload sent along with the request.
+ optional Payload payload = 1;
+
+ // Not expecting any payload from the response.
+}
+
+// Client-streaming response.
+message StreamingInputCallResponse {
+ // Aggregated size of payloads received from the client.
+ optional int32 aggregated_payload_size = 1;
+}
+
+// Configuration for a particular response.
+message ResponseParameters {
+ // Desired payload sizes in responses from the server.
+ // If response_type is COMPRESSABLE, this denotes the size before compression.
+ optional int32 size = 1;
+
+ // Desired interval between consecutive responses in the response stream in
+ // microseconds.
+ optional int32 interval_us = 2;
+}
+
+// Server-streaming request.
+message StreamingOutputCallRequest {
+ // Desired payload type in the response from the server.
+ // If response_type is RANDOM, the payload from each response in the stream
+ // might be of different types. This is to simulate a mixed type of payload
+ // stream.
+ optional PayloadType response_type = 1 [default = COMPRESSABLE];
+
+ // Configuration for each expected response message.
+ repeated ResponseParameters response_parameters = 2;
+
+ // Optional input payload sent along with the request.
+ optional Payload payload = 3;
+}
+
+// Server-streaming response, as configured by the request and parameters.
+message StreamingOutputCallResponse {
+ // Payload to increase response size.
+ optional Payload payload = 1;
+}
diff --git a/src/php/tests/interop/test.php b/src/php/tests/interop/test.php
deleted file mode 100755
index 014bbc9517..0000000000
--- a/src/php/tests/interop/test.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin 1.0
-// Source: test/cpp/interop/test.proto
-// Date: 2015-01-30 23:30:46
-
-namespace grpc\testing {
-
- class TestServiceClient{
-
- private $rpc_impl;
-
- public function __construct($rpc_impl) {
- $this->rpc_impl = $rpc_impl;
- }
- /**
- * @param grpc\testing\EmptyMessage $input
- */
- public function EmptyCall(\grpc\testing\EmptyMessage $argument, $metadata = array()) {
- return $this->rpc_impl->_simpleRequest('/grpc.testing.TestService/EmptyCall', $argument, '\grpc\testing\EmptyMessage::deserialize', $metadata);
- }
- /**
- * @param grpc\testing\SimpleRequest $input
- */
- public function UnaryCall(\grpc\testing\SimpleRequest $argument, $metadata = array()) {
- return $this->rpc_impl->_simpleRequest('/grpc.testing.TestService/UnaryCall', $argument, '\grpc\testing\SimpleResponse::deserialize', $metadata);
- }
- /**
- * @param grpc\testing\StreamingOutputCallRequest $input
- */
- public function StreamingOutputCall($argument, $metadata = array()) {
- return $this->rpc_impl->_serverStreamRequest('/grpc.testing.TestService/StreamingOutputCall', $argument, '\grpc\testing\StreamingOutputCallResponse::deserialize', $metadata);
- }
- /**
- * @param grpc\testing\StreamingInputCallRequest $input
- */
- public function StreamingInputCall($arguments, $metadata = array()) {
- return $this->rpc_impl->_clientStreamRequest('/grpc.testing.TestService/StreamingInputCall', $arguments, '\grpc\testing\StreamingInputCallResponse::deserialize', $metadata);
- }
- /**
- * @param grpc\testing\StreamingOutputCallRequest $input
- */
- public function FullDuplexCall($metadata = array()) {
- return $this->rpc_impl->_bidiRequest('/grpc.testing.TestService/FullDuplexCall', '\grpc\testing\StreamingOutputCallResponse::deserialize', $metadata);
- }
- /**
- * @param grpc\testing\StreamingOutputCallRequest $input
- */
- public function HalfDuplexCall($metadata = array()) {
- return $this->rpc_impl->_bidiRequest('/grpc.testing.TestService/HalfDuplexCall', '\grpc\testing\StreamingOutputCallResponse::deserialize', $metadata);
- }
- }
-}
diff --git a/src/php/tests/interop/test.proto b/src/php/tests/interop/test.proto
new file mode 100644
index 0000000000..39c08f3544
--- /dev/null
+++ b/src/php/tests/interop/test.proto
@@ -0,0 +1,72 @@
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+syntax = "proto2";
+
+import "empty.proto";
+import "messages.proto";
+
+package grpc.testing;
+
+// A simple service to test the various types of RPCs and experiment with
+// performance with various types of payload.
+service TestService {
+ // One empty request followed by one empty response.
+ rpc EmptyCall(grpc.testing.EmptyMessage) returns (grpc.testing.EmptyMessage);
+
+ // One request followed by one response.
+ // TODO(Issue 527): Describe required server behavior.
+ rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
+
+ // One request followed by a sequence of responses (streamed download).
+ // The server returns the payload with client desired type and sizes.
+ rpc StreamingOutputCall(StreamingOutputCallRequest)
+ returns (stream StreamingOutputCallResponse);
+
+ // A sequence of requests followed by one response (streamed upload).
+ // The server returns the aggregated size of client payload as the result.
+ rpc StreamingInputCall(stream StreamingInputCallRequest)
+ returns (StreamingInputCallResponse);
+
+ // A sequence of requests with each request served by the server immediately.
+ // As one request could lead to multiple responses, this interface
+ // demonstrates the idea of full duplexing.
+ rpc FullDuplexCall(stream StreamingOutputCallRequest)
+ returns (stream StreamingOutputCallResponse);
+
+ // A sequence of requests followed by a sequence of responses.
+ // The server buffers all the client requests and then serves them in order. A
+ // stream of responses are returned to the client when the server starts with
+ // first request.
+ rpc HalfDuplexCall(stream StreamingOutputCallRequest)
+ returns (stream StreamingOutputCallResponse);
+}
diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php
index 8bb0927f21..77a2d86ce4 100755
--- a/src/php/tests/unit_tests/CallTest.php
+++ b/src/php/tests/unit_tests/CallTest.php
@@ -36,65 +36,47 @@ class CallTest extends PHPUnit_Framework_TestCase{
static $port;
public static function setUpBeforeClass() {
- $cq = new Grpc\CompletionQueue();
- self::$server = new Grpc\Server($cq, []);
- self::$port = self::$server->add_http2_port('0.0.0.0:0');
+ self::$server = new Grpc\Server([]);
+ self::$port = self::$server->addHttp2Port('0.0.0.0:0');
}
public function setUp() {
- $this->cq = new Grpc\CompletionQueue();
$this->channel = new Grpc\Channel('localhost:' . self::$port, []);
$this->call = new Grpc\Call($this->channel,
'/foo',
- Grpc\Timeval::inf_future());
+ Grpc\Timeval::infFuture());
}
- /**
- * @expectedException LogicException
- * @expectedExceptionCode Grpc\CALL_ERROR_INVALID_FLAGS
- * @expectedExceptionMessage invoke
- */
- public function testInvokeRejectsBadFlags() {
- $this->call->invoke($this->cq, 0, 0, 0xDEADBEEF);
- }
-
- /**
- * @expectedException LogicException
- * @expectedExceptionCode Grpc\CALL_ERROR_NOT_ON_CLIENT
- * @expectedExceptionMessage server_accept
- */
- public function testServerAcceptFailsCorrectly() {
- $this->call->server_accept($this->cq, 0);
- }
-
- /* These test methods with assertTrue(true) at the end just check that the
- method calls completed without errors. PHPUnit warns for tests with no
- asserts, and this avoids that warning without changing the meaning of the
- tests */
-
public function testAddEmptyMetadata() {
- $this->call->add_metadata([], 0);
- /* Dummy assert: Checks that the previous call completed without error */
- $this->assertTrue(true);
+ $batch = [
+ Grpc\OP_SEND_INITIAL_METADATA => []
+ ];
+ $result = $this->call->startBatch($batch);
+ $this->assertTrue($result->send_metadata);
}
public function testAddSingleMetadata() {
- $this->call->add_metadata(['key' => ['value']], 0);
- /* Dummy assert: Checks that the previous call completed without error */
- $this->assertTrue(true);
+ $batch = [
+ Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value']]
+ ];
+ $result = $this->call->startBatch($batch);
+ $this->assertTrue($result->send_metadata);
}
public function testAddMultiValueMetadata() {
- $this->call->add_metadata(['key' => ['value1', 'value2']], 0);
- /* Dummy assert: Checks that the previous call completed without error */
- $this->assertTrue(true);
+ $batch = [
+ Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value1', 'value2']]
+ ];
+ $result = $this->call->startBatch($batch);
+ $this->assertTrue($result->send_metadata);
}
public function testAddSingleAndMultiValueMetadata() {
- $this->call->add_metadata(
- ['key1' => ['value1'],
- 'key2' => ['value2', 'value3']], 0);
- /* Dummy assert: Checks that the previous call completed without error */
- $this->assertTrue(true);
+ $batch = [
+ Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'],
+ 'key2' => ['value2', 'value3']]
+ ];
+ $result = $this->call->startBatch($batch);
+ $this->assertTrue($result->send_metadata);
}
}
diff --git a/src/php/tests/unit_tests/EndToEndTest.php b/src/php/tests/unit_tests/EndToEndTest.php
index 0cbc506c8e..296873fa8f 100755
--- a/src/php/tests/unit_tests/EndToEndTest.php
+++ b/src/php/tests/unit_tests/EndToEndTest.php
@@ -33,81 +33,68 @@
*/
class EndToEndTest extends PHPUnit_Framework_TestCase{
public function setUp() {
- $this->client_queue = new Grpc\CompletionQueue();
- $this->server_queue = new Grpc\CompletionQueue();
- $this->server = new Grpc\Server($this->server_queue, []);
- $port = $this->server->add_http2_port('0.0.0.0:0');
+ $this->server = new Grpc\Server([]);
+ $port = $this->server->addHttp2Port('0.0.0.0:0');
$this->channel = new Grpc\Channel('localhost:' . $port, []);
+ $this->server->start();
}
public function tearDown() {
unset($this->channel);
unset($this->server);
- unset($this->client_queue);
- unset($this->server_queue);
}
public function testSimpleRequestBody() {
- $deadline = Grpc\Timeval::inf_future();
+ $deadline = Grpc\Timeval::infFuture();
$status_text = 'xyz';
$call = new Grpc\Call($this->channel,
'dummy_method',
$deadline);
- $tag = 1;
- $call->invoke($this->client_queue, $tag, $tag);
- $server_tag = 2;
-
- $call->writes_done($tag);
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
-
- // check that a server rpc new was received
- $this->server->start();
- $this->server->request_call($server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\SERVER_RPC_NEW, $event->type);
- $server_call = $event->call;
- $this->assertNotNull($server_call);
- $server_call->server_accept($this->server_queue, $server_tag);
-
- $server_call->server_end_initial_metadata();
+ $event = $call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_CLOSE_FROM_CLIENT => true
+ ]);
- // the server sends the status
- $server_call->start_write_status(Grpc\STATUS_OK, $status_text, $server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_close);
- // the client gets CLIENT_METADATA_READ
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\CLIENT_METADATA_READ, $event->type);
+ $event = $this->server->requestCall();
+ $this->assertSame('dummy_method', $event->method);
+ $this->assertSame([], $event->metadata);
+ $server_call = $event->call;
- // the client gets FINISHED
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
- $status = $event->data;
+ $event = $server_call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => $status_text
+ ],
+ Grpc\OP_RECV_CLOSE_ON_SERVER => true
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_status);
+ $this->assertFalse($event->cancelled);
+
+ $event = $call->startBatch([
+ Grpc\OP_RECV_INITIAL_METADATA => true,
+ Grpc\OP_RECV_STATUS_ON_CLIENT => true
+ ]);
+
+ $this->assertSame([], $event->metadata);
+ $status = $event->status;
+ $this->assertSame([], $status->metadata);
$this->assertSame(Grpc\STATUS_OK, $status->code);
$this->assertSame($status_text, $status->details);
- // and the server gets FINISHED
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
- $status = $event->data;
-
unset($call);
unset($server_call);
}
public function testClientServerFullRequestResponse() {
- $deadline = Grpc\Timeval::inf_future();
+ $deadline = Grpc\Timeval::infFuture();
$req_text = 'client_server_full_request_response';
$reply_text = 'reply:client_server_full_request_response';
$status_text = 'status:client_server_full_response_text';
@@ -115,79 +102,52 @@ class EndToEndTest extends PHPUnit_Framework_TestCase{
$call = new Grpc\Call($this->channel,
'dummy_method',
$deadline);
- $tag = 1;
- $call->invoke($this->client_queue, $tag, $tag);
- $server_tag = 2;
+ $event = $call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
+ Grpc\OP_SEND_MESSAGE => $req_text
+ ]);
- // the client writes
- $call->start_write($req_text, $tag);
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\WRITE_ACCEPTED, $event->type);
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_close);
+ $this->assertTrue($event->send_message);
- // check that a server rpc new was received
- $this->server->start();
- $this->server->request_call($server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\SERVER_RPC_NEW, $event->type);
+ $event = $this->server->requestCall();
+ $this->assertSame('dummy_method', $event->method);
$server_call = $event->call;
- $this->assertNotNull($server_call);
- $server_call->server_accept($this->server_queue, $server_tag);
-
- $server_call->server_end_initial_metadata();
-
- // start the server read
- $server_call->start_read($server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\READ, $event->type);
- $this->assertSame($req_text, $event->data);
-
- // the server replies
- $server_call->start_write($reply_text, $server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\WRITE_ACCEPTED, $event->type);
-
- // the client reads the metadata
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\CLIENT_METADATA_READ, $event->type);
-
- // the client reads the reply
- $call->start_read($tag);
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\READ, $event->type);
- $this->assertSame($reply_text, $event->data);
-
- // the client sends writes done
- $call->writes_done($tag);
- $event = $this->client_queue->next($deadline);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
-
- // the server sends the status
- $server_call->start_write_status(GRPC\STATUS_OK, $status_text, $server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
-
- // the client gets FINISHED
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
- $status = $event->data;
+
+ $event = $server_call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_MESSAGE => $reply_text,
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => $status_text
+ ],
+ Grpc\OP_RECV_MESSAGE => true,
+ Grpc\OP_RECV_CLOSE_ON_SERVER => true,
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_status);
+ $this->assertTrue($event->send_message);
+ $this->assertFalse($event->cancelled);
+ $this->assertSame($req_text, $event->message);
+
+ $event = $call->startBatch([
+ Grpc\OP_RECV_INITIAL_METADATA => true,
+ Grpc\OP_RECV_MESSAGE => true,
+ Grpc\OP_RECV_STATUS_ON_CLIENT => true,
+ ]);
+
+ $this->assertSame([], $event->metadata);
+ $this->assertSame($reply_text, $event->message);
+ $status = $event->status;
+ $this->assertSame([], $status->metadata);
$this->assertSame(Grpc\STATUS_OK, $status->code);
$this->assertSame($status_text, $status->details);
- // and the server gets FINISHED
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
-
unset($call);
unset($server_call);
}
diff --git a/src/php/tests/unit_tests/SecureEndToEndTest.php b/src/php/tests/unit_tests/SecureEndToEndTest.php
index 896afeac49..0c18cd3e91 100755
--- a/src/php/tests/unit_tests/SecureEndToEndTest.php
+++ b/src/php/tests/unit_tests/SecureEndToEndTest.php
@@ -33,17 +33,16 @@
*/
class SecureEndToEndTest extends PHPUnit_Framework_TestCase{
public function setUp() {
- $this->client_queue = new Grpc\CompletionQueue();
- $this->server_queue = new Grpc\CompletionQueue();
$credentials = Grpc\Credentials::createSsl(
file_get_contents(dirname(__FILE__) . '/../data/ca.pem'));
$server_credentials = Grpc\ServerCredentials::createSsl(
null,
file_get_contents(dirname(__FILE__) . '/../data/server1.key'),
file_get_contents(dirname(__FILE__) . '/../data/server1.pem'));
- $this->server = new Grpc\Server($this->server_queue);
- $port = $this->server->add_secure_http2_port('0.0.0.0:0',
- $server_credentials);
+ $this->server = new Grpc\Server();
+ $port = $this->server->addSecureHttp2Port('0.0.0.0:0',
+ $server_credentials);
+ $this->server->start();
$this->channel = new Grpc\Channel(
'localhost:' . $port,
[
@@ -55,71 +54,59 @@ class SecureEndToEndTest extends PHPUnit_Framework_TestCase{
public function tearDown() {
unset($this->channel);
unset($this->server);
- unset($this->client_queue);
- unset($this->server_queue);
}
public function testSimpleRequestBody() {
- $this->server->start();
- $deadline = Grpc\Timeval::inf_future();
+ $deadline = Grpc\Timeval::infFuture();
$status_text = 'xyz';
$call = new Grpc\Call($this->channel,
'dummy_method',
$deadline);
- $tag = 1;
- $call->invoke($this->client_queue, $tag, $tag);
- $server_tag = 2;
-
- $call->writes_done($tag);
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
-
- // check that a server rpc new was received
- $this->server->request_call($server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\SERVER_RPC_NEW, $event->type);
+
+ $event = $call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_CLOSE_FROM_CLIENT => true
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_close);
+
+ $event = $this->server->requestCall();
+ $this->assertSame('dummy_method', $event->method);
+ $this->assertSame([], $event->metadata);
$server_call = $event->call;
- $this->assertNotNull($server_call);
- $server_call->server_accept($this->server_queue, $server_tag);
-
- $server_call->server_end_initial_metadata();
-
- // the server sends the status
- $server_call->start_write_status(Grpc\STATUS_OK, $status_text, $server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
-
- // the client gets CLIENT_METADATA_READ
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\CLIENT_METADATA_READ, $event->type);
-
- // the client gets FINISHED
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
- $status = $event->data;
+
+ $event = $server_call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => $status_text
+ ],
+ Grpc\OP_RECV_CLOSE_ON_SERVER => true
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_status);
+ $this->assertFalse($event->cancelled);
+
+ $event = $call->startBatch([
+ Grpc\OP_RECV_INITIAL_METADATA => true,
+ Grpc\OP_RECV_STATUS_ON_CLIENT => true
+ ]);
+
+ $this->assertSame([], $event->metadata);
+ $status = $event->status;
+ $this->assertSame([], $status->metadata);
$this->assertSame(Grpc\STATUS_OK, $status->code);
$this->assertSame($status_text, $status->details);
- // and the server gets FINISHED
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
- $status = $event->data;
-
unset($call);
unset($server_call);
}
public function testClientServerFullRequestResponse() {
- $this->server->start();
- $deadline = Grpc\Timeval::inf_future();
+ $deadline = Grpc\Timeval::infFuture();
$req_text = 'client_server_full_request_response';
$reply_text = 'reply:client_server_full_request_response';
$status_text = 'status:client_server_full_response_text';
@@ -127,78 +114,52 @@ class SecureEndToEndTest extends PHPUnit_Framework_TestCase{
$call = new Grpc\Call($this->channel,
'dummy_method',
$deadline);
- $tag = 1;
- $call->invoke($this->client_queue, $tag, $tag);
-
- $server_tag = 2;
-
- // the client writes
- $call->start_write($req_text, $tag);
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\WRITE_ACCEPTED, $event->type);
-
- // check that a server rpc new was received
- $this->server->request_call($server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\SERVER_RPC_NEW, $event->type);
+
+ $event = $call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
+ Grpc\OP_SEND_MESSAGE => $req_text
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_close);
+ $this->assertTrue($event->send_message);
+
+ $event = $this->server->requestCall();
+ $this->assertSame('dummy_method', $event->method);
$server_call = $event->call;
- $this->assertNotNull($server_call);
- $server_call->server_accept($this->server_queue, $server_tag);
-
- $server_call->server_end_initial_metadata();
-
- // start the server read
- $server_call->start_read($server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\READ, $event->type);
- $this->assertSame($req_text, $event->data);
-
- // the server replies
- $server_call->start_write($reply_text, $server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\WRITE_ACCEPTED, $event->type);
-
- // the client reads the metadata
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\CLIENT_METADATA_READ, $event->type);
-
- // the client reads the reply
- $call->start_read($tag);
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\READ, $event->type);
- $this->assertSame($reply_text, $event->data);
-
- // the client sends writes done
- $call->writes_done($tag);
- $event = $this->client_queue->next($deadline);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
-
- // the server sends the status
- $server_call->start_write_status(GRPC\STATUS_OK, $status_text, $server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
-
- // the client gets FINISHED
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
- $status = $event->data;
+
+ $event = $server_call->startBatch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_MESSAGE => $reply_text,
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => $status_text
+ ],
+ Grpc\OP_RECV_MESSAGE => true,
+ Grpc\OP_RECV_CLOSE_ON_SERVER => true,
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_status);
+ $this->assertTrue($event->send_message);
+ $this->assertFalse($event->cancelled);
+ $this->assertSame($req_text, $event->message);
+
+ $event = $call->startBatch([
+ Grpc\OP_RECV_INITIAL_METADATA => true,
+ Grpc\OP_RECV_MESSAGE => true,
+ Grpc\OP_RECV_STATUS_ON_CLIENT => true,
+ ]);
+
+ $this->assertSame([], $event->metadata);
+ $this->assertSame($reply_text, $event->message);
+ $status = $event->status;
+ $this->assertSame([], $status->metadata);
$this->assertSame(Grpc\STATUS_OK, $status->code);
$this->assertSame($status_text, $status->details);
- // and the server gets FINISHED
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
-
unset($call);
unset($server_call);
}
diff --git a/src/php/tests/unit_tests/TimevalTest.php b/src/php/tests/unit_tests/TimevalTest.php
index d20069afa1..a8bfcf0ac4 100755
--- a/src/php/tests/unit_tests/TimevalTest.php
+++ b/src/php/tests/unit_tests/TimevalTest.php
@@ -39,14 +39,14 @@ class TimevalTest extends PHPUnit_Framework_TestCase{
public function testPastIsLessThanZero() {
$zero = Grpc\Timeval::zero();
- $past = Grpc\Timeval::inf_past();
+ $past = Grpc\Timeval::infPast();
$this->assertLessThan(0, Grpc\Timeval::compare($past, $zero));
$this->assertGreaterThan(0, Grpc\Timeval::compare($zero, $past));
}
public function testFutureIsGreaterThanZero() {
$zero = Grpc\Timeval::zero();
- $future = Grpc\Timeval::inf_future();
+ $future = Grpc\Timeval::infFuture();
$this->assertLessThan(0, Grpc\Timeval::compare($zero, $future));
$this->assertGreaterThan(0, Grpc\Timeval::compare($future, $zero));
}
@@ -56,7 +56,7 @@ class TimevalTest extends PHPUnit_Framework_TestCase{
*/
public function testNowIsBetweenZeroAndFuture() {
$zero = Grpc\Timeval::zero();
- $future = Grpc\Timeval::inf_future();
+ $future = Grpc\Timeval::infFuture();
$now = Grpc\Timeval::now();
$this->assertLessThan(0, Grpc\Timeval::compare($zero, $now));
$this->assertLessThan(0, Grpc\Timeval::compare($now, $future));
diff --git a/src/python/README.md b/src/python/README.md
index c8057be38b..82bc776732 100644
--- a/src/python/README.md
+++ b/src/python/README.md
@@ -42,7 +42,14 @@ $ tools/run_tests/run_python.sh
Installing
-----------------------
-- [Install the gRPC core](https://github.com/grpc/grpc/blob/master/INSTALL)
+- Install the gRPC core
+ - [Debian package](https://github.com/grpc/grpc/releases)
+ ```
+ $ wget https://github.com/grpc/grpc/releases/download/release-0_5_0/libgrpc_0.5.0_amd64.deb
+ $ wget https://github.com/grpc/grpc/releases/download/release-0_5_0/libgrpc-dev_0.5.0_amd64.deb
+ $ sudo dpkg -i libgrpc_0.5.0_amd64.deb libgrpc-dev_0.5.0_amd64.deb
+ ```
+ - [From source](https://github.com/grpc/grpc/blob/master/INSTALL)
- Install gRPC Python's dependencies
```
@@ -53,3 +60,16 @@ $ pip install -r src/python/requirements.txt
```
$ pip install src/python/src
```
+
+Packaging to PyPI
+-----------------------
+
+- Install packaging dependencies
+```
+$ pip install setuptools twine
+```
+
+- Push to PyPI
+```
+$ ../../tools/distrib/python/submit.py
+```
diff --git a/src/python/interop/interop/_insecure_interop_test.py b/src/python/interop/interop/_insecure_interop_test.py
index e4ddff1a0b..42e7a4d5c4 100644
--- a/src/python/interop/interop/_insecure_interop_test.py
+++ b/src/python/interop/interop/_insecure_interop_test.py
@@ -42,11 +42,11 @@ class InsecureInteropTest(
unittest.TestCase):
def setUp(self):
- self.server = implementations.insecure_server(
+ self.server = implementations.server(
methods.SERVICE_NAME, methods.SERVER_METHODS, 0)
self.server.start()
port = self.server.port()
- self.stub = implementations.insecure_stub(
+ self.stub = implementations.stub(
methods.SERVICE_NAME, methods.CLIENT_METHODS, 'localhost', port)
def tearDown(self):
diff --git a/src/python/interop/interop/_interop_test_case.py b/src/python/interop/interop/_interop_test_case.py
index fec8f1915d..cd6a574e90 100644
--- a/src/python/interop/interop/_interop_test_case.py
+++ b/src/python/interop/interop/_interop_test_case.py
@@ -40,16 +40,16 @@ class InteropTestCase(object):
"""
def testEmptyUnary(self):
- methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub)
+ methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub, None)
def testLargeUnary(self):
- methods.TestCase.LARGE_UNARY.test_interoperability(self.stub)
+ methods.TestCase.LARGE_UNARY.test_interoperability(self.stub, None)
def testServerStreaming(self):
- methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub)
+ methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub, None)
def testClientStreaming(self):
- methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub)
+ methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub, None)
def testPingPong(self):
- methods.TestCase.PING_PONG.test_interoperability(self.stub)
+ methods.TestCase.PING_PONG.test_interoperability(self.stub, None)
diff --git a/src/python/interop/interop/_secure_interop_test.py b/src/python/interop/interop/_secure_interop_test.py
index 214212dca4..27e76315b6 100644
--- a/src/python/interop/interop/_secure_interop_test.py
+++ b/src/python/interop/interop/_secure_interop_test.py
@@ -45,14 +45,15 @@ class SecureInteropTest(
unittest.TestCase):
def setUp(self):
- self.server = implementations.secure_server(
+ self.server = implementations.server(
methods.SERVICE_NAME, methods.SERVER_METHODS, 0,
- resources.private_key(), resources.certificate_chain())
+ private_key=resources.private_key(),
+ certificate_chain=resources.certificate_chain())
self.server.start()
port = self.server.port()
- self.stub = implementations.secure_stub(
+ self.stub = implementations.stub(
methods.SERVICE_NAME, methods.CLIENT_METHODS, 'localhost', port,
- resources.test_root_certificates(), None, None,
+ secure=True, root_certificates=resources.test_root_certificates(),
server_host_override=_SERVER_HOST_OVERRIDE)
def tearDown(self):
diff --git a/src/python/interop/interop/client.py b/src/python/interop/interop/client.py
index fb7dfb5729..bae5e17460 100644
--- a/src/python/interop/interop/client.py
+++ b/src/python/interop/interop/client.py
@@ -30,6 +30,7 @@
"""The Python implementation of the GRPC interoperability test client."""
import argparse
+from oauth2client import client as oauth2client_client
from grpc.early_adopter import implementations
@@ -44,9 +45,6 @@ def _args():
parser.add_argument(
'--server_host', help='the host to which to connect', type=str)
parser.add_argument(
- '--server_host_override',
- help='the server host to which to claim to connect', type=str)
- parser.add_argument(
'--server_port', help='the port to which to connect', type=int)
parser.add_argument(
'--test_case', help='the test case to execute', type=str)
@@ -56,24 +54,40 @@ def _args():
parser.add_argument(
'--use_test_ca', help='replace platform root CAs with ca.pem',
action='store_true')
+ parser.add_argument(
+ '--server_host_override',
+ help='the server host to which to claim to connect', type=str)
+ parser.add_argument('--oauth_scope', help='scope for OAuth tokens', type=str)
+ parser.add_argument(
+ '--default_service_account',
+ help='email address of the default service account', type=str)
return parser.parse_args()
+def _oauth_access_token(args):
+ credentials = client.GoogleCredentials.get_application_default()
+ scoped_credentials = credentials.create_scoped([args.oauth_scope])
+ return scoped_credentials.get_access_token().access_token
def _stub(args):
+ if args.oauth_scope:
+ metadata_transformer = lambda x: [('Authorization', 'Bearer %s' % _oauth_access_token(args))]
+ else:
+ metadata_transformer = lambda x: []
if args.use_tls:
if args.use_test_ca:
root_certificates = resources.test_root_certificates()
else:
root_certificates = resources.prod_root_certificates()
- stub = implementations.secure_stub(
+ stub = implementations.stub(
methods.SERVICE_NAME, methods.CLIENT_METHODS, args.server_host,
- args.server_port, root_certificates, None, None,
+ args.server_port, metadata_transformer=metadata_transformer,
+ secure=True, root_certificates=root_certificates,
server_host_override=args.server_host_override)
else:
- stub = implementations.insecure_stub(
+ stub = implementations.stub(
methods.SERVICE_NAME, methods.CLIENT_METHODS, args.server_host,
- args.server_port)
+ args.server_port, secure=False)
return stub
@@ -89,7 +103,7 @@ def _test_interoperability():
args = _args()
stub = _stub(args)
test_case = _test_case_from_arg(args.test_case)
- test_case.test_interoperability(stub)
+ test_case.test_interoperability(stub, args)
if __name__ == '__main__':
diff --git a/src/python/interop/interop/empty_pb2.py b/src/python/interop/interop/empty_pb2.py
index 732a358a36..8c1ce2f13e 100644
--- a/src/python/interop/interop/empty_pb2.py
+++ b/src/python/interop/interop/empty_pb2.py
@@ -57,6 +57,7 @@ Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), d
_sym_db.RegisterMessage(Empty)
-from grpc.framework.face import demonstration as _face_testing
-from grpc.framework.face import interfaces as _face_interfaces
+import abc
+from grpc.early_adopter import implementations
+from grpc.framework.alpha import utilities
# @@protoc_insertion_point(module_scope)
diff --git a/src/python/interop/interop/messages_pb2.py b/src/python/interop/interop/messages_pb2.py
index d449a99140..0bf3d86a31 100644
--- a/src/python/interop/interop/messages_pb2.py
+++ b/src/python/interop/interop/messages_pb2.py
@@ -441,6 +441,7 @@ StreamingOutputCallResponse = _reflection.GeneratedProtocolMessageType('Streamin
_sym_db.RegisterMessage(StreamingOutputCallResponse)
-from grpc.framework.face import demonstration as _face_testing
-from grpc.framework.face import interfaces as _face_interfaces
+import abc
+from grpc.early_adopter import implementations
+from grpc.framework.alpha import utilities
# @@protoc_insertion_point(module_scope)
diff --git a/src/python/interop/interop/methods.py b/src/python/interop/interop/methods.py
index 79550a3789..c69771dff1 100644
--- a/src/python/interop/interop/methods.py
+++ b/src/python/interop/interop/methods.py
@@ -30,8 +30,12 @@
"""Implementations of interoperability test methods."""
import enum
+import json
+import os
import threading
+from oauth2client import client as oauth2client_client
+
from grpc.framework.alpha import utilities
from interop import empty_pb2
@@ -150,19 +154,12 @@ SERVER_METHODS = {
}
-def _empty_unary(stub):
- with stub:
- response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT)
- if not isinstance(response, empty_pb2.Empty):
- raise TypeError(
- 'response is of type "%s", not empty_pb2.Empty!', type(response))
-
-
-def _large_unary(stub):
+def _large_unary_common_behavior(stub, fill_username, fill_oauth_scope):
with stub:
request = messages_pb2.SimpleRequest(
response_type=messages_pb2.COMPRESSABLE, response_size=314159,
- payload=messages_pb2.Payload(body=b'\x00' * 271828))
+ payload=messages_pb2.Payload(body=b'\x00' * 271828),
+ fill_username=fill_username, fill_oauth_scope=fill_oauth_scope)
response_future = stub.UnaryCall.async(request, _TIMEOUT)
response = response_future.result()
if response.payload.type is not messages_pb2.COMPRESSABLE:
@@ -171,6 +168,19 @@ def _large_unary(stub):
if len(response.payload.body) != 314159:
raise ValueError(
'response body of incorrect size %d!' % len(response.payload.body))
+ return response
+
+
+def _empty_unary(stub):
+ with stub:
+ response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT)
+ if not isinstance(response, empty_pb2.Empty):
+ raise TypeError(
+ 'response is of type "%s", not empty_pb2.Empty!', type(response))
+
+
+def _large_unary(stub):
+ _large_unary_common_behavior(stub, False, False)
def _client_streaming(stub):
@@ -266,6 +276,28 @@ def _ping_pong(stub):
pipe.close()
+def _compute_engine_creds(stub, args):
+ response = _large_unary_common_behavior(stub, True, True)
+ if args.default_service_account != response.username:
+ raise ValueError(
+ 'expected username %s, got %s' % (args.default_service_account,
+ response.username))
+
+
+def _service_account_creds(stub, args):
+ json_key_filename = os.environ[
+ oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
+ wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
+ response = _large_unary_common_behavior(stub, True, True)
+ if wanted_email != response.username:
+ raise ValueError(
+ 'expected username %s, got %s' % (wanted_email, response.username))
+ if response.oauth_scope in args.oauth_scope:
+ raise ValueError(
+ 'expected to find oauth scope "%s" in received "%s"' %
+ (response.oauth_scope, args.oauth_scope))
+
+
@enum.unique
class TestCase(enum.Enum):
EMPTY_UNARY = 'empty_unary'
@@ -273,8 +305,10 @@ class TestCase(enum.Enum):
SERVER_STREAMING = 'server_streaming'
CLIENT_STREAMING = 'client_streaming'
PING_PONG = 'ping_pong'
+ COMPUTE_ENGINE_CREDS = 'compute_engine_creds'
+ SERVICE_ACCOUNT_CREDS = 'service_account_creds'
- def test_interoperability(self, stub):
+ def test_interoperability(self, stub, args):
if self is TestCase.EMPTY_UNARY:
_empty_unary(stub)
elif self is TestCase.LARGE_UNARY:
@@ -285,5 +319,9 @@ class TestCase(enum.Enum):
_client_streaming(stub)
elif self is TestCase.PING_PONG:
_ping_pong(stub)
+ elif self is TestCase.COMPUTE_ENGINE_CREDS:
+ _compute_engine_creds(stub, args)
+ elif self is TestCase.SERVICE_ACCOUNT_CREDS:
+ _service_account_creds(stub, args)
else:
raise NotImplementedError('Test case "%s" not implemented!' % self.name)
diff --git a/src/python/interop/interop/server.py b/src/python/interop/interop/server.py
index 5791203743..a67d412038 100644
--- a/src/python/interop/interop/server.py
+++ b/src/python/interop/interop/server.py
@@ -53,11 +53,11 @@ def serve():
if args.use_tls:
private_key = resources.private_key()
certificate_chain = resources.certificate_chain()
- server = implementations.secure_server(
- methods.SERVICE_NAME, methods.SERVER_METHODS, args.port, private_key,
- certificate_chain)
+ server = implementations.server(
+ methods.SERVICE_NAME, methods.SERVER_METHODS, args.port,
+ private_key=private_key, certificate_chain=certificate_chain)
else:
- server = implementations.insecure_server(
+ server = implementations.server(
methods.SERVICE_NAME, methods.SERVER_METHODS, args.port)
server.start()
diff --git a/src/python/interop/interop/test_pb2.py b/src/python/interop/interop/test_pb2.py
index e86094611b..71325d5a9f 100644
--- a/src/python/interop/interop/test_pb2.py
+++ b/src/python/interop/interop/test_pb2.py
@@ -29,121 +29,150 @@ _sym_db.RegisterFileDescriptor(DESCRIPTOR)
-from grpc.framework.face import demonstration as _face_testing
-from grpc.framework.face import interfaces as _face_interfaces
-class TestServiceService(object):
+import abc
+from grpc.early_adopter import implementations
+from grpc.framework.alpha import utilities
+class EarlyAdopterTestServiceServicer(object):
"""<fill me in later!>"""
- def __init__(self):
- pass
-class TestServiceServicer(object):
- """<fill me in later!>"""
- def EmptyCall(self, arg):
+ __metaclass__ = abc.ABCMeta
+ @abc.abstractmethod
+ def EmptyCall(self, request, context):
+ raise NotImplementedError()
+ @abc.abstractmethod
+ def UnaryCall(self, request, context):
raise NotImplementedError()
- def UnaryCall(self, arg):
+ @abc.abstractmethod
+ def StreamingOutputCall(self, request, context):
raise NotImplementedError()
- def StreamingOutputCall(self, arg):
+ @abc.abstractmethod
+ def StreamingInputCall(self, request_iterator, context):
raise NotImplementedError()
- def StreamingInputCall(self, arg):
+ @abc.abstractmethod
+ def FullDuplexCall(self, request_iterator, context):
raise NotImplementedError()
- def FullDuplexCall(self, arg):
+ @abc.abstractmethod
+ def HalfDuplexCall(self, request_iterator, context):
+ raise NotImplementedError()
+class EarlyAdopterTestServiceServer(object):
+ """<fill me in later!>"""
+ __metaclass__ = abc.ABCMeta
+ @abc.abstractmethod
+ def start(self):
raise NotImplementedError()
- def HalfDuplexCall(self, arg):
+ @abc.abstractmethod
+ def stop(self):
raise NotImplementedError()
-class TestServiceStub(object):
+class EarlyAdopterTestServiceStub(object):
"""<fill me in later!>"""
- def EmptyCall(self, arg):
+ __metaclass__ = abc.ABCMeta
+ @abc.abstractmethod
+ def EmptyCall(self, request):
raise NotImplementedError()
EmptyCall.async = None
- def UnaryCall(self, arg):
+ @abc.abstractmethod
+ def UnaryCall(self, request):
raise NotImplementedError()
UnaryCall.async = None
- def StreamingOutputCall(self, arg):
+ @abc.abstractmethod
+ def StreamingOutputCall(self, request):
raise NotImplementedError()
StreamingOutputCall.async = None
- def StreamingInputCall(self, arg):
+ @abc.abstractmethod
+ def StreamingInputCall(self, request_iterator):
raise NotImplementedError()
StreamingInputCall.async = None
- def FullDuplexCall(self, arg):
+ @abc.abstractmethod
+ def FullDuplexCall(self, request_iterator):
raise NotImplementedError()
FullDuplexCall.async = None
- def HalfDuplexCall(self, arg):
+ @abc.abstractmethod
+ def HalfDuplexCall(self, request_iterator):
raise NotImplementedError()
HalfDuplexCall.async = None
-class _TestServiceStub(TestServiceStub):
- def __init__(self, face_stub, default_timeout):
- self._face_stub = face_stub
- self._default_timeout = default_timeout
- stub_self = self
- class EmptyCall(object):
- def __call__(self, arg):
- return stub_self._face_stub.blocking_value_in_value_out("EmptyCall", arg, stub_self._default_timeout)
- def async(self, arg):
- return stub_self._face_stub.future_value_in_value_out("EmptyCall", arg, stub_self._default_timeout)
- self.EmptyCall = EmptyCall()
- class UnaryCall(object):
- def __call__(self, arg):
- return stub_self._face_stub.blocking_value_in_value_out("UnaryCall", arg, stub_self._default_timeout)
- def async(self, arg):
- return stub_self._face_stub.future_value_in_value_out("UnaryCall", arg, stub_self._default_timeout)
- self.UnaryCall = UnaryCall()
- class StreamingOutputCall(object):
- def __call__(self, arg):
- return stub_self._face_stub.inline_value_in_stream_out("StreamingOutputCall", arg, stub_self._default_timeout)
- def async(self, arg):
- return stub_self._face_stub.inline_value_in_stream_out("StreamingOutputCall", arg, stub_self._default_timeout)
- self.StreamingOutputCall = StreamingOutputCall()
- class StreamingInputCall(object):
- def __call__(self, arg):
- return stub_self._face_stub.blocking_stream_in_value_out("StreamingInputCall", arg, stub_self._default_timeout)
- def async(self, arg):
- return stub_self._face_stub.future_stream_in_value_out("StreamingInputCall", arg, stub_self._default_timeout)
- self.StreamingInputCall = StreamingInputCall()
- class FullDuplexCall(object):
- def __call__(self, arg):
- return stub_self._face_stub.inline_stream_in_stream_out("FullDuplexCall", arg, stub_self._default_timeout)
- def async(self, arg):
- return stub_self._face_stub.inline_stream_in_stream_out("FullDuplexCall", arg, stub_self._default_timeout)
- self.FullDuplexCall = FullDuplexCall()
- class HalfDuplexCall(object):
- def __call__(self, arg):
- return stub_self._face_stub.inline_stream_in_stream_out("HalfDuplexCall", arg, stub_self._default_timeout)
- def async(self, arg):
- return stub_self._face_stub.inline_stream_in_stream_out("HalfDuplexCall", arg, stub_self._default_timeout)
- self.HalfDuplexCall = HalfDuplexCall()
-def mock_TestService(servicer, default_timeout):
- value_in_value_out = {}
- value_in_stream_out = {}
- stream_in_value_out = {}
- stream_in_stream_out = {}
- class EmptyCall(_face_interfaces.InlineValueInValueOutMethod):
- def service(self, request, context):
- return servicer.EmptyCall(request)
- value_in_value_out['EmptyCall'] = EmptyCall()
- class UnaryCall(_face_interfaces.InlineValueInValueOutMethod):
- def service(self, request, context):
- return servicer.UnaryCall(request)
- value_in_value_out['UnaryCall'] = UnaryCall()
- class StreamingOutputCall(_face_interfaces.InlineValueInStreamOutMethod):
- def service(self, request, context):
- return servicer.StreamingOutputCall(request)
- value_in_stream_out['StreamingOutputCall'] = StreamingOutputCall()
- class StreamingInputCall(_face_interfaces.InlineStreamInValueOutMethod):
- def service(self, request, context):
- return servicer.StreamingInputCall(request)
- stream_in_value_out['StreamingInputCall'] = StreamingInputCall()
- class FullDuplexCall(_face_interfaces.InlineStreamInStreamOutMethod):
- def service(self, request, context):
- return servicer.FullDuplexCall(request)
- stream_in_stream_out['FullDuplexCall'] = FullDuplexCall()
- class HalfDuplexCall(_face_interfaces.InlineStreamInStreamOutMethod):
- def service(self, request, context):
- return servicer.HalfDuplexCall(request)
- stream_in_stream_out['HalfDuplexCall'] = HalfDuplexCall()
- face_linked_pair = _face_testing.server_and_stub(default_timeout,inline_value_in_value_out_methods=value_in_value_out,inline_value_in_stream_out_methods=value_in_stream_out,inline_stream_in_value_out_methods=stream_in_value_out,inline_stream_in_stream_out_methods=stream_in_stream_out)
- class LinkedPair(object):
- def __init__(self, server, stub):
- self.server = server
- self.stub = stub
- stub = _TestServiceStub(face_linked_pair.stub, default_timeout)
- return LinkedPair(None, stub)
+def early_adopter_create_TestService_server(servicer, port, private_key=None, certificate_chain=None):
+ import test.cpp.interop.empty_pb2
+ import test.cpp.interop.empty_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ method_service_descriptions = {
+ "EmptyCall": utilities.unary_unary_service_description(
+ servicer.EmptyCall,
+ test.cpp.interop.empty_pb2.Empty.FromString,
+ test.cpp.interop.empty_pb2.Empty.SerializeToString,
+ ),
+ "FullDuplexCall": utilities.stream_stream_service_description(
+ servicer.FullDuplexCall,
+ test.cpp.interop.messages_pb2.StreamingOutputCallRequest.FromString,
+ test.cpp.interop.messages_pb2.StreamingOutputCallResponse.SerializeToString,
+ ),
+ "HalfDuplexCall": utilities.stream_stream_service_description(
+ servicer.HalfDuplexCall,
+ test.cpp.interop.messages_pb2.StreamingOutputCallRequest.FromString,
+ test.cpp.interop.messages_pb2.StreamingOutputCallResponse.SerializeToString,
+ ),
+ "StreamingInputCall": utilities.stream_unary_service_description(
+ servicer.StreamingInputCall,
+ test.cpp.interop.messages_pb2.StreamingInputCallRequest.FromString,
+ test.cpp.interop.messages_pb2.StreamingInputCallResponse.SerializeToString,
+ ),
+ "StreamingOutputCall": utilities.unary_stream_service_description(
+ servicer.StreamingOutputCall,
+ test.cpp.interop.messages_pb2.StreamingOutputCallRequest.FromString,
+ test.cpp.interop.messages_pb2.StreamingOutputCallResponse.SerializeToString,
+ ),
+ "UnaryCall": utilities.unary_unary_service_description(
+ servicer.UnaryCall,
+ test.cpp.interop.messages_pb2.SimpleRequest.FromString,
+ test.cpp.interop.messages_pb2.SimpleResponse.SerializeToString,
+ ),
+ }
+ return implementations.server("grpc.testing.TestService", method_service_descriptions, port, private_key=private_key, certificate_chain=certificate_chain)
+def early_adopter_create_TestService_stub(host, port, metadata_transformer=None, secure=False, root_certificates=None, private_key=None, certificate_chain=None, server_host_override=None):
+ import test.cpp.interop.empty_pb2
+ import test.cpp.interop.empty_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ import test.cpp.interop.messages_pb2
+ method_invocation_descriptions = {
+ "EmptyCall": utilities.unary_unary_invocation_description(
+ test.cpp.interop.empty_pb2.Empty.SerializeToString,
+ test.cpp.interop.empty_pb2.Empty.FromString,
+ ),
+ "FullDuplexCall": utilities.stream_stream_invocation_description(
+ test.cpp.interop.messages_pb2.StreamingOutputCallRequest.SerializeToString,
+ test.cpp.interop.messages_pb2.StreamingOutputCallResponse.FromString,
+ ),
+ "HalfDuplexCall": utilities.stream_stream_invocation_description(
+ test.cpp.interop.messages_pb2.StreamingOutputCallRequest.SerializeToString,
+ test.cpp.interop.messages_pb2.StreamingOutputCallResponse.FromString,
+ ),
+ "StreamingInputCall": utilities.stream_unary_invocation_description(
+ test.cpp.interop.messages_pb2.StreamingInputCallRequest.SerializeToString,
+ test.cpp.interop.messages_pb2.StreamingInputCallResponse.FromString,
+ ),
+ "StreamingOutputCall": utilities.unary_stream_invocation_description(
+ test.cpp.interop.messages_pb2.StreamingOutputCallRequest.SerializeToString,
+ test.cpp.interop.messages_pb2.StreamingOutputCallResponse.FromString,
+ ),
+ "UnaryCall": utilities.unary_unary_invocation_description(
+ test.cpp.interop.messages_pb2.SimpleRequest.SerializeToString,
+ test.cpp.interop.messages_pb2.SimpleResponse.FromString,
+ ),
+ }
+ return implementations.stub("grpc.testing.TestService", method_invocation_descriptions, host, port, metadata_transformer=metadata_transformer, secure=secure, root_certificates=root_certificates, private_key=private_key, certificate_chain=certificate_chain, server_host_override=server_host_override)
# @@protoc_insertion_point(module_scope)
diff --git a/src/python/interop/setup.py b/src/python/interop/setup.py
index 6db5435090..502fcbedd8 100644
--- a/src/python/interop/setup.py
+++ b/src/python/interop/setup.py
@@ -29,7 +29,7 @@
"""A setup module for the GRPC Python interop testing package."""
-from distutils import core as _core
+import setuptools
_PACKAGES = (
'interop',
@@ -45,9 +45,13 @@ _PACKAGE_DATA = {
'credentials/server1.pem',]
}
-_INSTALL_REQUIRES = ['grpc-2015>=0.0.1']
+_INSTALL_REQUIRES = ['oauth2client>=1.4.7', 'grpcio>=0.4.0a4']
-_core.setup(
- name='interop', version='0.0.1', packages=_PACKAGES,
- package_dir=_PACKAGE_DIRECTORIES, package_data=_PACKAGE_DATA,
- install_requires=_INSTALL_REQUIRES)
+setuptools.setup(
+ name='interop',
+ version='0.0.1',
+ packages=_PACKAGES,
+ package_dir=_PACKAGE_DIRECTORIES,
+ package_data=_PACKAGE_DATA,
+ install_requires=_INSTALL_REQUIRES
+)
diff --git a/src/python/src/.gitignore b/src/python/src/.gitignore
new file mode 100644
index 0000000000..bc15a52cf1
--- /dev/null
+++ b/src/python/src/.gitignore
@@ -0,0 +1,3 @@
+MANIFEST
+grpcio.egg-info/
+dist/
diff --git a/src/python/src/MANIFEST.in b/src/python/src/MANIFEST.in
new file mode 100644
index 0000000000..6f32db0548
--- /dev/null
+++ b/src/python/src/MANIFEST.in
@@ -0,0 +1 @@
+graft grpc
diff --git a/src/python/src/README.rst b/src/python/src/README.rst
new file mode 100644
index 0000000000..bc1815febc
--- /dev/null
+++ b/src/python/src/README.rst
@@ -0,0 +1,27 @@
+gRPC Python
+===========
+
+Package for GRPC Python.
+
+Dependencies
+------------
+
+Ensure that you have installed GRPC core.
+
+On debian linux systems, install from our released deb package:
+
+::
+
+ $ wget https://github.com/grpc/grpc/releases/download/release-0_5_0/libgrpc_0.5.0_amd64.deb
+ $ wget https://github.com/grpc/grpc/releases/download/release-0_5_0/libgrpc-dev_0.5.0_amd64.deb
+ $ sudo dpkg -i libgrpc_0.5.0_amd64.deb libgrpc-dev_0.5.0_amd64.deb
+
+Otherwise, install from source:
+
+::
+
+ git clone https://github.com/grpc/grpc.git
+ cd grpc
+ ./configure
+ make && make install
+
diff --git a/src/python/src/grpc/_adapter/_call.c b/src/python/src/grpc/_adapter/_call.c
index d8806e5680..bf96c1a3fa 100644
--- a/src/python/src/grpc/_adapter/_call.c
+++ b/src/python/src/grpc/_adapter/_call.c
@@ -160,8 +160,22 @@ static const PyObject *pygrpc_call_accept(Call *self, PyObject *args) {
return result;
}
+static const PyObject *pygrpc_call_add_metadata(Call *self, PyObject *args) {
+ const char* key = NULL;
+ const char* value = NULL;
+ int value_length = 0;
+ grpc_metadata metadata;
+ if (!PyArg_ParseTuple(args, "ss#", &key, &value, &value_length)) {
+ return NULL;
+ }
+ metadata.key = key;
+ metadata.value = value;
+ metadata.value_length = value_length;
+ return pygrpc_translate_call_error(
+ grpc_call_add_metadata_old(self->c_call, &metadata, 0));
+}
+
static const PyObject *pygrpc_call_premetadata(Call *self) {
- /* TODO(nathaniel): Metadata support. */
return pygrpc_translate_call_error(
grpc_call_server_end_initial_metadata_old(self->c_call, 0));
}
@@ -236,6 +250,11 @@ static PyMethodDef methods[] = {
{"complete", (PyCFunction)pygrpc_call_complete, METH_O,
"Complete writes to this call."},
{"accept", (PyCFunction)pygrpc_call_accept, METH_VARARGS, "Accept an RPC."},
+ {"add_metadata", (PyCFunction)pygrpc_call_add_metadata, METH_VARARGS,
+ "Add metadata to the call. May not be called after invoke on the client "
+ "side. On the server side: when called before premetadata it provides "
+ "'leading' metadata, when called after premetadata but before status it "
+ "provides 'trailing metadata'; may not be called after status."},
{"premetadata", (PyCFunction)pygrpc_call_premetadata, METH_VARARGS,
"Indicate the end of leading metadata in the response."},
{"read", (PyCFunction)pygrpc_call_read, METH_O,
diff --git a/src/python/src/grpc/_adapter/_call.h b/src/python/src/grpc/_adapter/_call.h
index a936e23023..c04a2285f7 100644
--- a/src/python/src/grpc/_adapter/_call.h
+++ b/src/python/src/grpc/_adapter/_call.h
@@ -37,7 +37,10 @@
#include <Python.h>
#include <grpc/grpc.h>
-typedef struct { PyObject_HEAD grpc_call *c_call; } Call;
+typedef struct {
+ PyObject_HEAD
+ grpc_call *c_call;
+} Call;
PyTypeObject pygrpc_CallType;
diff --git a/src/python/src/grpc/_adapter/_channel.h b/src/python/src/grpc/_adapter/_channel.h
index 6241ccd02e..afc0f80359 100644
--- a/src/python/src/grpc/_adapter/_channel.h
+++ b/src/python/src/grpc/_adapter/_channel.h
@@ -37,7 +37,10 @@
#include <Python.h>
#include <grpc/grpc.h>
-typedef struct { PyObject_HEAD grpc_channel *c_channel; } Channel;
+typedef struct {
+ PyObject_HEAD
+ grpc_channel *c_channel;
+} Channel;
PyTypeObject pygrpc_ChannelType;
diff --git a/src/python/src/grpc/_adapter/_client_credentials.h b/src/python/src/grpc/_adapter/_client_credentials.h
index 664dc80d75..bb9f7f0c3a 100644
--- a/src/python/src/grpc/_adapter/_client_credentials.h
+++ b/src/python/src/grpc/_adapter/_client_credentials.h
@@ -38,7 +38,8 @@
#include <grpc/grpc_security.h>
typedef struct {
- PyObject_HEAD grpc_credentials *c_client_credentials;
+ PyObject_HEAD
+ grpc_credentials *c_client_credentials;
} ClientCredentials;
PyTypeObject pygrpc_ClientCredentialsType;
diff --git a/src/python/src/grpc/_adapter/_completion_queue.c b/src/python/src/grpc/_adapter/_completion_queue.c
index b56ca1926e..a639eff53e 100644
--- a/src/python/src/grpc/_adapter/_completion_queue.c
+++ b/src/python/src/grpc/_adapter/_completion_queue.c
@@ -115,35 +115,56 @@ static PyObject *pygrpc_status_code(grpc_status_code c_status_code) {
}
}
+static PyObject *pygrpc_metadata_collection_get(
+ grpc_metadata *metadata_elements, size_t count) {
+ PyObject *metadata = PyList_New(count);
+ size_t i;
+ for (i = 0; i < count; ++i) {
+ grpc_metadata elem = metadata_elements[i];
+ PyObject *key = PyString_FromString(elem.key);
+ PyObject *value = PyString_FromStringAndSize(elem.value, elem.value_length);
+ PyObject* kvp = PyTuple_Pack(2, key, value);
+ /* n.b. PyList_SetItem *steals* a reference to the set element. */
+ PyList_SetItem(metadata, i, kvp);
+ Py_DECREF(key);
+ Py_DECREF(value);
+ }
+ return metadata;
+}
+
static PyObject *pygrpc_stop_event_args(grpc_event *c_event) {
- return PyTuple_Pack(7, stop_event_kind, Py_None, Py_None, Py_None,
- Py_None, Py_None, Py_None);
+ return PyTuple_Pack(8, stop_event_kind, Py_None, Py_None, Py_None,
+ Py_None, Py_None, Py_None, Py_None);
}
static PyObject *pygrpc_write_event_args(grpc_event *c_event) {
PyObject *write_accepted =
c_event->data.write_accepted == GRPC_OP_OK ? Py_True : Py_False;
- return PyTuple_Pack(7, write_event_kind, (PyObject *)c_event->tag,
- write_accepted, Py_None, Py_None, Py_None, Py_None);
+ return PyTuple_Pack(8, write_event_kind, (PyObject *)c_event->tag,
+ write_accepted, Py_None, Py_None, Py_None, Py_None,
+ Py_None);
}
static PyObject *pygrpc_complete_event_args(grpc_event *c_event) {
PyObject *complete_accepted =
c_event->data.finish_accepted == GRPC_OP_OK ? Py_True : Py_False;
- return PyTuple_Pack(7, complete_event_kind, (PyObject *)c_event->tag,
- Py_None, complete_accepted, Py_None, Py_None, Py_None);
+ return PyTuple_Pack(8, complete_event_kind, (PyObject *)c_event->tag,
+ Py_None, complete_accepted, Py_None, Py_None, Py_None,
+ Py_None);
}
static PyObject *pygrpc_service_event_args(grpc_event *c_event) {
if (c_event->data.server_rpc_new.method == NULL) {
- return PyTuple_Pack(7, service_event_kind, c_event->tag,
- Py_None, Py_None, Py_None, Py_None, Py_None);
+ return PyTuple_Pack(
+ 8, service_event_kind, c_event->tag, Py_None, Py_None, Py_None, Py_None,
+ Py_None, Py_None);
} else {
PyObject *method = NULL;
PyObject *host = NULL;
PyObject *service_deadline = NULL;
Call *call = NULL;
PyObject *service_acceptance = NULL;
+ PyObject *metadata = NULL;
PyObject *event_args = NULL;
method = PyBytes_FromString(c_event->data.server_rpc_new.method);
@@ -173,11 +194,16 @@ static PyObject *pygrpc_service_event_args(grpc_event *c_event) {
goto error;
}
- event_args = PyTuple_Pack(7, service_event_kind,
+ metadata = pygrpc_metadata_collection_get(
+ c_event->data.server_rpc_new.metadata_elements,
+ c_event->data.server_rpc_new.metadata_count);
+ event_args = PyTuple_Pack(8, service_event_kind,
(PyObject *)c_event->tag, Py_None, Py_None,
- service_acceptance, Py_None, Py_None);
+ service_acceptance, Py_None, Py_None,
+ metadata);
Py_DECREF(service_acceptance);
+ Py_DECREF(metadata);
error:
Py_XDECREF(call);
Py_XDECREF(method);
@@ -190,8 +216,8 @@ error:
static PyObject *pygrpc_read_event_args(grpc_event *c_event) {
if (c_event->data.read == NULL) {
- return PyTuple_Pack(7, read_event_kind, (PyObject *)c_event->tag,
- Py_None, Py_None, Py_None, Py_None, Py_None);
+ return PyTuple_Pack(8, read_event_kind, (PyObject *)c_event->tag,
+ Py_None, Py_None, Py_None, Py_None, Py_None, Py_None);
} else {
size_t length;
size_t offset;
@@ -216,17 +242,23 @@ static PyObject *pygrpc_read_event_args(grpc_event *c_event) {
if (bytes == NULL) {
return NULL;
}
- event_args = PyTuple_Pack(7, read_event_kind, (PyObject *)c_event->tag,
- Py_None, Py_None, Py_None, bytes, Py_None);
+ event_args = PyTuple_Pack(8, read_event_kind, (PyObject *)c_event->tag,
+ Py_None, Py_None, Py_None, bytes, Py_None,
+ Py_None);
Py_DECREF(bytes);
return event_args;
}
}
static PyObject *pygrpc_metadata_event_args(grpc_event *c_event) {
- /* TODO(nathaniel): Actual transmission of metadata. */
- return PyTuple_Pack(7, metadata_event_kind, (PyObject *)c_event->tag,
- Py_None, Py_None, Py_None, Py_None, Py_None);
+ PyObject *metadata = pygrpc_metadata_collection_get(
+ c_event->data.client_metadata_read.elements,
+ c_event->data.client_metadata_read.count);
+ PyObject* result = PyTuple_Pack(
+ 8, metadata_event_kind, (PyObject *)c_event->tag, Py_None, Py_None,
+ Py_None, Py_None, Py_None, metadata);
+ Py_DECREF(metadata);
+ return result;
}
static PyObject *pygrpc_finished_event_args(grpc_event *c_event) {
@@ -234,6 +266,7 @@ static PyObject *pygrpc_finished_event_args(grpc_event *c_event) {
PyObject *details;
PyObject *status;
PyObject *event_args;
+ PyObject *metadata;
code = pygrpc_status_code(c_event->data.finished.status);
if (code == NULL) {
@@ -253,9 +286,14 @@ static PyObject *pygrpc_finished_event_args(grpc_event *c_event) {
if (status == NULL) {
return NULL;
}
- event_args = PyTuple_Pack(7, finish_event_kind, (PyObject *)c_event->tag,
- Py_None, Py_None, Py_None, Py_None, status);
+ metadata = pygrpc_metadata_collection_get(
+ c_event->data.finished.metadata_elements,
+ c_event->data.finished.metadata_count);
+ event_args = PyTuple_Pack(8, finish_event_kind, (PyObject *)c_event->tag,
+ Py_None, Py_None, Py_None, Py_None, status,
+ metadata);
Py_DECREF(status);
+ Py_DECREF(metadata);
return event_args;
}
diff --git a/src/python/src/grpc/_adapter/_completion_queue.h b/src/python/src/grpc/_adapter/_completion_queue.h
index 8e5ee9f406..9b377d15d9 100644
--- a/src/python/src/grpc/_adapter/_completion_queue.h
+++ b/src/python/src/grpc/_adapter/_completion_queue.h
@@ -38,7 +38,8 @@
#include <grpc/grpc.h>
typedef struct {
- PyObject_HEAD grpc_completion_queue *c_completion_queue;
+ PyObject_HEAD
+ grpc_completion_queue *c_completion_queue;
} CompletionQueue;
PyTypeObject pygrpc_CompletionQueueType;
diff --git a/src/python/src/grpc/_adapter/_datatypes.py b/src/python/src/grpc/_adapter/_datatypes.py
index e271ec83b9..3b22784243 100644
--- a/src/python/src/grpc/_adapter/_datatypes.py
+++ b/src/python/src/grpc/_adapter/_datatypes.py
@@ -70,7 +70,7 @@ class Event(
collections.namedtuple(
'Event',
['kind', 'tag', 'write_accepted', 'complete_accepted',
- 'service_acceptance', 'bytes', 'status'])):
+ 'service_acceptance', 'bytes', 'status', 'metadata'])):
"""Describes an event emitted from a completion queue."""
@enum.unique
diff --git a/src/python/src/grpc/_adapter/_links_test.py b/src/python/src/grpc/_adapter/_links_test.py
index cfdcc2c4bc..4987be389a 100644
--- a/src/python/src/grpc/_adapter/_links_test.py
+++ b/src/python/src/grpc/_adapter/_links_test.py
@@ -43,6 +43,14 @@ _IDENTITY = lambda x: x
_TIMEOUT = 2
+# TODO(nathaniel): End-to-end metadata testing.
+def _transform_metadata(unused_metadata):
+ return (
+ ('one unused key', 'one unused value'),
+ ('another unused key', 'another unused value'),
+)
+
+
class RoundTripTest(unittest.TestCase):
def setUp(self):
@@ -76,7 +84,8 @@ class RoundTripTest(unittest.TestCase):
rear_link = rear.RearLink(
'localhost', port, self.rear_link_pool, {test_method: None},
- {test_method: None}, False, None, None, None)
+ {test_method: None}, False, None, None, None,
+ metadata_transformer=_transform_metadata)
rear_link.join_fore_link(test_fore_link)
test_fore_link.join_rear_link(rear_link)
rear_link.start()
diff --git a/src/python/src/grpc/_adapter/_low_test.py b/src/python/src/grpc/_adapter/_low_test.py
index b04ac1c950..e88b70969c 100644
--- a/src/python/src/grpc/_adapter/_low_test.py
+++ b/src/python/src/grpc/_adapter/_low_test.py
@@ -115,6 +115,18 @@ class EchoTest(unittest.TestCase):
def _perform_echo_test(self, test_data):
method = 'test method'
details = 'test details'
+ server_leading_metadata_key = 'my_server_leading_key'
+ server_leading_metadata_value = 'my_server_leading_value'
+ server_trailing_metadata_key = 'my_server_trailing_key'
+ server_trailing_metadata_value = 'my_server_trailing_value'
+ client_metadata_key = 'my_client_key'
+ client_metadata_value = 'my_client_value'
+ server_leading_binary_metadata_key = 'my_server_leading_key-bin'
+ server_leading_binary_metadata_value = b'\0'*2047
+ server_trailing_binary_metadata_key = 'my_server_trailing_key-bin'
+ server_trailing_binary_metadata_value = b'\0'*2047
+ client_binary_metadata_key = 'my_client_key-bin'
+ client_binary_metadata_value = b'\0'*2047
deadline = _FUTURE
metadata_tag = object()
finish_tag = object()
@@ -128,6 +140,9 @@ class EchoTest(unittest.TestCase):
client_data = []
client_call = _low.Call(self.channel, method, self.host, deadline)
+ client_call.add_metadata(client_metadata_key, client_metadata_value)
+ client_call.add_metadata(client_binary_metadata_key,
+ client_binary_metadata_value)
client_call.invoke(self.client_completion_queue, metadata_tag, finish_tag)
@@ -139,15 +154,31 @@ class EchoTest(unittest.TestCase):
self.assertEqual(method, service_accepted.service_acceptance.method)
self.assertEqual(self.host, service_accepted.service_acceptance.host)
self.assertIsNotNone(service_accepted.service_acceptance.call)
+ metadata = dict(service_accepted.metadata)
+ self.assertIn(client_metadata_key, metadata)
+ self.assertEqual(client_metadata_value, metadata[client_metadata_key])
+ self.assertIn(client_binary_metadata_key, metadata)
+ self.assertEqual(client_binary_metadata_value,
+ metadata[client_binary_metadata_key])
server_call = service_accepted.service_acceptance.call
server_call.accept(self.server_completion_queue, finish_tag)
+ server_call.add_metadata(server_leading_metadata_key,
+ server_leading_metadata_value)
+ server_call.add_metadata(server_leading_binary_metadata_key,
+ server_leading_binary_metadata_value)
server_call.premetadata()
metadata_accepted = self.client_completion_queue.get(_FUTURE)
self.assertIsNotNone(metadata_accepted)
self.assertEqual(_low.Event.Kind.METADATA_ACCEPTED, metadata_accepted.kind)
self.assertEqual(metadata_tag, metadata_accepted.tag)
- # TODO(nathaniel): Test transmission and reception of metadata.
+ metadata = dict(metadata_accepted.metadata)
+ self.assertIn(server_leading_metadata_key, metadata)
+ self.assertEqual(server_leading_metadata_value,
+ metadata[server_leading_metadata_key])
+ self.assertIn(server_leading_binary_metadata_key, metadata)
+ self.assertEqual(server_leading_binary_metadata_value,
+ metadata[server_leading_binary_metadata_key])
for datum in test_data:
client_call.write(datum, write_tag)
@@ -194,6 +225,11 @@ class EchoTest(unittest.TestCase):
self.assertEqual(read_tag, read_accepted.tag)
self.assertIsNone(read_accepted.bytes)
+ server_call.add_metadata(server_trailing_metadata_key,
+ server_trailing_metadata_value)
+ server_call.add_metadata(server_trailing_binary_metadata_key,
+ server_trailing_binary_metadata_value)
+
server_call.status(_low.Status(_low.Code.OK, details), status_tag)
server_terminal_event_one = self.server_completion_queue.get(_FUTURE)
server_terminal_event_two = self.server_completion_queue.get(_FUTURE)
@@ -229,6 +265,13 @@ class EchoTest(unittest.TestCase):
self.assertEqual(_low.Event.Kind.FINISH, finish_accepted.kind)
self.assertEqual(finish_tag, finish_accepted.tag)
self.assertEqual(_low.Status(_low.Code.OK, details), finish_accepted.status)
+ metadata = dict(finish_accepted.metadata)
+ self.assertIn(server_trailing_metadata_key, metadata)
+ self.assertEqual(server_trailing_metadata_value,
+ metadata[server_trailing_metadata_key])
+ self.assertIn(server_trailing_binary_metadata_key, metadata)
+ self.assertEqual(server_trailing_binary_metadata_value,
+ metadata[server_trailing_binary_metadata_key])
server_timeout_none_event = self.server_completion_queue.get(0)
self.assertIsNone(server_timeout_none_event)
diff --git a/src/python/src/grpc/_adapter/_server.h b/src/python/src/grpc/_adapter/_server.h
index 0c517e3715..4836bb638c 100644
--- a/src/python/src/grpc/_adapter/_server.h
+++ b/src/python/src/grpc/_adapter/_server.h
@@ -37,7 +37,10 @@
#include <Python.h>
#include <grpc/grpc.h>
-typedef struct { PyObject_HEAD grpc_server *c_server; } Server;
+typedef struct {
+ PyObject_HEAD
+ grpc_server *c_server;
+} Server;
int pygrpc_add_server(PyObject *module);
diff --git a/src/python/src/grpc/_adapter/_server_credentials.h b/src/python/src/grpc/_adapter/_server_credentials.h
index 2e56efdcd9..6090404bd9 100644
--- a/src/python/src/grpc/_adapter/_server_credentials.h
+++ b/src/python/src/grpc/_adapter/_server_credentials.h
@@ -38,7 +38,8 @@
#include <grpc/grpc_security.h>
typedef struct {
- PyObject_HEAD grpc_server_credentials *c_server_credentials;
+ PyObject_HEAD
+ grpc_server_credentials *c_server_credentials;
} ServerCredentials;
PyTypeObject pygrpc_ServerCredentialsType;
diff --git a/src/python/src/grpc/_adapter/rear.py b/src/python/src/grpc/_adapter/rear.py
index f19321c426..2b93aa6331 100644
--- a/src/python/src/grpc/_adapter/rear.py
+++ b/src/python/src/grpc/_adapter/rear.py
@@ -93,7 +93,7 @@ class RearLink(base_interfaces.RearLink, activated.Activated):
def __init__(
self, host, port, pool, request_serializers, response_deserializers,
secure, root_certificates, private_key, certificate_chain,
- server_host_override=None):
+ metadata_transformer=None, server_host_override=None):
"""Constructor.
Args:
@@ -111,6 +111,9 @@ class RearLink(base_interfaces.RearLink, activated.Activated):
key should be used.
certificate_chain: The PEM-encoded certificate chain to use or None if
no certificate chain should be used.
+ metadata_transformer: A function that given a metadata object produces
+ another metadata to be used in the underlying communication on the
+ wire.
server_host_override: (For testing only) the target name used for SSL
host name checking.
"""
@@ -134,6 +137,7 @@ class RearLink(base_interfaces.RearLink, activated.Activated):
self._root_certificates = root_certificates
self._private_key = private_key
self._certificate_chain = certificate_chain
+ self._metadata_transformer = metadata_transformer
self._server_host_override = server_host_override
def _on_write_event(self, operation_id, event, rpc_state):
@@ -243,6 +247,10 @@ class RearLink(base_interfaces.RearLink, activated.Activated):
"""
request_serializer = self._request_serializers[name]
call = _low.Call(self._channel, name, self._host, time.time() + timeout)
+ if self._metadata_transformer is not None:
+ metadata = self._metadata_transformer([])
+ for metadata_key, metadata_value in metadata:
+ call.add_metadata(metadata_key, metadata_value)
call.invoke(self._completion_queue, operation_id, operation_id)
outstanding = set(_INVOCATION_EVENT_KINDS)
diff --git a/src/python/src/grpc/early_adopter/implementations.py b/src/python/src/grpc/early_adopter/implementations.py
index cc0b8ec9e8..35456d38c6 100644
--- a/src/python/src/grpc/early_adopter/implementations.py
+++ b/src/python/src/grpc/early_adopter/implementations.py
@@ -114,7 +114,7 @@ class _Stub(interfaces.Stub):
def __init__(
self, breakdown, host, port, secure, root_certificates, private_key,
- certificate_chain, server_host_override=None):
+ certificate_chain, metadata_transformer=None, server_host_override=None):
self._lock = threading.Lock()
self._breakdown = breakdown
self._host = host
@@ -123,6 +123,7 @@ class _Stub(interfaces.Stub):
self._root_certificates = root_certificates
self._private_key = private_key
self._certificate_chain = certificate_chain
+ self._metadata_transformer = metadata_transformer
self._server_host_override = server_host_override
self._pool = None
@@ -141,6 +142,7 @@ class _Stub(interfaces.Stub):
self._breakdown.request_serializers,
self._breakdown.response_deserializers, self._secure,
self._root_certificates, self._private_key, self._certificate_chain,
+ metadata_transformer=self._metadata_transformer,
server_host_override=self._server_host_override)
self._front.join_rear_link(self._rear_link)
self._rear_link.join_fore_link(self._front)
@@ -188,43 +190,11 @@ class _Stub(interfaces.Stub):
raise AttributeError(attr)
-def _build_stub(
- service_name, methods, host, port, secure, root_certificates, private_key,
- certificate_chain, server_host_override=None):
- breakdown = _face_utilities.break_down_invocation(service_name, methods)
- return _Stub(
- breakdown, host, port, secure, root_certificates, private_key,
- certificate_chain, server_host_override=server_host_override)
-
-
-def _build_server(service_name, methods, port, private_key, certificate_chain):
- breakdown = _face_utilities.break_down_service(service_name, methods)
- return _Server(breakdown, port, private_key, certificate_chain)
-
-
-def insecure_stub(service_name, methods, host, port):
- """Constructs an insecure interfaces.Stub.
-
- Args:
- service_name: The package-qualified full name of the service.
- methods: A dictionary from RPC method name to
- interfaces.RpcMethodInvocationDescription describing the RPCs to be
- supported by the created stub. The RPC method names in the dictionary are
- not qualified by the service name or decorated in any other way.
- host: The host to which to connect for RPC service.
- port: The port to which to connect for RPC service.
-
- Returns:
- An interfaces.Stub affording RPC invocation.
- """
- return _build_stub(
- service_name, methods, host, port, False, None, None, None)
-
-
-def secure_stub(
- service_name, methods, host, port, root_certificates, private_key,
- certificate_chain, server_host_override=None):
- """Constructs an insecure interfaces.Stub.
+def stub(
+ service_name, methods, host, port, metadata_transformer=None, secure=False,
+ root_certificates=None, private_key=None, certificate_chain=None,
+ server_host_override=None):
+ """Constructs an interfaces.Stub.
Args:
service_name: The package-qualified full name of the service.
@@ -234,6 +204,10 @@ def secure_stub(
not qualified by the service name or decorated in any other way.
host: The host to which to connect for RPC service.
port: The port to which to connect for RPC service.
+ metadata_transformer: A callable that given a metadata object produces
+ another metadata object to be used in the underlying communication on the
+ wire.
+ secure: Whether or not to construct the stub with a secure connection.
root_certificates: The PEM-encoded root certificates or None to ask for
them to be retrieved from a default location.
private_key: The PEM-encoded private key to use or None if no private key
@@ -246,32 +220,15 @@ def secure_stub(
Returns:
An interfaces.Stub affording RPC invocation.
"""
- return _build_stub(
- service_name, methods, host, port, True, root_certificates, private_key,
+ breakdown = _face_utilities.break_down_invocation(service_name, methods)
+ return _Stub(
+ breakdown, host, port, secure, root_certificates, private_key,
certificate_chain, server_host_override=server_host_override)
-def insecure_server(service_name, methods, port):
- """Constructs an insecure interfaces.Server.
-
- Args:
- service_name: The package-qualified full name of the service.
- methods: A dictionary from RPC method name to
- interfaces.RpcMethodServiceDescription describing the RPCs to
- be serviced by the created server. The RPC method names in the dictionary
- are not qualified by the service name or decorated in any other way.
- port: The desired port on which to serve or zero to ask for a port to
- be automatically selected.
-
- Returns:
- An interfaces.Server that will run with no security and
- service unsecured raw requests.
- """
- return _build_server(service_name, methods, port, None, None)
-
-
-def secure_server(service_name, methods, port, private_key, certificate_chain):
- """Constructs a secure interfaces.Server.
+def server(
+ service_name, methods, port, private_key=None, certificate_chain=None):
+ """Constructs an interfaces.Server.
Args:
service_name: The package-qualified full name of the service.
@@ -281,11 +238,12 @@ def secure_server(service_name, methods, port, private_key, certificate_chain):
are not qualified by the service name or decorated in any other way.
port: The port on which to serve or zero to ask for a port to be
automatically selected.
- private_key: A pem-encoded private key.
- certificate_chain: A pem-encoded certificate chain.
+ private_key: A pem-encoded private key, or None for an insecure server.
+ certificate_chain: A pem-encoded certificate chain, or None for an insecure
+ server.
Returns:
An interfaces.Server that will serve secure traffic.
"""
- return _build_server(
- service_name, methods, port, private_key, certificate_chain)
+ breakdown = _face_utilities.break_down_service(service_name, methods)
+ return _Server(breakdown, port, private_key, certificate_chain)
diff --git a/src/python/src/grpc/early_adopter/implementations_test.py b/src/python/src/grpc/early_adopter/implementations_test.py
index ae4adad90f..32b974724c 100644
--- a/src/python/src/grpc/early_adopter/implementations_test.py
+++ b/src/python/src/grpc/early_adopter/implementations_test.py
@@ -106,11 +106,11 @@ _TIMEOUT = 3
class EarlyAdopterImplementationsTest(unittest.TestCase):
def setUp(self):
- self.server = implementations.insecure_server(
+ self.server = implementations.server(
SERVICE_NAME, _SERVICE_DESCRIPTIONS, 0)
self.server.start()
port = self.server.port()
- self.stub = implementations.insecure_stub(
+ self.stub = implementations.stub(
SERVICE_NAME, _INVOCATION_DESCRIPTIONS, 'localhost', port)
def tearDown(self):
diff --git a/src/python/src/setup.py b/src/python/src/setup.py
index bd70634b8f..32ac41e285 100644
--- a/src/python/src/setup.py
+++ b/src/python/src/setup.py
@@ -30,6 +30,8 @@
"""A setup module for the GRPC Python package."""
from distutils import core as _core
+import setuptools
+import sys
_EXTENSION_SOURCES = (
'grpc/_adapter/_c.c',
@@ -49,8 +51,9 @@ _EXTENSION_INCLUDE_DIRECTORIES = (
_EXTENSION_LIBRARIES = (
'grpc',
'gpr',
- 'rt',
)
+if not "darwin" in sys.platform:
+ _EXTENSION_LIBRARIES += ('rt',)
_EXTENSION_MODULE = _core.Extension(
'grpc._adapter._c', sources=list(_EXTENSION_SOURCES),
@@ -80,7 +83,15 @@ _PACKAGE_DIRECTORIES = {
'grpc.framework': 'grpc/framework',
}
-_core.setup(
- name='grpc-2015', version='0.4.0',
- ext_modules=[_EXTENSION_MODULE], packages=list(_PACKAGES),
- package_dir=_PACKAGE_DIRECTORIES)
+setuptools.setup(
+ name='grpcio',
+ version='0.5.0a0',
+ ext_modules=[_EXTENSION_MODULE],
+ packages=list(_PACKAGES),
+ package_dir=_PACKAGE_DIRECTORIES,
+ install_requires=[
+ 'enum34==1.0.4',
+ 'futures==2.2.0',
+ 'protobuf==3.0.0-alpha-1'
+ ]
+)
diff --git a/src/ruby/Rakefile b/src/ruby/Rakefile
index b27305d16c..afb354e922 100755
--- a/src/ruby/Rakefile
+++ b/src/ruby/Rakefile
@@ -2,14 +2,17 @@
require 'rake/extensiontask'
require 'rspec/core/rake_task'
require 'rubocop/rake_task'
+require 'bundler/gem_tasks'
-desc 'Run Rubocop to check for style violations'
+# Add rubocop style checking tasks
RuboCop::RakeTask.new
+# Add the extension compiler task
Rake::ExtensionTask.new 'grpc' do |ext|
ext.lib_dir = File.join('lib', 'grpc')
end
+# Define the test suites
SPEC_SUITES = [
{ id: :wrapper, title: 'wrapper layer', files: %w(spec/*.rb) },
{ id: :idiomatic, title: 'idiomatic layer', dir: %w(spec/generic),
@@ -19,36 +22,34 @@ SPEC_SUITES = [
{ id: :server, title: 'rpc server thread tests', dir: %w(spec/generic),
tag: 'server' }
]
+namespace :suite do
+ SPEC_SUITES.each do |suite|
+ desc "Run all specs in the #{suite[:title]} spec suite"
+ RSpec::Core::RakeTask.new(suite[:id]) do |t|
+ spec_files = []
+ suite[:files].each { |f| spec_files += Dir[f] } if suite[:files]
+
+ if suite[:dir]
+ suite[:dir].each { |f| spec_files += Dir["#{f}/**/*_spec.rb"] }
+ end
+ helper = 'spec/spec_helper.rb'
+ spec_files << helper unless spec_files.include?(helper)
-desc 'Run all RSpec tests'
-namespace :spec do
- namespace :suite do
- SPEC_SUITES.each do |suite|
- desc "Run all specs in #{suite[:title]} spec suite"
- RSpec::Core::RakeTask.new(suite[:id]) do |t|
- spec_files = []
- suite[:files].each { |f| spec_files += Dir[f] } if suite[:files]
-
- if suite[:dirs]
- suite[:dirs].each { |f| spec_files += Dir["#{f}/**/*_spec.rb"] }
- end
-
- t.pattern = spec_files
- t.rspec_opts = "--tag #{suite[:tag]}" if suite[:tag]
- if suite[:tags]
- t.rspec_opts = suite[:tags].map { |x| "--tag #{x}" }.join(' ')
- end
+ t.pattern = spec_files
+ t.rspec_opts = "--tag #{suite[:tag]}" if suite[:tag]
+ if suite[:tags]
+ t.rspec_opts = suite[:tags].map { |x| "--tag #{x}" }.join(' ')
end
end
end
end
-desc 'Compiles the extension then runs all the tests'
-task :all
+# Define dependencies between the suites.
+task 'suite:wrapper' => [:compile, :rubocop]
+task 'suite:idiomatic' => 'suite:wrapper'
+task 'suite:bidi' => 'suite:wrapper'
+task 'suite:server' => 'suite:wrapper'
+desc 'Compiles the gRPC extension then runs all the tests'
+task all: ['suite:idiomatic', 'suite:bidi', 'suite:server']
task default: :all
-task 'spec:suite:wrapper' => [:compile, :rubocop]
-task 'spec:suite:idiomatic' => 'spec:suite:wrapper'
-task 'spec:suite:bidi' => 'spec:suite:wrapper'
-task 'spec:suite:server' => 'spec:suite:wrapper'
-task all: ['spec:suite:idiomatic', 'spec:suite:bidi', 'spec:suite:server']
diff --git a/src/ruby/lib/grpc/generic/service.rb b/src/ruby/lib/grpc/generic/service.rb
index 6ea0831a2e..69076b4c6e 100644
--- a/src/ruby/lib/grpc/generic/service.rb
+++ b/src/ruby/lib/grpc/generic/service.rb
@@ -176,25 +176,26 @@ module GRPC
unmarshal = desc.unmarshal_proc(:output)
route = "/#{route_prefix}/#{name}"
if desc.request_response?
- define_method(mth_name) do |req, deadline = nil|
+ define_method(mth_name) do |req, deadline = nil, **kw|
logger.debug("calling #{@host}:#{route}")
- request_response(route, req, marshal, unmarshal, deadline)
+ request_response(route, req, marshal, unmarshal, deadline, **kw)
end
elsif desc.client_streamer?
- define_method(mth_name) do |reqs, deadline = nil|
+ define_method(mth_name) do |reqs, deadline = nil, **kw|
logger.debug("calling #{@host}:#{route}")
- client_streamer(route, reqs, marshal, unmarshal, deadline)
+ client_streamer(route, reqs, marshal, unmarshal, deadline, **kw)
end
elsif desc.server_streamer?
- define_method(mth_name) do |req, deadline = nil, &blk|
+ define_method(mth_name) do |req, deadline = nil, **kw, &blk|
logger.debug("calling #{@host}:#{route}")
- server_streamer(route, req, marshal, unmarshal, deadline,
+ server_streamer(route, req, marshal, unmarshal, deadline, **kw,
&blk)
end
else # is a bidi_stream
- define_method(mth_name) do |reqs, deadline = nil, &blk|
+ define_method(mth_name) do |reqs, deadline = nil, **kw, &blk|
logger.debug("calling #{@host}:#{route}")
- bidi_streamer(route, reqs, marshal, unmarshal, deadline, &blk)
+ bidi_streamer(route, reqs, marshal, unmarshal, deadline, **kw,
+ &blk)
end
end
end
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index 513a53724f..bfd0cbb393 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -29,5 +29,5 @@
# GRPC contains the General RPC module.
module GRPC
- VERSION = '0.5.0'
+ VERSION = '0.6.0'
end
diff --git a/src/ruby/spec/generic/active_call_spec.rb b/src/ruby/spec/generic/active_call_spec.rb
index 8914225b55..96e07cacb4 100644
--- a/src/ruby/spec/generic/active_call_spec.rb
+++ b/src/ruby/spec/generic/active_call_spec.rb
@@ -67,7 +67,7 @@ describe GRPC::ActiveCall do
end
describe '#multi_req_view' do
- xit 'exposes a fixed subset of the ActiveCall methods' do
+ it 'exposes a fixed subset of the ActiveCall methods' do
want = %w(cancelled, deadline, each_remote_read, metadata, shutdown)
v = @client_call.multi_req_view
want.each do |w|
@@ -77,7 +77,7 @@ describe GRPC::ActiveCall do
end
describe '#single_req_view' do
- xit 'exposes a fixed subset of the ActiveCall methods' do
+ it 'exposes a fixed subset of the ActiveCall methods' do
want = %w(cancelled, deadline, metadata, shutdown)
v = @client_call.single_req_view
want.each do |w|
diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb
index 73f2d37e30..0c98fc40d9 100644
--- a/src/ruby/spec/generic/client_stub_spec.rb
+++ b/src/ruby/spec/generic/client_stub_spec.rb
@@ -384,13 +384,7 @@ describe 'ClientStub' do
th.join
end
- # disabled because an unresolved wire-protocol implementation feature
- #
- # - servers should be able initiate messaging, however, as it stand
- # servers don't know if all the client metadata has been sent until
- # they receive a message from the client. Without receiving all the
- # metadata, the server does not accept the call, so this test hangs.
- xit 'supports a server-initiated ping pong', bidi: true do
+ it 'supports a server-initiated ping pong', bidi: true do
server_port = create_test_server
host = "localhost:#{server_port}"
th = run_bidi_streamer_echo_ping_pong(@sent_msgs, @pass, false)
diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb
index f3b89b5895..34e5cdcd04 100644
--- a/src/ruby/spec/generic/rpc_server_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_spec.rb
@@ -81,14 +81,17 @@ EchoStub = EchoService.rpc_stub_class
class SlowService
include GRPC::GenericService
rpc :an_rpc, EchoMsg, EchoMsg
+ attr_reader :received_md, :delay
def initialize(_default_var = 'ignored')
+ @delay = 0.25
+ @received_md = []
end
- def an_rpc(req, _call)
- delay = 0.25
- logger.info("starting a slow #{delay} rpc")
- sleep delay
+ def an_rpc(req, call)
+ logger.info("starting a slow #{@delay} rpc")
+ sleep @delay
+ @received_md << call.metadata unless call.metadata.nil?
req # send back the req as the response
end
end
@@ -354,6 +357,37 @@ describe GRPC::RpcServer do
t.join
end
+ it 'should receive metadata when a deadline is specified', server: true do
+ service = SlowService.new
+ @srv.handle(service)
+ t = Thread.new { @srv.run }
+ @srv.wait_till_running
+ req = EchoMsg.new
+ stub = SlowStub.new(@host, **@client_opts)
+ deadline = service.delay + 0.5 # wait for long enough
+ expect(stub.an_rpc(req, deadline, k1: 'v1', k2: 'v2')).to be_a(EchoMsg)
+ wanted_md = [{ 'k1' => 'v1', 'k2' => 'v2' }]
+ expect(service.received_md).to eq(wanted_md)
+ @srv.stop
+ t.join
+ end
+
+ it 'should not receive metadata if the client times out', server: true do
+ service = SlowService.new
+ @srv.handle(service)
+ t = Thread.new { @srv.run }
+ @srv.wait_till_running
+ req = EchoMsg.new
+ stub = SlowStub.new(@host, **@client_opts)
+ deadline = 0.1 # too short for SlowService to respond
+ blk = proc { stub.an_rpc(req, deadline, k1: 'v1', k2: 'v2') }
+ expect(&blk).to raise_error GRPC::BadStatus
+ wanted_md = []
+ expect(service.received_md).to eq(wanted_md)
+ @srv.stop
+ t.join
+ end
+
it 'should receive updated metadata', server: true do
service = EchoService.new
@srv.handle(service)
diff --git a/templates/BUILD.template b/templates/BUILD.template
new file mode 100644
index 0000000000..8303b9f8e9
--- /dev/null
+++ b/templates/BUILD.template
@@ -0,0 +1,110 @@
+# GRPC Bazel BUILD file.
+# This currently builds C and C++ code.
+
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+licenses(["notice"]) # 3-clause BSD
+
+package(default_visibility = ["//visibility:public"])
+
+<%!
+def get_deps(target_dict):
+ deps = []
+ if target_dict.get('secure', 'no') == 'yes':
+ deps = [
+ "//external:libssl",
+ ]
+ if target_dict.get('build', None) == 'protoc':
+ deps.append("//external:protobuf_compiler")
+ if target_dict['name'] == 'grpc++_unsecure' or target_dict['name'] == 'grpc++':
+ deps.append("//external:protobuf_clib")
+ for d in target_dict.get('deps', []):
+ if d.find('//') == 0 or d[0] == ':':
+ deps.append(d)
+ else:
+ deps.append(':%s' % (d))
+ return deps
+%>
+
+% for lib in libs:
+% if lib.build != "private":
+${cc_library(lib)}
+% endif
+% endfor
+
+% for tgt in targets:
+% if tgt.build == 'protoc':
+${cc_binary(tgt)}
+% endif
+% endfor
+
+<%def name="cc_library(lib)">
+cc_library(
+ name = "${lib.name}",
+ srcs = [
+% for hdr in lib.get("headers", []):
+ "${hdr}",
+% endfor
+% for src in lib.src:
+ "${src}",
+% endfor
+ ],
+ hdrs = [
+% for hdr in lib.get("public_headers", []):
+ "${hdr}",
+% endfor
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+% for dep in get_deps(lib):
+ "${dep}",
+% endfor
+ ],
+)
+</%def>
+
+<%def name="cc_binary(tgt)">
+cc_binary(
+ name = "${tgt.name}",
+ srcs = [
+% for src in tgt.src:
+ "${src}",
+% endfor
+ ],
+ deps = [
+% for dep in get_deps(tgt):
+ "${dep}",
+% endfor
+ ],
+)
+</%def>
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 36d11425df..2cfbfa36ec 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -35,17 +35,11 @@
proto_re = re.compile('(.*)\\.proto')
- def excluded(filename, exclude_res):
- for r in exclude_res:
- if r.match(filename):
- return True
- return False
-
def proto_to_cc(filename):
m = proto_re.match(filename)
if not m:
return filename
- return '$(GENDIR)/' + m.group(1) + '.pb.cc'
+ return '$(GENDIR)/' + m.group(1) + '.pb.cc $(GENDIR)/' + m.group(1) + '.grpc.pb.cc'
%>
@@ -111,6 +105,15 @@ CPPFLAGS_dbg = -O0
LDFLAGS_dbg =
DEFINES_dbg = _DEBUG DEBUG
+VALID_CONFIG_mutrace = 1
+CC_mutrace = $(DEFAULT_CC)
+CXX_mutrace = $(DEFAULT_CXX)
+LD_mutrace = $(DEFAULT_CC)
+LDXX_mutrace = $(DEFAULT_CXX)
+CPPFLAGS_mutrace = -O0
+LDFLAGS_mutrace = -rdynamic
+DEFINES_mutrace = _DEBUG DEBUG
+
VALID_CONFIG_valgrind = 1
REQUIRE_CUSTOM_LIBRARIES_valgrind = 1
CC_valgrind = $(DEFAULT_CC)
@@ -235,7 +238,6 @@ ifeq ($(HAS_CXX11),true)
CXXFLAGS += -std=c++11
else
CXXFLAGS += -std=c++0x
-DEFINES += GRPC_OLD_CXX
endif
CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter
LDFLAGS += -g
@@ -832,11 +834,17 @@ endif
% for p in protos:
ifeq ($(NO_PROTOC),true)
$(GENDIR)/${p}.pb.cc: protoc_dep_error
+$(GENDIR)/${p}.grpc.pb.cc: protoc_dep_error
else
$(GENDIR)/${p}.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
- $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+ $(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/${p}.grpc.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+ $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
endif
% endfor
@@ -918,10 +926,11 @@ ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/${lib.name}.$(SHARED_EXT) $(prefix)/lib/${lib.name}.$(SHARED_EXT)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}-imp.a $(prefix)/lib/lib${lib.name}-imp.a
else
-ifneq ($(SYSTEM),Darwin)
$(E) "[INSTALL] Installing lib${lib.name}.$(SHARED_EXT)"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.so.${settings.version.major}
$(Q) ln -sf lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.so
endif
endif
@@ -1158,7 +1167,7 @@ ${out_libbase}.$(SHARED_EXT): $(LIB${lib.name.upper()}_OBJS) ${lib_deps}
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
ifeq ($(SYSTEM),Darwin)
- $(Q) ${ld} $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o ${out_libbase}.$(SHARED_EXT) ${common}${libs}
+ $(Q) ${ld} $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name lib${lib.name}.$(SHARED_EXT) -dynamiclib -o ${out_libbase}.$(SHARED_EXT) ${common}${libs}
else
$(Q) ${ld} $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,lib${lib.name}.so.${settings.version.major} -o ${out_libbase}.$(SHARED_EXT) ${common}${libs}
$(Q) ln -sf lib${lib.name}.$(SHARED_EXT) ${out_libbase}.so.${settings.version.major}
diff --git a/templates/vsprojects/vs2010/Grpc.mak.template b/templates/vsprojects/vs2010/Grpc.mak.template
new file mode 100644
index 0000000000..8e1b33bba7
--- /dev/null
+++ b/templates/vsprojects/vs2010/Grpc.mak.template
@@ -0,0 +1,107 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+<%!
+ import re
+%>\
+<%def name="to_windows_path(path)">${path.replace('/','\\')}</%def>\
+<%
+ allowed_dependencies = set(['gpr', 'grpc', 'gpr_test_util', 'grpc_test_util'])
+ buildable_targets = [ target for target in targets if set(target.deps).issubset(allowed_dependencies) and all([src.endswith('.c') for src in target.src])]
+ test_targets = [ target for target in buildable_targets if target.name.endswith('_test') ]
+%>\
+# NMake file to build secondary gRPC targets on Windows.
+# Use grpc.sln to solution to build the gRPC libraries.
+
+OUT_DIR=test_bin
+
+CC=cl.exe
+LINK=link.exe
+
+INCLUDES=/I..\.. /I..\..\include /I..\..\third_party\zlib /I..\third_party /I..\..\third_party\openssl\inc32
+DEFINES=/D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /D _CRT_SECURE_NO_WARNINGS
+CFLAGS=/c $(INCLUDES) /nologo /Z7 /W3 /WX- /sdl $(DEFINES) /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze-
+LFLAGS=/DEBUG /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86
+
+OPENSSL_LIBS=..\..\third_party\openssl\out32\ssleay32.lib ..\..\third_party\openssl\out32\libeay32.lib
+WINSOCK_LIBS=ws2_32.lib
+ZLIB_LIBS=Debug\zlibwapi.lib
+LIBS=$(OPENSSL_LIBS) $(WINSOCK_LIBS) $(ZLIB_LIBS)
+
+gpr_test_util:
+ MSBuild.exe gpr_test_util.vcxproj /p:Configuration=Debug
+
+grpc_test_util:
+ MSBuild.exe grpc_test_util.vcxproj /p:Configuration=Debug
+
+$(OUT_DIR):
+ mkdir $(OUT_DIR)
+
+buildtests: \
+% for target in test_targets:
+${target.name}.exe \
+% endfor
+
+ echo All tests built.
+
+test: \
+% for target in test_targets:
+${target.name} \
+% endfor
+
+ echo All tests ran.
+
+test_gpr: \
+% for target in [ tgt for tgt in test_targets if tgt.name.startswith('gpr_')]:
+${target.name} \
+% endfor
+
+ echo All tests ran.
+
+% for target in buildable_targets:
+${target.name}.exe: grpc_test_util
+ echo Building ${target.name}
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ \
+%for source in target.src:
+..\..\${to_windows_path(source)} \
+%endfor
+
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\${target.name}.exe" \
+%for dep in target.deps:
+Debug\${dep}.lib \
+%endfor
+$(LIBS) \
+%for source in target.src:
+$(OUT_DIR)\${re.search('([^/]+)\.c$', source).group(1)}.obj \
+%endfor
+
+${target.name}: ${target.name}.exe
+ echo Running ${target.name}
+ $(OUT_DIR)\${target.name}.exe
+
+% endfor
diff --git a/templates/vsprojects/vs2013/gpr_shared.vcxproj.filters.template b/templates/vsprojects/vs2010/gpr.vcxproj.filters.template
index c8b2ce099e..c8b2ce099e 100644
--- a/templates/vsprojects/vs2013/gpr_shared.vcxproj.filters.template
+++ b/templates/vsprojects/vs2010/gpr.vcxproj.filters.template
diff --git a/templates/vsprojects/vs2010/gpr.vcxproj.template b/templates/vsprojects/vs2010/gpr.vcxproj.template
new file mode 100644
index 0000000000..c478aadcdd
--- /dev/null
+++ b/templates/vsprojects/vs2010/gpr.vcxproj.template
@@ -0,0 +1,2 @@
+<%namespace file="vcxproj_defs.include" import="gen_project"/>\
+${gen_project('gpr', libs, targets)}
diff --git a/templates/vsprojects/vs2010/gpr_test_util.vcxproj.template b/templates/vsprojects/vs2010/gpr_test_util.vcxproj.template
new file mode 100644
index 0000000000..1f1bc0a5fb
--- /dev/null
+++ b/templates/vsprojects/vs2010/gpr_test_util.vcxproj.template
@@ -0,0 +1,2 @@
+<%namespace file="vcxproj_defs.include" import="gen_project"/>\
+${gen_project('gpr_test_util', libs, targets)} \ No newline at end of file
diff --git a/templates/vsprojects/vs2010/grpc++.vcxproj.filters.template b/templates/vsprojects/vs2010/grpc++.vcxproj.filters.template
new file mode 100644
index 0000000000..d74cce8c78
--- /dev/null
+++ b/templates/vsprojects/vs2010/grpc++.vcxproj.filters.template
@@ -0,0 +1,2 @@
+<%namespace file="vcxproj.filters_defs.include" import="gen_filters"/>\
+${gen_filters('grpc++', libs, targets)}
diff --git a/templates/vsprojects/vs2010/grpc++.vcxproj.template b/templates/vsprojects/vs2010/grpc++.vcxproj.template
new file mode 100644
index 0000000000..93994bb392
--- /dev/null
+++ b/templates/vsprojects/vs2010/grpc++.vcxproj.template
@@ -0,0 +1,2 @@
+<%namespace file="vcxproj_defs.include" import="gen_project"/>\
+${gen_project('grpc++', libs, targets)} \ No newline at end of file
diff --git a/templates/vsprojects/vs2010/grpc.sln.template b/templates/vsprojects/vs2010/grpc.sln.template
new file mode 100644
index 0000000000..47aa03ca41
--- /dev/null
+++ b/templates/vsprojects/vs2010/grpc.sln.template
@@ -0,0 +1,59 @@
+## Template for Visual Studio solution
+## based on http://msdn.microsoft.com/en-us/library/bb165951(v=vs.90).aspx
+## NOTE: tabs in this file are needed by Visual Studio to correctly interpret
+## the file.
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual C++ Express 2010
+<%
+## Visual Studio uses GUIDs for project types
+## http://msdn.microsoft.com/en-us/library/hb23x61k%28v=vs.80%29.aspx
+cpp_proj_type = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
+%>\
+% for project in vsprojects:
+Project("${cpp_proj_type}") = "${project.name}", "${project.name}.vcxproj", "${project.vs_project_guid}"
+ % if project.get('deps', None):
+ ProjectSection(ProjectDependencies) = postProject
+ % for dep in project.get('deps', []):
+ ${vsproject_dict[dep].vs_project_guid} = ${vsproject_dict[dep].vs_project_guid}
+ % endfor
+ EndProjectSection
+ % endif
+EndProject
+% endfor
+Project("${cpp_proj_type}") = "grpc_csharp_ext_shared", "grpc_csharp_ext_shared.vcxproj", "{C26D04A8-37C6-44C7-B458-906C9FCE928C}"
+EndProject
+Project("${cpp_proj_type}") = "zlibvc", "third_party\zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+% for project in vsprojects:
+ ${project.vs_project_guid}.Debug|Win32.ActiveCfg = Debug|Win32
+ ${project.vs_project_guid}.Debug|Win32.Build.0 = Debug|Win32
+ ${project.vs_project_guid}.Release|Win32.ActiveCfg = Release|Win32
+ ${project.vs_project_guid}.Release|Win32.Build.0 = Release|Win32
+% endfor
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32
+ {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Debug|Win32.Build.0 = Debug|Win32
+ {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Release|Win32.ActiveCfg = Release|Win32
+ {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Release|Win32.Build.0 = Release|Win32
+ {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Debug|Win32.Build.0 = Debug|Win32
+ {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Release|Win32.ActiveCfg = Release|Win32
+ {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Release|Win32.Build.0 = Release|Win32
+ {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Debug|Win32.Build.0 = Debug|Win32
+ {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Release|Win32.ActiveCfg = Release|Win32
+ {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/templates/vsprojects/vs2013/grpc_shared.vcxproj.filters.template b/templates/vsprojects/vs2010/grpc.vcxproj.filters.template
index b8e91bd61c..b8e91bd61c 100644
--- a/templates/vsprojects/vs2013/grpc_shared.vcxproj.filters.template
+++ b/templates/vsprojects/vs2010/grpc.vcxproj.filters.template
diff --git a/templates/vsprojects/vs2010/grpc.vcxproj.template b/templates/vsprojects/vs2010/grpc.vcxproj.template
new file mode 100644
index 0000000000..3de6453f52
--- /dev/null
+++ b/templates/vsprojects/vs2010/grpc.vcxproj.template
@@ -0,0 +1,2 @@
+<%namespace file="vcxproj_defs.include" import="gen_project"/>\
+${gen_project('grpc', libs, targets)} \ No newline at end of file
diff --git a/templates/vsprojects/vs2010/grpc_csharp_ext.vcxproj.template b/templates/vsprojects/vs2010/grpc_csharp_ext.vcxproj.template
new file mode 100644
index 0000000000..84aa50209a
--- /dev/null
+++ b/templates/vsprojects/vs2010/grpc_csharp_ext.vcxproj.template
@@ -0,0 +1,2 @@
+<%namespace file="vcxproj_defs.include" import="gen_project"/>\
+${gen_project('grpc_csharp_ext', libs, targets)}
diff --git a/templates/vsprojects/vs2010/grpc_csharp_ext_shared.vcxproj.template b/templates/vsprojects/vs2010/grpc_csharp_ext_shared.vcxproj.template
new file mode 100644
index 0000000000..193a2cd13f
--- /dev/null
+++ b/templates/vsprojects/vs2010/grpc_csharp_ext_shared.vcxproj.template
@@ -0,0 +1,2 @@
+<%namespace file="vcxproj_defs.include" import="gen_project"/>\
+${gen_project('grpc_csharp_ext', libs, targets, configuration_type = 'DynamicLibrary', project_guid = '{C26D04A8-37C6-44C7-B458-906C9FCE928C}', additional_props = ['winsock', 'ssl'])}
diff --git a/templates/vsprojects/vs2010/grpc_test_util.vcxproj.template b/templates/vsprojects/vs2010/grpc_test_util.vcxproj.template
new file mode 100644
index 0000000000..72e625d9b9
--- /dev/null
+++ b/templates/vsprojects/vs2010/grpc_test_util.vcxproj.template
@@ -0,0 +1,2 @@
+<%namespace file="vcxproj_defs.include" import="gen_project"/>\
+${gen_project('grpc_test_util', libs, targets)} \ No newline at end of file
diff --git a/templates/vsprojects/vs2010/grpc_unsecure.vcxproj.filters.template b/templates/vsprojects/vs2010/grpc_unsecure.vcxproj.filters.template
new file mode 100644
index 0000000000..ef918922ef
--- /dev/null
+++ b/templates/vsprojects/vs2010/grpc_unsecure.vcxproj.filters.template
@@ -0,0 +1,2 @@
+<%namespace file="vcxproj.filters_defs.include" import="gen_filters"/>\
+${gen_filters('grpc_unsecure', libs, targets)}
diff --git a/templates/vsprojects/vs2010/grpc_unsecure.vcxproj.template b/templates/vsprojects/vs2010/grpc_unsecure.vcxproj.template
new file mode 100644
index 0000000000..4f62b85a85
--- /dev/null
+++ b/templates/vsprojects/vs2010/grpc_unsecure.vcxproj.template
@@ -0,0 +1,2 @@
+<%namespace file="vcxproj_defs.include" import="gen_project"/>\
+${gen_project('grpc_unsecure', libs, targets)} \ No newline at end of file
diff --git a/templates/vsprojects/vs2010/vcxproj.filters_defs.include b/templates/vsprojects/vs2010/vcxproj.filters_defs.include
new file mode 100644
index 0000000000..539ae932f1
--- /dev/null
+++ b/templates/vsprojects/vs2010/vcxproj.filters_defs.include
@@ -0,0 +1,64 @@
+<%!
+ import re
+ import hashlib
+
+ def calc_to_filter(path):
+ return '\\'.join(path.split('/')[:-1])
+%>\
+<%def name="to_windows_path(path)">${path.replace('/','\\')}</%def>\
+<%def name="to_filter(path)">${calc_to_filter(path)}</%def>\
+<%def name="filter_to_guid(proj, filter)">${re.sub('(........)(....)(....)(....)', r'\1-\2-\3-\4-', hashlib.md5(''.join([filter, proj])).hexdigest())}</%def>\
+<%def name="gen_filters(name, libs, targets)">\
+% for project in vsprojects:
+ % if project.name == name:
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ % if project.get('src',[]):
+ <ItemGroup>
+ % for src_name in project.src:
+ <ClCompile Include="..\..\${to_windows_path(src_name)}">
+ <Filter>${to_filter(src_name)}</Filter>
+ </ClCompile>
+ % endfor
+ </ItemGroup>
+ % endif
+ % if project.get('public_headers',[]):
+ <ItemGroup>
+ % for public_header in project.public_headers:
+ <ClInclude Include="..\..\${to_windows_path(public_header)}">
+ <Filter>${to_filter(public_header)}</Filter>
+ </ClInclude>
+ % endfor
+ </ItemGroup>
+ % endif
+ % if project.get('headers',[]):
+ <ItemGroup>
+ % for header in project.headers:
+ <ClInclude Include="..\..\${to_windows_path(header)}">
+ <Filter>${to_filter(header)}</Filter>
+ </ClInclude>
+ % endfor
+ </ItemGroup>
+ % endif
+<%
+ filters = set()
+ files = project.get('src', []) + project.get('public_headers', []) + project.get('headers', [])
+ for file in files:
+ filter = calc_to_filter(file)
+ paths = filter.split('\\')
+ for i in range(len(paths)):
+ filters.add('\\'.join(paths[:i + 1]))
+
+ filters = sorted(filters)
+%>
+ <ItemGroup>
+ % for filter in filters:
+ <Filter Include="${filter}">
+ <UniqueIdentifier>{${filter_to_guid(project.name, filter)}}</UniqueIdentifier>
+ </Filter>
+ % endfor
+ </ItemGroup>
+</Project>
+ % endif
+% endfor
+</%def>\ \ No newline at end of file
diff --git a/templates/vsprojects/vs2010/vcxproj_defs.include b/templates/vsprojects/vs2010/vcxproj_defs.include
new file mode 100644
index 0000000000..8fd78a34dc
--- /dev/null
+++ b/templates/vsprojects/vs2010/vcxproj_defs.include
@@ -0,0 +1,131 @@
+<%def name="to_windows_path(path)">${path.replace('/','\\')}</%def>\
+<%def name="get_subsystem(is_library)">${'Windows' if is_library else 'Console'}</%def>\
+<%def name="gen_project(name, libs, targets, configuration_type = 'StaticLibrary', project_guid = None, additional_props = [], depends_on_zlib = False)">\
+% for project in vsprojects:
+ % if project.name == name:
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>${project_guid if project_guid else project.vs_project_guid}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>${configuration_type}</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <IntDir>$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>${configuration_type}</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <IntDir>$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="global.props" />
+ % for prop in additional_props:
+ <Import Project="${prop}.props" />
+ % endfor
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="global.props" />
+ % for prop in additional_props:
+ <Import Project="${prop}.props" />
+ % endfor
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>${name}</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>${name}</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>${get_subsystem(project.is_library)}</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>${get_subsystem(project.is_library)}</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ % if project.get('public_headers',[]):
+ <ItemGroup>
+ % for public_header in project.public_headers:
+ <ClInclude Include="..\..\${to_windows_path(public_header)}" />
+ % endfor
+ </ItemGroup>
+ % endif
+ % if project.get('headers',[]):
+ <ItemGroup>
+ % for header in project.headers:
+ <ClInclude Include="..\..\${to_windows_path(header)}" />
+ % endfor
+ </ItemGroup>
+ % endif
+ % if project.get('src',[]):
+ <ItemGroup>
+ % for src_name in project.src:
+ <ClCompile Include="..\..\${to_windows_path(src_name)}">
+ </ClCompile>
+ % endfor
+ </ItemGroup>
+ % endif
+ % if project.get('deps',[]):
+ <ItemGroup>
+ % for dep in project.deps:
+ <ProjectReference Include="${dep}.vcxproj">
+ <Project>${vsproject_dict[dep].vs_project_guid}</Project>
+ </ProjectReference>
+ % endfor
+ % if depends_on_zlib:
+ <ProjectReference Include="third_party\zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ % endif
+ </ItemGroup>
+ % endif
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
+ % endif
+% endfor
+</%def>\ \ No newline at end of file
diff --git a/templates/vsprojects/vs2013/gpr_shared.vcxproj.template b/templates/vsprojects/vs2013/gpr_shared.vcxproj.template
deleted file mode 100644
index d1b1dd3c8b..0000000000
--- a/templates/vsprojects/vs2013/gpr_shared.vcxproj.template
+++ /dev/null
@@ -1,2 +0,0 @@
-<%namespace file="vcxproj_defs.include" import="gen_project"/>\
-${gen_project('gpr', libs, targets, configuration_type = 'DynamicLibrary', project_guid = '{3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}')}
diff --git a/templates/vsprojects/vs2013/grpc.sln.template b/templates/vsprojects/vs2013/grpc.sln.template
index d17f4a31aa..2b0f76b90d 100644
--- a/templates/vsprojects/vs2013/grpc.sln.template
+++ b/templates/vsprojects/vs2013/grpc.sln.template
@@ -23,10 +23,6 @@ Project("${cpp_proj_type}") = "${project.name}", "${project.name}.vcxproj", "${p
% endif
EndProject
% endfor
-Project("${cpp_proj_type}") = "gpr_shared", "gpr_shared.vcxproj", "{3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}"
-EndProject
-Project("${cpp_proj_type}") = "grpc_shared", "grpc_shared.vcxproj", "{F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}"
-EndProject
Project("${cpp_proj_type}") = "grpc_csharp_ext_shared", "grpc_csharp_ext_shared.vcxproj", "{C26D04A8-37C6-44C7-B458-906C9FCE928C}"
EndProject
Project("${cpp_proj_type}") = "zlibvc", "third_party\zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
diff --git a/templates/vsprojects/vs2013/grpc_shared.vcxproj.template b/templates/vsprojects/vs2013/grpc_shared.vcxproj.template
deleted file mode 100644
index 890189c28d..0000000000
--- a/templates/vsprojects/vs2013/grpc_shared.vcxproj.template
+++ /dev/null
@@ -1,2 +0,0 @@
-<%namespace file="vcxproj_defs.include" import="gen_project"/>\
-${gen_project('grpc', libs, targets, configuration_type = 'DynamicLibrary', project_guid = '{F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}', additional_props = ['ssl', 'winsock'], depends_on_zlib = True)}
diff --git a/test/compiler/python_plugin_test.py b/test/compiler/python_plugin_test.py
index 3d2f117b0d..ad3bebac30 100644
--- a/test/compiler/python_plugin_test.py
+++ b/test/compiler/python_plugin_test.py
@@ -177,7 +177,7 @@ def _CreateService(test_pb2, delay):
servicer = Servicer()
server = getattr(
- test_pb2, SERVER_FACTORY_IDENTIFIER)(servicer, 0, None, None)
+ test_pb2, SERVER_FACTORY_IDENTIFIER)(servicer, 0)
with server:
port = server.port()
stub = getattr(test_pb2, STUB_FACTORY_IDENTIFIER)('localhost', port)
diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c
index e15fa7fcd9..592dfd415f 100644
--- a/test/core/end2end/tests/cancel_after_invoke.c
+++ b/test/core/end2end/tests/cancel_after_invoke.c
@@ -51,10 +51,11 @@ static void *tag(gpr_intptr t) { return (void *)t; }
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
const char *test_name,
+ cancellation_mode mode,
grpc_channel_args *client_args,
grpc_channel_args *server_args) {
grpc_end2end_test_fixture f;
- gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
+ gpr_log(GPR_INFO, "%s/%s/%s", test_name, config.name, mode.name);
f = config.create_fixture(client_args, server_args);
config.init_client(&f, client_args);
config.init_server(&f, server_args);
@@ -109,7 +110,8 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
grpc_op ops[6];
grpc_op *op;
grpc_call *c;
- grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL);
+ grpc_end2end_test_fixture f =
+ begin_test(config, __FUNCTION__, mode, NULL, NULL);
gpr_timespec deadline = five_seconds_time();
cq_verifier *v_client = cq_verifier_create(f.client_cq);
grpc_metadata_array initial_metadata_recv;
diff --git a/test/core/end2end/tests/cancel_test_helpers.h b/test/core/end2end/tests/cancel_test_helpers.h
index f2581dc32f..0d680fcfe1 100644
--- a/test/core/end2end/tests/cancel_test_helpers.h
+++ b/test/core/end2end/tests/cancel_test_helpers.h
@@ -35,6 +35,7 @@
#define GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H
typedef struct {
+ const char *name;
grpc_call_error (*initiate_cancel)(grpc_call *call);
grpc_status_code expect_status;
const char *expect_details;
@@ -45,7 +46,9 @@ static grpc_call_error wait_for_deadline(grpc_call *call) {
}
static const cancellation_mode cancellation_modes[] = {
- {grpc_call_cancel, GRPC_STATUS_CANCELLED, ""},
- {wait_for_deadline, GRPC_STATUS_DEADLINE_EXCEEDED, "Deadline Exceeded"}, };
+ {"cancel", grpc_call_cancel, GRPC_STATUS_CANCELLED, ""},
+ {"deadline", wait_for_deadline, GRPC_STATUS_DEADLINE_EXCEEDED,
+ "Deadline Exceeded"},
+};
-#endif /* GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H */
+#endif /* GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H */
diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c
index 708444a287..1c02c4b2f8 100644
--- a/test/core/iomgr/tcp_server_posix_test.c
+++ b/test/core/iomgr/tcp_server_posix_test.c
@@ -61,14 +61,14 @@ static void on_connect(void *arg, grpc_endpoint *tcp) {
static void test_no_op(void) {
grpc_tcp_server *s = grpc_tcp_server_create();
- grpc_tcp_server_destroy(s);
+ grpc_tcp_server_destroy(s, NULL, NULL);
}
static void test_no_op_with_start(void) {
grpc_tcp_server *s = grpc_tcp_server_create();
LOG_TEST();
grpc_tcp_server_start(s, NULL, 0, on_connect, NULL);
- grpc_tcp_server_destroy(s);
+ grpc_tcp_server_destroy(s, NULL, NULL);
}
static void test_no_op_with_port(void) {
@@ -81,7 +81,7 @@ static void test_no_op_with_port(void) {
GPR_ASSERT(
grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr)));
- grpc_tcp_server_destroy(s);
+ grpc_tcp_server_destroy(s, NULL, NULL);
}
static void test_no_op_with_port_and_start(void) {
@@ -96,7 +96,7 @@ static void test_no_op_with_port_and_start(void) {
grpc_tcp_server_start(s, NULL, 0, on_connect, NULL);
- grpc_tcp_server_destroy(s);
+ grpc_tcp_server_destroy(s, NULL, NULL);
}
static void test_connect(int n) {
@@ -145,7 +145,7 @@ static void test_connect(int n) {
gpr_mu_unlock(&mu);
- grpc_tcp_server_destroy(s);
+ grpc_tcp_server_destroy(s, NULL, NULL);
}
int main(int argc, char **argv) {
diff --git a/test/core/support/thd_test.c b/test/core/support/thd_test.c
index c03a905d2a..bb3d54a262 100644
--- a/test/core/support/thd_test.c
+++ b/test/core/support/thd_test.c
@@ -60,12 +60,16 @@ static void thd_body(void *v) {
gpr_mu_unlock(&t->mu);
}
+static void thd_body_joinable(void *v) { }
+
/* Test that we can create a number of threads and wait for them. */
static void test(void) {
int i;
gpr_thd_id thd;
+ gpr_thd_id thds[1000];
struct test t;
int n = 1000;
+ gpr_thd_options options = gpr_thd_options_default();
gpr_mu_init(&t.mu);
gpr_cv_init(&t.done_cv);
t.n = n;
@@ -79,6 +83,13 @@ static void test(void) {
}
gpr_mu_unlock(&t.mu);
GPR_ASSERT(t.n == 0);
+ gpr_thd_options_set_joinable(&options);
+ for (i = 0; i < n; i++) {
+ GPR_ASSERT(gpr_thd_new(&thds[i], &thd_body_joinable, NULL, &options));
+ }
+ for (i = 0; i < n; i++) {
+ gpr_thd_join(thds[i]);
+ }
}
/* ------------------------------------------------- */
diff --git a/test/core/tsi/transport_security_test.c b/test/core/tsi/transport_security_test.c
index c5882af966..d591e43faa 100644
--- a/test/core/tsi/transport_security_test.c
+++ b/test/core/tsi/transport_security_test.c
@@ -39,10 +39,15 @@
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
+#include <openssl/crypto.h>
+
#include "src/core/support/string.h"
#include "src/core/tsi/ssl_transport_security.h"
#include "test/core/util/test_config.h"
+/* Currently points to 1.0.2a. */
+#define GRPC_MIN_OPENSSL_VERSION_NUMBER 0x1000201fL
+
typedef struct {
/* 1 if success, 0 if failure. */
int expected;
@@ -296,8 +301,13 @@ static void test_peer_matches_name(void) {
}
}
+static void test_openssl_version(void) {
+ GPR_ASSERT(OPENSSL_VERSION_NUMBER >= GRPC_MIN_OPENSSL_VERSION_NUMBER);
+}
+
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_peer_matches_name();
+ test_openssl_version();
return 0;
}
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c
index 36f13e1b51..7467c2f9ea 100644
--- a/test/core/util/port_posix.c
+++ b/test/core/util/port_posix.c
@@ -32,7 +32,8 @@
*/
#include <grpc/support/port_platform.h>
-#ifdef GPR_POSIX_SOCKET
+#include "test/core/util/test_config.h"
+#if defined(GPR_POSIX_SOCKET) && defined(GRPC_TEST_PICK_PORT)
#include "test/core/util/port.h"
@@ -125,7 +126,7 @@ int grpc_pick_unused_port(void) {
} else {
port = 0;
}
-
+
if (!is_port_available(&port, is_tcp)) {
continue;
}
@@ -155,4 +156,4 @@ int grpc_pick_unused_port_or_die(void) {
return port;
}
-#endif /* GPR_POSIX_SOCKET */
+#endif /* GPR_POSIX_SOCKET && GRPC_TEST_PICK_PORT */
diff --git a/test/core/util/test_config.h b/test/core/util/test_config.h
index 668a069f26..0b3c54373d 100644
--- a/test/core/util/test_config.h
+++ b/test/core/util/test_config.h
@@ -59,6 +59,10 @@ extern "C" {
gpr_time_add(gpr_now(), \
gpr_time_from_micros(GRPC_TEST_SLOWDOWN_FACTOR * 1e3 * (x)))
+#ifndef GRPC_TEST_CUSTOM_PICK_PORT
+#define GRPC_TEST_PICK_PORT
+#endif
+
void grpc_test_init(int argc, char **argv);
#ifdef __cplusplus
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 4c71831dec..dd294d9516 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -35,8 +35,8 @@
#include <memory>
#include "test/core/util/test_config.h"
-#include "test/cpp/util/echo_duplicate.pb.h"
-#include "test/cpp/util/echo.pb.h"
+#include "test/cpp/util/echo_duplicate.grpc.pb.h"
+#include "test/cpp/util/echo.grpc.pb.h"
#include "src/cpp/util/time.h"
#include <grpc++/async_unary_call.h>
#include <grpc++/channel_arguments.h>
@@ -532,15 +532,19 @@ TEST_F(AsyncEnd2endTest, MetadataRpc) {
send_request.set_message("Hello");
std::pair<grpc::string, grpc::string> meta1("key1", "val1");
std::pair<grpc::string, grpc::string> meta2(
- "key2-bin", {"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", 13});
+ "key2-bin",
+ grpc::string("\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc",
+ 13));
std::pair<grpc::string, grpc::string> meta3("key3", "val3");
std::pair<grpc::string, grpc::string> meta6(
"key4-bin",
- {"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", 14});
+ grpc::string("\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d",
+ 14));
std::pair<grpc::string, grpc::string> meta5("key5", "val5");
std::pair<grpc::string, grpc::string> meta4(
"key6-bin",
- {"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee", 15});
+ grpc::string("\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee",
+ 15));
cli_ctx.AddMetadata(meta1.first, meta1.second);
cli_ctx.AddMetadata(meta2.first, meta2.second);
@@ -595,6 +599,5 @@ int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
int result = RUN_ALL_TESTS();
grpc_shutdown();
- google::protobuf::ShutdownProtobufLibrary();
return result;
}
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 41c2669533..f96051cafa 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -35,8 +35,8 @@
#include <thread>
#include "test/core/util/test_config.h"
-#include "test/cpp/util/echo_duplicate.pb.h"
-#include "test/cpp/util/echo.pb.h"
+#include "test/cpp/util/echo_duplicate.grpc.pb.h"
+#include "test/cpp/util/echo.grpc.pb.h"
#include "src/cpp/util/time.h"
#include "src/cpp/server/thread_pool.h"
#include <grpc++/channel_arguments.h>
@@ -83,10 +83,30 @@ void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request,
class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
public:
+ TestServiceImpl() : signal_client_(false) {}
+
Status Echo(ServerContext* context, const EchoRequest* request,
EchoResponse* response) GRPC_OVERRIDE {
response->set_message(request->message());
MaybeEchoDeadline(context, request, response);
+ if (request->has_param() && request->param().client_cancel_after_us()) {
+ {
+ std::unique_lock<std::mutex> lock(mu_);
+ signal_client_ = true;
+ }
+ while (!context->IsCancelled()) {
+ std::this_thread::sleep_for(std::chrono::microseconds(
+ request->param().client_cancel_after_us()));
+ }
+ return Status::Cancelled;
+ } else if (request->has_param() &&
+ request->param().server_cancel_after_us()) {
+ std::this_thread::sleep_for(
+ std::chrono::microseconds(request->param().server_cancel_after_us()));
+ return Status::Cancelled;
+ } else {
+ EXPECT_FALSE(context->IsCancelled());
+ }
return Status::OK;
}
@@ -130,6 +150,15 @@ class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
}
return Status::OK;
}
+
+ bool signal_client() {
+ std::unique_lock<std::mutex> lock(mu_);
+ return signal_client_;
+ }
+
+ private:
+ bool signal_client_;
+ std::mutex mu_;
};
class TestServiceImplDupPkg
@@ -151,7 +180,8 @@ class End2endTest : public ::testing::Test {
server_address_ << "localhost:" << port;
// Setup server
ServerBuilder builder;
- builder.AddListeningPort(server_address_.str(), InsecureServerCredentials());
+ builder.AddListeningPort(server_address_.str(),
+ InsecureServerCredentials());
builder.RegisterService(&service_);
builder.RegisterService(&dup_pkg_service_);
builder.SetThreadPool(&thread_pool_);
@@ -423,6 +453,44 @@ TEST_F(End2endTest, BadCredentials) {
EXPECT_EQ("Rpc sent on a lame channel.", s.details());
}
+void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) {
+ std::this_thread::sleep_for(std::chrono::microseconds(delay_us));
+ while (!service->signal_client()) {
+ }
+ context->TryCancel();
+}
+
+// Client cancels rpc after 10ms
+TEST_F(End2endTest, ClientCancelsRpc) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+ const int kCancelDelayUs = 10 * 1000;
+ request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs);
+
+ ClientContext context;
+ std::thread cancel_thread(CancelRpc, &context, kCancelDelayUs, &service_);
+ Status s = stub_->Echo(&context, request, &response);
+ cancel_thread.join();
+ EXPECT_EQ(StatusCode::CANCELLED, s.code());
+ EXPECT_TRUE(s.details().empty());
+}
+
+// Server cancels rpc after 1ms
+TEST_F(End2endTest, ServerCancelsRpc) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+ request.mutable_param()->set_server_cancel_after_us(1000);
+
+ ClientContext context;
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_EQ(StatusCode::CANCELLED, s.code());
+ EXPECT_TRUE(s.details().empty());
+}
+
} // namespace testing
} // namespace grpc
@@ -432,6 +500,5 @@ int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
int result = RUN_ALL_TESTS();
grpc_shutdown();
- google::protobuf::ShutdownProtobufLibrary();
return result;
}
diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc
index 711f1b9540..eb6f5369a9 100644
--- a/test/cpp/end2end/generic_end2end_test.cc
+++ b/test/cpp/end2end/generic_end2end_test.cc
@@ -38,7 +38,7 @@
#include "src/cpp/util/time.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
-#include "test/cpp/util/echo.pb.h"
+#include "test/cpp/util/echo.grpc.pb.h"
#include <grpc++/async_generic_service.h>
#include <grpc++/async_unary_call.h>
#include <grpc++/byte_buffer.h>
@@ -47,6 +47,7 @@
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/credentials.h>
+#include <grpc++/generic_stub.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
@@ -83,12 +84,21 @@ bool ParseFromByteBuffer(ByteBuffer* buffer, grpc::protobuf::Message* message) {
buffer->Dump(&slices);
grpc::string buf;
buf.reserve(buffer->Length());
- for (const Slice& s : slices) {
- buf.append(reinterpret_cast<const char*>(s.begin()), s.size());
+ for (auto s = slices.begin(); s != slices.end(); s++) {
+ buf.append(reinterpret_cast<const char*>(s->begin()), s->size());
}
return message->ParseFromString(buf);
}
+std::unique_ptr<ByteBuffer> SerializeToByteBuffer(
+ grpc::protobuf::Message* message) {
+ grpc::string buf;
+ message->SerializeToString(&buf);
+ gpr_slice s = gpr_slice_from_copied_string(buf.c_str());
+ Slice slice(s, Slice::STEAL_REF);
+ return std::unique_ptr<ByteBuffer>(new ByteBuffer(&slice, 1));
+}
+
class GenericEnd2endTest : public ::testing::Test {
protected:
GenericEnd2endTest() : generic_service_("*") {}
@@ -118,7 +128,7 @@ class GenericEnd2endTest : public ::testing::Test {
void ResetStub() {
std::shared_ptr<ChannelInterface> channel = CreateChannel(
server_address_.str(), InsecureCredentials(), ChannelArguments());
- stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel));
+ generic_stub_.reset(new GenericStub(channel));
}
void server_ok(int i) { verify_ok(&srv_cq_, i, true); }
@@ -127,6 +137,7 @@ class GenericEnd2endTest : public ::testing::Test {
void client_fail(int i) { verify_ok(&cli_cq_, i, false); }
void SendRpc(int num_rpcs) {
+ const grpc::string kMethodName("/grpc.cpp.test.util.TestService/Echo");
for (int i = 0; i < num_rpcs; i++) {
EchoRequest send_request;
EchoRequest recv_request;
@@ -139,35 +150,42 @@ class GenericEnd2endTest : public ::testing::Test {
GenericServerAsyncReaderWriter stream(&srv_ctx);
send_request.set_message("Hello");
- std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
- stub_->AsyncEcho(&cli_ctx, send_request, &cli_cq_, tag(1)));
+ std::unique_ptr<GenericClientAsyncReaderWriter> call =
+ generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1));
client_ok(1);
+ std::unique_ptr<ByteBuffer> send_buffer =
+ SerializeToByteBuffer(&send_request);
+ call->Write(*send_buffer, tag(2));
+ client_ok(2);
+ call->WritesDone(tag(3));
+ client_ok(3);
- generic_service_.RequestCall(&srv_ctx, &stream, &srv_cq_, tag(2));
+ generic_service_.RequestCall(&srv_ctx, &stream, &srv_cq_, tag(4));
- verify_ok(generic_service_.completion_queue(), 2, true);
+ verify_ok(generic_service_.completion_queue(), 4, true);
EXPECT_EQ(server_address_.str(), srv_ctx.host());
- EXPECT_EQ("/grpc.cpp.test.util.TestService/Echo", srv_ctx.method());
+ EXPECT_EQ(kMethodName, srv_ctx.method());
ByteBuffer recv_buffer;
- stream.Read(&recv_buffer, tag(3));
- server_ok(3);
+ stream.Read(&recv_buffer, tag(5));
+ server_ok(5);
EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request));
EXPECT_EQ(send_request.message(), recv_request.message());
send_response.set_message(recv_request.message());
- grpc::string buf;
- send_response.SerializeToString(&buf);
- gpr_slice s = gpr_slice_from_copied_string(buf.c_str());
- Slice slice(s, Slice::STEAL_REF);
- ByteBuffer send_buffer(&slice, 1);
- stream.Write(send_buffer, tag(4));
- server_ok(4);
-
- stream.Finish(Status::OK, tag(5));
- server_ok(5);
+ send_buffer = SerializeToByteBuffer(&send_response);
+ stream.Write(*send_buffer, tag(6));
+ server_ok(6);
+
+ stream.Finish(Status::OK, tag(7));
+ server_ok(7);
+
+ recv_buffer.Clear();
+ call->Read(&recv_buffer, tag(8));
+ client_ok(8);
+ EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response));
- response_reader->Finish(&recv_response, &recv_status, tag(4));
- client_ok(4);
+ call->Finish(&recv_status, tag(9));
+ client_ok(9);
EXPECT_EQ(send_response.message(), recv_response.message());
EXPECT_TRUE(recv_status.IsOk());
@@ -177,6 +195,7 @@ class GenericEnd2endTest : public ::testing::Test {
CompletionQueue cli_cq_;
CompletionQueue srv_cq_;
std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
+ std::unique_ptr<grpc::GenericStub> generic_stub_;
std::unique_ptr<Server> server_;
AsyncGenericService generic_service_;
std::ostringstream server_address_;
@@ -196,6 +215,7 @@ TEST_F(GenericEnd2endTest, SequentialRpcs) {
TEST_F(GenericEnd2endTest, SimpleBidiStreaming) {
ResetStub();
+ const grpc::string kMethodName("/grpc.cpp.test.util.TestService/BidiStream");
EchoRequest send_request;
EchoRequest recv_request;
EchoResponse send_response;
@@ -206,17 +226,19 @@ TEST_F(GenericEnd2endTest, SimpleBidiStreaming) {
GenericServerAsyncReaderWriter srv_stream(&srv_ctx);
send_request.set_message("Hello");
- std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse> >
- cli_stream(stub_->AsyncBidiStream(&cli_ctx, &cli_cq_, tag(1)));
+ std::unique_ptr<GenericClientAsyncReaderWriter> cli_stream =
+ generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1));
client_ok(1);
generic_service_.RequestCall(&srv_ctx, &srv_stream, &srv_cq_, tag(2));
verify_ok(generic_service_.completion_queue(), 2, true);
EXPECT_EQ(server_address_.str(), srv_ctx.host());
- EXPECT_EQ("/grpc.cpp.test.util.TestService/BidiStream", srv_ctx.method());
+ EXPECT_EQ(kMethodName, srv_ctx.method());
- cli_stream->Write(send_request, tag(3));
+ std::unique_ptr<ByteBuffer> send_buffer =
+ SerializeToByteBuffer(&send_request);
+ cli_stream->Write(*send_buffer, tag(3));
client_ok(3);
ByteBuffer recv_buffer;
@@ -226,22 +248,18 @@ TEST_F(GenericEnd2endTest, SimpleBidiStreaming) {
EXPECT_EQ(send_request.message(), recv_request.message());
send_response.set_message(recv_request.message());
- grpc::string buf;
- send_response.SerializeToString(&buf);
- gpr_slice s = gpr_slice_from_copied_string(buf.c_str());
- Slice slice(s, Slice::STEAL_REF);
- ByteBuffer send_buffer(&slice, 1);
- srv_stream.Write(send_buffer, tag(5));
+ send_buffer = SerializeToByteBuffer(&send_response);
+ srv_stream.Write(*send_buffer, tag(5));
server_ok(5);
- cli_stream->Read(&recv_response, tag(6));
+ cli_stream->Read(&recv_buffer, tag(6));
client_ok(6);
+ EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response));
EXPECT_EQ(send_response.message(), recv_response.message());
cli_stream->WritesDone(tag(7));
client_ok(7);
- recv_buffer.Clear();
srv_stream.Read(&recv_buffer, tag(8));
server_fail(8);
@@ -265,6 +283,5 @@ int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
int result = RUN_ALL_TESTS();
grpc_shutdown();
- google::protobuf::ShutdownProtobufLibrary();
return result;
}
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index de6c6b7b77..7c5e1aa715 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -51,9 +51,9 @@
#include <grpc++/status.h>
#include <grpc++/stream.h>
#include "test/cpp/util/create_test_channel.h"
-#include "test/cpp/interop/test.pb.h"
-#include "test/cpp/interop/empty.pb.h"
-#include "test/cpp/interop/messages.pb.h"
+#include "test/cpp/interop/test.grpc.pb.h"
+#include "test/cpp/interop/empty.grpc.pb.h"
+#include "test/cpp/interop/messages.grpc.pb.h"
DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
DEFINE_bool(use_prod_roots, false, "True to use SSL roots for google");
diff --git a/test/cpp/interop/server.cc b/test/cpp/interop/server.cc
index eceb600d4c..87bf48938b 100644
--- a/test/cpp/interop/server.cc
+++ b/test/cpp/interop/server.cc
@@ -49,9 +49,9 @@
#include <grpc++/server_credentials.h>
#include <grpc++/status.h>
#include <grpc++/stream.h>
-#include "test/cpp/interop/test.pb.h"
-#include "test/cpp/interop/empty.pb.h"
-#include "test/cpp/interop/messages.pb.h"
+#include "test/cpp/interop/test.grpc.pb.h"
+#include "test/cpp/interop/empty.grpc.pb.h"
+#include "test/cpp/interop/messages.grpc.pb.h"
DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
DEFINE_int32(port, 0, "Server port.");
@@ -213,8 +213,11 @@ void RunServer() {
builder.RegisterService(&service);
std::shared_ptr<ServerCredentials> creds = grpc::InsecureServerCredentials();
if (FLAGS_enable_ssl) {
- SslServerCredentialsOptions ssl_opts = {
- "", {{test_server1_key, test_server1_cert}}};
+ SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key,
+ test_server1_cert};
+ SslServerCredentialsOptions ssl_opts;
+ ssl_opts.pem_root_certs = "";
+ ssl_opts.pem_key_cert_pairs.push_back(pkcp);
creds = grpc::SslServerCredentials(ssl_opts);
}
builder.AddListeningPort(server_address.str(), creds);
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index 221fb30fc5..2dc5b3860f 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -36,7 +36,7 @@
#include "test/cpp/qps/histogram.h"
#include "test/cpp/qps/timer.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
#include <condition_variable>
#include <mutex>
@@ -104,7 +104,7 @@ class Client {
void EndThreads() { threads_.clear(); }
- virtual void ThreadFunc(Histogram* histogram, size_t thread_idx) = 0;
+ virtual bool ThreadFunc(Histogram* histogram, size_t thread_idx) = 0;
private:
class Thread {
@@ -113,20 +113,24 @@ class Client {
: done_(false),
new_(nullptr),
impl_([this, idx, client]() {
- for (;;) {
- // run the loop body
- client->ThreadFunc(&histogram_, idx);
- // lock, see if we're done
- std::lock_guard<std::mutex> g(mu_);
- if (done_) return;
- // also check if we're marking, and swap out the histogram if so
- if (new_) {
- new_->Swap(&histogram_);
- new_ = nullptr;
- cv_.notify_one();
+ for (;;) {
+ // run the loop body
+ bool thread_still_ok = client->ThreadFunc(&histogram_, idx);
+ // lock, see if we're done
+ std::lock_guard<std::mutex> g(mu_);
+ if (!thread_still_ok) {
+ gpr_log(GPR_ERROR, "Finishing client thread due to RPC error");
+ done_ = true;
+ }
+ if (done_) {return;}
+ // check if we're marking, swap out the histogram if so
+ if (new_) {
+ new_->Swap(&histogram_);
+ new_ = nullptr;
+ cv_.notify_one();
+ }
}
- }
- }) {}
+ }) {}
~Thread() {
{
@@ -164,8 +168,12 @@ class Client {
std::unique_ptr<Timer> timer_;
};
-std::unique_ptr<Client> CreateSynchronousClient(const ClientConfig& args);
-std::unique_ptr<Client> CreateAsyncClient(const ClientConfig& args);
+std::unique_ptr<Client>
+ CreateSynchronousUnaryClient(const ClientConfig& args);
+std::unique_ptr<Client>
+ CreateSynchronousStreamingClient(const ClientConfig& args);
+std::unique_ptr<Client> CreateAsyncUnaryClient(const ClientConfig& args);
+std::unique_ptr<Client> CreateAsyncStreamingClient(const ClientConfig& args);
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index 526f37a1fd..0a6d9beeca 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -46,9 +46,9 @@
#include <grpc++/async_unary_call.h>
#include <grpc++/client_context.h>
#include <grpc++/status.h>
-#include "test/core/util/grpc_profiler.h"
+#include <grpc++/stream.h>
#include "test/cpp/util/create_test_channel.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
#include "test/cpp/qps/timer.h"
#include "test/cpp/qps/client.h"
@@ -59,13 +59,13 @@ class ClientRpcContext {
public:
ClientRpcContext() {}
virtual ~ClientRpcContext() {}
- virtual bool RunNextState() = 0; // do next state, return false if steps done
+ // next state, return false if done. Collect stats when appropriate
+ virtual bool RunNextState(bool, Histogram* hist) = 0;
virtual void StartNewClone() = 0;
static void* tag(ClientRpcContext* c) { return reinterpret_cast<void*>(c); }
static ClientRpcContext* detag(void* t) {
return reinterpret_cast<ClientRpcContext*>(t);
}
- virtual void report_stats(Histogram* hist) = 0;
};
template <class RequestType, class ResponseType>
@@ -89,9 +89,12 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
response_reader_(
start_req(stub_, &context_, req_, ClientRpcContext::tag(this))) {}
~ClientRpcContextUnaryImpl() GRPC_OVERRIDE {}
- bool RunNextState() GRPC_OVERRIDE { return (this->*next_state_)(); }
- void report_stats(Histogram* hist) GRPC_OVERRIDE {
- hist->Add((Timer::Now() - start_) * 1e9);
+ bool RunNextState(bool ok, Histogram* hist) GRPC_OVERRIDE {
+ bool ret = (this->*next_state_)(ok);
+ if (!ret) {
+ hist->Add((Timer::Now() - start_) * 1e9);
+ }
+ return ret;
}
void StartNewClone() GRPC_OVERRIDE {
@@ -99,16 +102,16 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
}
private:
- bool ReqSent() {
+ bool ReqSent(bool) {
next_state_ = &ClientRpcContextUnaryImpl::RespDone;
response_reader_->Finish(&response_, &status_, ClientRpcContext::tag(this));
return true;
}
- bool RespDone() {
+ bool RespDone(bool) {
next_state_ = &ClientRpcContextUnaryImpl::DoCallBack;
return false;
}
- bool DoCallBack() {
+ bool DoCallBack(bool) {
callback_(status_, &response_);
return false;
}
@@ -116,7 +119,7 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
TestService::Stub* stub_;
RequestType req_;
ResponseType response_;
- bool (ClientRpcContextUnaryImpl::*next_state_)();
+ bool (ClientRpcContextUnaryImpl::*next_state_)(bool);
std::function<void(grpc::Status, ResponseType*)> callback_;
std::function<std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>(
TestService::Stub*, grpc::ClientContext*, const RequestType&, void*)>
@@ -127,24 +130,19 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
response_reader_;
};
-class AsyncClient GRPC_FINAL : public Client {
+class AsyncUnaryClient GRPC_FINAL : public Client {
public:
- explicit AsyncClient(const ClientConfig& config) : Client(config) {
+ explicit AsyncUnaryClient(const ClientConfig& config) : Client(config) {
for (int i = 0; i < config.async_client_threads(); i++) {
cli_cqs_.emplace_back(new CompletionQueue);
}
- auto payload_size = config.payload_size();
- auto check_done = [payload_size](grpc::Status s, SimpleResponse* response) {
- GPR_ASSERT(s.IsOk() && (response->payload().type() ==
- grpc::testing::PayloadType::COMPRESSABLE) &&
- (response->payload().body().length() ==
- static_cast<size_t>(payload_size)));
- };
+ auto check_done = [](grpc::Status s, SimpleResponse* response) {};
int t = 0;
for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) {
- for (auto& channel : channels_) {
+ for (auto channel = channels_.begin(); channel != channels_.end();
+ channel++) {
auto* cq = cli_cqs_[t].get();
t = (t + 1) % cli_cqs_.size();
auto start_req = [cq](TestService::Stub* stub, grpc::ClientContext* ctx,
@@ -152,7 +150,7 @@ class AsyncClient GRPC_FINAL : public Client {
return stub->AsyncUnaryCall(ctx, request, cq, tag);
};
- TestService::Stub* stub = channel.get_stub();
+ TestService::Stub* stub = channel->get_stub();
const SimpleRequest& request = request_;
new ClientRpcContextUnaryImpl<SimpleRequest, SimpleResponse>(
stub, request, start_req, check_done);
@@ -162,39 +160,181 @@ class AsyncClient GRPC_FINAL : public Client {
StartThreads(config.async_client_threads());
}
- ~AsyncClient() GRPC_OVERRIDE {
+ ~AsyncUnaryClient() GRPC_OVERRIDE {
EndThreads();
- for (auto& cq : cli_cqs_) {
- cq->Shutdown();
+ for (auto cq = cli_cqs_.begin(); cq != cli_cqs_.end(); cq++) {
+ (*cq)->Shutdown();
void* got_tag;
bool ok;
- while (cq->Next(&got_tag, &ok)) {
+ while ((*cq)->Next(&got_tag, &ok)) {
delete ClientRpcContext::detag(got_tag);
}
}
}
- void ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
+ bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
void* got_tag;
bool ok;
- cli_cqs_[thread_idx]->Next(&got_tag, &ok);
+ switch (cli_cqs_[thread_idx]->AsyncNext(&got_tag, &ok, std::chrono::system_clock::now() + std::chrono::seconds(1))) {
+ case CompletionQueue::SHUTDOWN: return false;
+ case CompletionQueue::TIMEOUT: return true;
+ case CompletionQueue::GOT_EVENT: break;
+ }
ClientRpcContext* ctx = ClientRpcContext::detag(got_tag);
- if (ctx->RunNextState() == false) {
+ if (ctx->RunNextState(ok, histogram) == false) {
+ // call the callback and then delete it
+ ctx->RunNextState(ok, histogram);
+ ctx->StartNewClone();
+ delete ctx;
+ }
+
+ return true;
+ }
+
+ std::vector<std::unique_ptr<CompletionQueue>> cli_cqs_;
+};
+
+template <class RequestType, class ResponseType>
+class ClientRpcContextStreamingImpl : public ClientRpcContext {
+ public:
+ ClientRpcContextStreamingImpl(
+ TestService::Stub *stub, const RequestType &req,
+ std::function<
+ std::unique_ptr<grpc::ClientAsyncReaderWriter<
+ RequestType,ResponseType>>(
+ TestService::Stub *, grpc::ClientContext *, void *)> start_req,
+ std::function<void(grpc::Status, ResponseType *)> on_done)
+ : context_(),
+ stub_(stub),
+ req_(req),
+ response_(),
+ next_state_(&ClientRpcContextStreamingImpl::ReqSent),
+ callback_(on_done),
+ start_req_(start_req),
+ start_(Timer::Now()),
+ stream_(start_req_(stub_, &context_, ClientRpcContext::tag(this))) {}
+ ~ClientRpcContextStreamingImpl() GRPC_OVERRIDE {}
+ bool RunNextState(bool ok, Histogram *hist) GRPC_OVERRIDE {
+ return (this->*next_state_)(ok, hist);
+ }
+ void StartNewClone() GRPC_OVERRIDE {
+ new ClientRpcContextStreamingImpl(stub_, req_, start_req_, callback_);
+ }
+
+ private:
+ bool ReqSent(bool ok, Histogram *) {
+ return StartWrite(ok);
+ }
+ bool StartWrite(bool ok) {
+ if (!ok) {
+ return(false);
+ }
+ start_ = Timer::Now();
+ next_state_ = &ClientRpcContextStreamingImpl::WriteDone;
+ stream_->Write(req_, ClientRpcContext::tag(this));
+ return true;
+ }
+ bool WriteDone(bool ok, Histogram *) {
+ if (!ok) {
+ return(false);
+ }
+ next_state_ = &ClientRpcContextStreamingImpl::ReadDone;
+ stream_->Read(&response_, ClientRpcContext::tag(this));
+ return true;
+ }
+ bool ReadDone(bool ok, Histogram *hist) {
+ hist->Add((Timer::Now() - start_) * 1e9);
+ return StartWrite(ok);
+ }
+ grpc::ClientContext context_;
+ TestService::Stub *stub_;
+ RequestType req_;
+ ResponseType response_;
+ bool (ClientRpcContextStreamingImpl::*next_state_)(bool, Histogram *);
+ std::function<void(grpc::Status, ResponseType *)> callback_;
+ std::function<std::unique_ptr<grpc::ClientAsyncReaderWriter<
+ RequestType,ResponseType>>(
+ TestService::Stub *, grpc::ClientContext *, void *)> start_req_;
+ grpc::Status status_;
+ double start_;
+ std::unique_ptr<grpc::ClientAsyncReaderWriter<RequestType,ResponseType>>
+ stream_;
+};
+
+class AsyncStreamingClient GRPC_FINAL : public Client {
+ public:
+ explicit AsyncStreamingClient(const ClientConfig &config) : Client(config) {
+ for (int i = 0; i < config.async_client_threads(); i++) {
+ cli_cqs_.emplace_back(new CompletionQueue);
+ }
+
+ auto check_done = [](grpc::Status s, SimpleResponse* response) {};
+
+ int t = 0;
+ for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) {
+ for (auto channel = channels_.begin(); channel != channels_.end();
+ channel++) {
+ auto* cq = cli_cqs_[t].get();
+ t = (t + 1) % cli_cqs_.size();
+ auto start_req = [cq](TestService::Stub *stub, grpc::ClientContext *ctx,
+ void *tag) {
+ auto stream = stub->AsyncStreamingCall(ctx, cq, tag);
+ return stream;
+ };
+
+ TestService::Stub *stub = channel->get_stub();
+ const SimpleRequest &request = request_;
+ new ClientRpcContextStreamingImpl<SimpleRequest, SimpleResponse>(
+ stub, request, start_req, check_done);
+ }
+ }
+
+ StartThreads(config.async_client_threads());
+ }
+
+ ~AsyncStreamingClient() GRPC_OVERRIDE {
+ EndThreads();
+
+ for (auto cq = cli_cqs_.begin(); cq != cli_cqs_.end(); cq++) {
+ (*cq)->Shutdown();
+ void *got_tag;
+ bool ok;
+ while ((*cq)->Next(&got_tag, &ok)) {
+ delete ClientRpcContext::detag(got_tag);
+ }
+ }
+ }
+
+ bool ThreadFunc(Histogram *histogram, size_t thread_idx) GRPC_OVERRIDE {
+ void *got_tag;
+ bool ok;
+ switch (cli_cqs_[thread_idx]->AsyncNext(&got_tag, &ok, std::chrono::system_clock::now() + std::chrono::seconds(1))) {
+ case CompletionQueue::SHUTDOWN: return false;
+ case CompletionQueue::TIMEOUT: return true;
+ case CompletionQueue::GOT_EVENT: break;
+ }
+
+ ClientRpcContext *ctx = ClientRpcContext::detag(got_tag);
+ if (ctx->RunNextState(ok, histogram) == false) {
// call the callback and then delete it
- ctx->report_stats(histogram);
- ctx->RunNextState();
+ ctx->RunNextState(ok, histogram);
ctx->StartNewClone();
delete ctx;
}
+
+ return true;
}
std::vector<std::unique_ptr<CompletionQueue>> cli_cqs_;
};
-std::unique_ptr<Client> CreateAsyncClient(const ClientConfig& args) {
- return std::unique_ptr<Client>(new AsyncClient(args));
+std::unique_ptr<Client> CreateAsyncUnaryClient(const ClientConfig& args) {
+ return std::unique_ptr<Client>(new AsyncUnaryClient(args));
+}
+std::unique_ptr<Client> CreateAsyncStreamingClient(const ClientConfig& args) {
+ return std::unique_ptr<Client>(new AsyncStreamingClient(args));
}
} // namespace testing
diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc
index 7bb7231c6f..aea5a0fb27 100644
--- a/test/cpp/qps/client_sync.cc
+++ b/test/cpp/qps/client_sync.cc
@@ -48,45 +48,91 @@
#include <grpc/support/host_port.h>
#include <gflags/gflags.h>
#include <grpc++/client_context.h>
-#include <grpc++/status.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
-#include "test/core/util/grpc_profiler.h"
+#include <grpc++/status.h>
+#include <grpc++/stream.h>
+#include <gtest/gtest.h>
#include "test/cpp/util/create_test_channel.h"
#include "test/cpp/qps/client.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
#include "test/cpp/qps/histogram.h"
#include "test/cpp/qps/timer.h"
namespace grpc {
namespace testing {
-class SynchronousClient GRPC_FINAL : public Client {
+class SynchronousClient : public Client {
public:
SynchronousClient(const ClientConfig& config) : Client(config) {
- size_t num_threads =
- config.outstanding_rpcs_per_channel() * config.client_channels();
- responses_.resize(num_threads);
- StartThreads(num_threads);
+ num_threads_ =
+ config.outstanding_rpcs_per_channel() * config.client_channels();
+ responses_.resize(num_threads_);
}
- ~SynchronousClient() { EndThreads(); }
+ virtual ~SynchronousClient() { EndThreads(); }
+
+ protected:
+ size_t num_threads_;
+ std::vector<SimpleResponse> responses_;
+};
- void ThreadFunc(Histogram* histogram, size_t thread_idx) {
+class SynchronousUnaryClient GRPC_FINAL : public SynchronousClient {
+ public:
+ SynchronousUnaryClient(const ClientConfig& config):
+ SynchronousClient(config) {StartThreads(num_threads_);}
+ ~SynchronousUnaryClient() {}
+
+ bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
auto* stub = channels_[thread_idx % channels_.size()].get_stub();
double start = Timer::Now();
grpc::ClientContext context;
grpc::Status s =
stub->UnaryCall(&context, request_, &responses_[thread_idx]);
histogram->Add((Timer::Now() - start) * 1e9);
+ return s.IsOk();
}
+};
- private:
- std::vector<SimpleResponse> responses_;
+class SynchronousStreamingClient GRPC_FINAL : public SynchronousClient {
+ public:
+ SynchronousStreamingClient(const ClientConfig& config):
+ SynchronousClient(config) {
+ for (size_t thread_idx=0;thread_idx<num_threads_;thread_idx++){
+ auto* stub = channels_[thread_idx % channels_.size()].get_stub();
+ stream_ = stub->StreamingCall(&context_);
+ }
+ StartThreads(num_threads_);
+ }
+ ~SynchronousStreamingClient() {
+ if (stream_) {
+ SimpleResponse response;
+ stream_->WritesDone();
+ EXPECT_TRUE(stream_->Finish().IsOk());
+ }
+ }
+
+ bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
+ double start = Timer::Now();
+ if (stream_->Write(request_) && stream_->Read(&responses_[thread_idx])) {
+ histogram->Add((Timer::Now() - start) * 1e9);
+ return true;
+ }
+ return false;
+ }
+ private:
+ grpc::ClientContext context_;
+ std::unique_ptr<grpc::ClientReaderWriter<SimpleRequest,
+ SimpleResponse>> stream_;
};
-std::unique_ptr<Client> CreateSynchronousClient(const ClientConfig& config) {
- return std::unique_ptr<Client>(new SynchronousClient(config));
+std::unique_ptr<Client>
+CreateSynchronousUnaryClient(const ClientConfig& config) {
+ return std::unique_ptr<Client>(new SynchronousUnaryClient(config));
+}
+std::unique_ptr<Client>
+CreateSynchronousStreamingClient(const ClientConfig& config) {
+ return std::unique_ptr<Client>(new SynchronousStreamingClient(config));
}
} // namespace testing
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index d29ca1de94..f44883783d 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -74,7 +74,9 @@ static vector<string> get_hosts(const string& name) {
ScenarioResult RunScenario(const ClientConfig& initial_client_config,
size_t num_clients,
const ServerConfig& server_config,
- size_t num_servers) {
+ size_t num_servers,
+ int warmup_seconds,
+ int benchmark_seconds) {
// ClientContext allocator (all are destroyed at scope exit)
list<ClientContext> contexts;
auto alloc_context = [&contexts]() {
@@ -146,7 +148,7 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config,
// Let everything warmup
gpr_log(GPR_INFO, "Warming up");
gpr_timespec start = gpr_now();
- gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(5)));
+ gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(warmup_seconds)));
// Start a run
gpr_log(GPR_INFO, "Starting");
@@ -154,55 +156,55 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config,
server_mark.mutable_mark();
ClientArgs client_mark;
client_mark.mutable_mark();
- for (auto& server : servers) {
- GPR_ASSERT(server.stream->Write(server_mark));
+ for (auto server = servers.begin(); server != servers.end(); server++) {
+ GPR_ASSERT(server->stream->Write(server_mark));
}
- for (auto& client : clients) {
- GPR_ASSERT(client.stream->Write(client_mark));
+ for (auto client = clients.begin(); client != clients.end(); client++) {
+ GPR_ASSERT(client->stream->Write(client_mark));
}
ServerStatus server_status;
ClientStatus client_status;
- for (auto& server : servers) {
- GPR_ASSERT(server.stream->Read(&server_status));
+ for (auto server = servers.begin(); server != servers.end(); server++) {
+ GPR_ASSERT(server->stream->Read(&server_status));
}
- for (auto& client : clients) {
- GPR_ASSERT(client.stream->Read(&client_status));
+ for (auto client = clients.begin(); client != clients.end(); client++) {
+ GPR_ASSERT(client->stream->Read(&client_status));
}
// Wait some time
gpr_log(GPR_INFO, "Running");
- gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(15)));
+ gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(benchmark_seconds)));
// Finish a run
ScenarioResult result;
gpr_log(GPR_INFO, "Finishing");
- for (auto& server : servers) {
- GPR_ASSERT(server.stream->Write(server_mark));
+ for (auto server = servers.begin(); server != servers.end(); server++) {
+ GPR_ASSERT(server->stream->Write(server_mark));
}
- for (auto& client : clients) {
- GPR_ASSERT(client.stream->Write(client_mark));
+ for (auto client = clients.begin(); client != clients.end(); client++) {
+ GPR_ASSERT(client->stream->Write(client_mark));
}
- for (auto& server : servers) {
- GPR_ASSERT(server.stream->Read(&server_status));
+ for (auto server = servers.begin(); server != servers.end(); server++) {
+ GPR_ASSERT(server->stream->Read(&server_status));
const auto& stats = server_status.stats();
result.server_resources.push_back(ResourceUsage{
stats.time_elapsed(), stats.time_user(), stats.time_system()});
}
- for (auto& client : clients) {
- GPR_ASSERT(client.stream->Read(&client_status));
+ for (auto client = clients.begin(); client != clients.end(); client++) {
+ GPR_ASSERT(client->stream->Read(&client_status));
const auto& stats = client_status.stats();
result.latencies.MergeProto(stats.latencies());
result.client_resources.push_back(ResourceUsage{
stats.time_elapsed(), stats.time_user(), stats.time_system()});
}
- for (auto& client : clients) {
- GPR_ASSERT(client.stream->WritesDone());
- GPR_ASSERT(client.stream->Finish().IsOk());
+ for (auto client = clients.begin(); client != clients.end(); client++) {
+ GPR_ASSERT(client->stream->WritesDone());
+ GPR_ASSERT(client->stream->Finish().IsOk());
}
- for (auto& server : servers) {
- GPR_ASSERT(server.stream->WritesDone());
- GPR_ASSERT(server.stream->Finish().IsOk());
+ for (auto server = servers.begin(); server != servers.end(); server++) {
+ GPR_ASSERT(server->stream->WritesDone());
+ GPR_ASSERT(server->stream->Finish().IsOk());
}
return result;
}
diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h
index d87e80dc55..b3a8bf8cc4 100644
--- a/test/cpp/qps/driver.h
+++ b/test/cpp/qps/driver.h
@@ -35,7 +35,7 @@
#define TEST_QPS_DRIVER_H
#include "test/cpp/qps/histogram.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
namespace grpc {
namespace testing {
@@ -54,7 +54,10 @@ struct ScenarioResult {
ScenarioResult RunScenario(const grpc::testing::ClientConfig& client_config,
size_t num_clients,
const grpc::testing::ServerConfig& server_config,
- size_t num_servers);
+ size_t num_servers,
+ int warmup_seconds,
+ int benchmark_seconds);
+
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/qps/histogram.h b/test/cpp/qps/histogram.h
index 7ba00e94c3..0547b7283a 100644
--- a/test/cpp/qps/histogram.h
+++ b/test/cpp/qps/histogram.h
@@ -35,7 +35,7 @@
#define TEST_QPS_HISTOGRAM_H
#include <grpc/support/histogram.h>
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
namespace grpc {
namespace testing {
@@ -50,10 +50,10 @@ class Histogram {
void Merge(Histogram* h) { gpr_histogram_merge(impl_, h->impl_); }
void Add(double value) { gpr_histogram_add(impl_, value); }
- double Percentile(double pctile) {
+ double Percentile(double pctile) const {
return gpr_histogram_percentile(impl_, pctile);
}
- double Count() { return gpr_histogram_count(impl_); }
+ double Count() const { return gpr_histogram_count(impl_); }
void Swap(Histogram* other) { std::swap(impl_, other->impl_); }
void FillProto(HistogramData* p) {
size_t n;
diff --git a/test/cpp/qps/qps-sweep.sh b/test/cpp/qps/qps-sweep.sh
new file mode 100755
index 0000000000..7bc6eade2c
--- /dev/null
+++ b/test/cpp/qps/qps-sweep.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+if [ x"$QPS_WORKERS" == x ]; then
+ echo Error: Must set QPS_WORKERS variable in form \
+ "host:port,host:port,..." 1>&2
+ exit 1
+fi
+
+bins=`find . .. ../.. ../../.. -name bins | head -1`
+
+for channels in 1 2 4 8
+do
+ for client in SYNCHRONOUS_CLIENT ASYNC_CLIENT
+ do
+ for server in SYNCHRONOUS_SERVER ASYNC_SERVER
+ do
+ for rpc in UNARY STREAMING
+ do
+ echo "Test $rpc $client $server , $channels channels"
+ "$bins"/opt/qps_driver --rpc_type=$rpc \
+ --client_type=$client --server_type=$server
+ done
+ done
+ done
+done
diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc
index 5e9a577f8e..220f826118 100644
--- a/test/cpp/qps/qps_driver.cc
+++ b/test/cpp/qps/qps_driver.cc
@@ -35,13 +35,17 @@
#include <grpc/support/log.h>
#include "test/cpp/qps/driver.h"
-#include "test/cpp/qps/stats.h"
+#include "test/cpp/qps/report.h"
DEFINE_int32(num_clients, 1, "Number of client binaries");
DEFINE_int32(num_servers, 1, "Number of server binaries");
+DEFINE_int32(warmup_seconds, 5, "Warmup time (in seconds)");
+DEFINE_int32(benchmark_seconds, 30, "Benchmark time (in seconds)");
+
// Common config
DEFINE_bool(enable_ssl, false, "Use SSL");
+DEFINE_string(rpc_type, "UNARY", "Type of RPC: UNARY or STREAMING");
// Server config
DEFINE_int32(server_threads, 1, "Number of server threads");
@@ -59,8 +63,8 @@ using grpc::testing::ClientConfig;
using grpc::testing::ServerConfig;
using grpc::testing::ClientType;
using grpc::testing::ServerType;
+using grpc::testing::RpcType;
using grpc::testing::ResourceUsage;
-using grpc::testing::sum;
// In some distros, gflags is in the namespace google, and in some others,
// in gflags. This hack is enabling us to find both.
@@ -73,6 +77,9 @@ int main(int argc, char** argv) {
grpc_init();
ParseCommandLineFlags(&argc, &argv, true);
+ RpcType rpc_type;
+ GPR_ASSERT(RpcType_Parse(FLAGS_rpc_type, &rpc_type));
+
ClientType client_type;
ServerType server_type;
GPR_ASSERT(ClientType_Parse(FLAGS_client_type, &client_type));
@@ -86,46 +93,20 @@ int main(int argc, char** argv) {
client_config.set_client_channels(FLAGS_client_channels);
client_config.set_payload_size(FLAGS_payload_size);
client_config.set_async_client_threads(FLAGS_async_client_threads);
+ client_config.set_rpc_type(rpc_type);
ServerConfig server_config;
server_config.set_server_type(server_type);
server_config.set_threads(FLAGS_server_threads);
server_config.set_enable_ssl(FLAGS_enable_ssl);
- auto result = RunScenario(client_config, FLAGS_num_clients, server_config,
- FLAGS_num_servers);
-
- gpr_log(GPR_INFO, "QPS: %.1f",
- result.latencies.Count() /
- average(result.client_resources,
- [](ResourceUsage u) { return u.wall_time; }));
-
- gpr_log(GPR_INFO, "Latencies (50/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f us",
- result.latencies.Percentile(50) / 1000,
- result.latencies.Percentile(95) / 1000,
- result.latencies.Percentile(99) / 1000,
- result.latencies.Percentile(99.9) / 1000);
-
- gpr_log(GPR_INFO, "Server system time: %.2f%%",
- 100.0 * sum(result.server_resources,
- [](ResourceUsage u) { return u.system_time; }) /
- sum(result.server_resources,
- [](ResourceUsage u) { return u.wall_time; }));
- gpr_log(GPR_INFO, "Server user time: %.2f%%",
- 100.0 * sum(result.server_resources,
- [](ResourceUsage u) { return u.user_time; }) /
- sum(result.server_resources,
- [](ResourceUsage u) { return u.wall_time; }));
- gpr_log(GPR_INFO, "Client system time: %.2f%%",
- 100.0 * sum(result.client_resources,
- [](ResourceUsage u) { return u.system_time; }) /
- sum(result.client_resources,
- [](ResourceUsage u) { return u.wall_time; }));
- gpr_log(GPR_INFO, "Client user time: %.2f%%",
- 100.0 * sum(result.client_resources,
- [](ResourceUsage u) { return u.user_time; }) /
- sum(result.client_resources,
- [](ResourceUsage u) { return u.wall_time; }));
+ auto result = RunScenario(client_config, FLAGS_num_clients,
+ server_config, FLAGS_num_servers,
+ FLAGS_warmup_seconds, FLAGS_benchmark_seconds);
+
+ ReportQPSPerCore(result, server_config);
+ ReportLatency(result);
+ ReportTimes(result);
grpc_shutdown();
return 0;
diff --git a/test/cpp/qps/qpstest.proto b/test/cpp/qps/qpstest.proto
index 6a7170bf58..1553ef5f07 100644
--- a/test/cpp/qps/qpstest.proto
+++ b/test/cpp/qps/qpstest.proto
@@ -87,15 +87,21 @@ enum ServerType {
ASYNC_SERVER = 2;
}
+enum RpcType {
+ UNARY = 1;
+ STREAMING = 2;
+}
+
message ClientConfig {
repeated string server_targets = 1;
required ClientType client_type = 2;
- required bool enable_ssl = 3;
+ optional bool enable_ssl = 3 [default=false];
required int32 outstanding_rpcs_per_channel = 4;
required int32 client_channels = 5;
required int32 payload_size = 6;
// only for async client:
optional int32 async_client_threads = 7;
+ optional RpcType rpc_type = 8 [default=UNARY];
}
// Request current stats
@@ -121,8 +127,8 @@ message ClientStatus {
message ServerConfig {
required ServerType server_type = 1;
- required int32 threads = 2;
- required bool enable_ssl = 3;
+ optional int32 threads = 2 [default=1];
+ optional bool enable_ssl = 3 [default=false];
}
message ServerArgs {
@@ -144,7 +150,7 @@ message SimpleRequest {
// Desired payload size in the response from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
- optional int32 response_size = 2;
+ optional int32 response_size = 2 [default=0];
// Optional input payload sent along with the request.
optional Payload payload = 3;
@@ -154,72 +160,14 @@ message SimpleResponse {
optional Payload payload = 1;
}
-message StreamingInputCallRequest {
- // Optional input payload sent along with the request.
- optional Payload payload = 1;
-
- // Not expecting any payload from the response.
-}
-
-message StreamingInputCallResponse {
- // Aggregated size of payloads received from the client.
- optional int32 aggregated_payload_size = 1;
-}
-
-message ResponseParameters {
- // Desired payload sizes in responses from the server.
- // If response_type is COMPRESSABLE, this denotes the size before compression.
- required int32 size = 1;
-
- // Desired interval between consecutive responses in the response stream in
- // microseconds.
- required int32 interval_us = 2;
-}
-
-message StreamingOutputCallRequest {
- // Desired payload type in the response from the server.
- // If response_type is RANDOM, the payload from each response in the stream
- // might be of different types. This is to simulate a mixed type of payload
- // stream.
- optional PayloadType response_type = 1 [default=COMPRESSABLE];
-
- repeated ResponseParameters response_parameters = 2;
-
- // Optional input payload sent along with the request.
- optional Payload payload = 3;
-}
-
-message StreamingOutputCallResponse {
- optional Payload payload = 1;
-}
-
service TestService {
// One request followed by one response.
// The server returns the client payload as-is.
rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
- // One request followed by a sequence of responses (streamed download).
- // The server returns the payload with client desired type and sizes.
- rpc StreamingOutputCall(StreamingOutputCallRequest)
- returns (stream StreamingOutputCallResponse);
-
- // A sequence of requests followed by one response (streamed upload).
- // The server returns the aggregated size of client payload as the result.
- rpc StreamingInputCall(stream StreamingInputCallRequest)
- returns (StreamingInputCallResponse);
-
- // A sequence of requests with each request served by the server immediately.
- // As one request could lead to multiple responses, this interface
- // demonstrates the idea of full duplexing.
- rpc FullDuplexCall(stream StreamingOutputCallRequest)
- returns (stream StreamingOutputCallResponse);
-
- // A sequence of requests followed by a sequence of responses.
- // The server buffers all the client requests and then serves them in order. A
- // stream of responses are returned to the client when the server starts with
- // first request.
- rpc HalfDuplexCall(stream StreamingOutputCallRequest)
- returns (stream StreamingOutputCallResponse);
+ // One request followed by one response.
+ // The server returns the client payload as-is.
+ rpc StreamingCall(stream SimpleRequest) returns (stream SimpleResponse);
}
service Worker {
diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc
new file mode 100644
index 0000000000..29d88da344
--- /dev/null
+++ b/test/cpp/qps/report.cc
@@ -0,0 +1,94 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/cpp/qps/report.h"
+
+#include <grpc/support/log.h>
+#include "test/cpp/qps/stats.h"
+
+namespace grpc {
+namespace testing {
+
+// QPS: XXX
+void ReportQPS(const ScenarioResult& result) {
+ gpr_log(GPR_INFO, "QPS: %.1f",
+ result.latencies.Count() /
+ average(result.client_resources,
+ [](ResourceUsage u) { return u.wall_time; }));
+}
+
+// QPS: XXX (YYY/server core)
+void ReportQPSPerCore(const ScenarioResult& result, const ServerConfig& server_config) {
+ auto qps =
+ result.latencies.Count() /
+ average(result.client_resources,
+ [](ResourceUsage u) { return u.wall_time; });
+
+ gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", qps, qps/server_config.threads());
+}
+
+// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us
+void ReportLatency(const ScenarioResult& result) {
+ gpr_log(GPR_INFO, "Latencies (50/90/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f/%.1f us",
+ result.latencies.Percentile(50) / 1000,
+ result.latencies.Percentile(90) / 1000,
+ result.latencies.Percentile(95) / 1000,
+ result.latencies.Percentile(99) / 1000,
+ result.latencies.Percentile(99.9) / 1000);
+}
+
+void ReportTimes(const ScenarioResult& result) {
+ gpr_log(GPR_INFO, "Server system time: %.2f%%",
+ 100.0 * sum(result.server_resources,
+ [](ResourceUsage u) { return u.system_time; }) /
+ sum(result.server_resources,
+ [](ResourceUsage u) { return u.wall_time; }));
+ gpr_log(GPR_INFO, "Server user time: %.2f%%",
+ 100.0 * sum(result.server_resources,
+ [](ResourceUsage u) { return u.user_time; }) /
+ sum(result.server_resources,
+ [](ResourceUsage u) { return u.wall_time; }));
+ gpr_log(GPR_INFO, "Client system time: %.2f%%",
+ 100.0 * sum(result.client_resources,
+ [](ResourceUsage u) { return u.system_time; }) /
+ sum(result.client_resources,
+ [](ResourceUsage u) { return u.wall_time; }));
+ gpr_log(GPR_INFO, "Client user time: %.2f%%",
+ 100.0 * sum(result.client_resources,
+ [](ResourceUsage u) { return u.user_time; }) /
+ sum(result.client_resources,
+ [](ResourceUsage u) { return u.wall_time; }));
+}
+
+} // namespace testing
+} // namespace grpc
diff --git a/src/php/ext/grpc/completion_queue.h b/test/cpp/qps/report.h
index 1d386cc58f..343e426ca4 100755..100644
--- a/src/php/ext/grpc/completion_queue.h
+++ b/test/cpp/qps/report.h
@@ -31,32 +31,27 @@
*
*/
-#ifndef NET_GRPC_PHP_GRPC_COMPLETION_QUEUE_H_
-#define NET_GRPC_PHP_GRPC_COMPLETION_QUEUE_H_
+#ifndef TEST_QPS_REPORT_H
+#define TEST_QPS_REPORT_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "php_grpc.h"
-
-#include "grpc/grpc.h"
+#include "test/cpp/qps/driver.h"
-/* Class entry for the PHP CompletionQueue class */
-extern zend_class_entry *grpc_ce_completion_queue;
+namespace grpc {
+namespace testing {
-/* Wrapper class for grpc_completion_queue that can be associated with a
- PHP object */
-typedef struct wrapped_grpc_completion_queue {
- zend_object std;
+// QPS: XXX
+void ReportQPS(const ScenarioResult& result);
+// QPS: XXX (YYY/server core)
+void ReportQPSPerCore(const ScenarioResult& result, const ServerConfig& config);
+// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us
+void ReportLatency(const ScenarioResult& result);
+// Server system time: XX%
+// Server user time: XX%
+// Client system time: XX%
+// Client user time: XX%
+void ReportTimes(const ScenarioResult& result);
- grpc_completion_queue *wrapped;
-} wrapped_grpc_completion_queue;
+} // namespace testing
+} // namespace grpc
-/* Initialize the CompletionQueue class */
-void grpc_init_completion_queue(TSRMLS_D);
-
-#endif /* NET_GRPC_PHP_GRPC_COMPLETION_QUEUE_H_ */
+#endif
diff --git a/test/cpp/qps/server.cc b/test/cpp/qps/server.cc
deleted file mode 100644
index e1907b069b..0000000000
--- a/test/cpp/qps/server.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/signal.h>
-#include <thread>
-
-#include <unistd.h>
-
-#include <gflags/gflags.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/host_port.h>
-#include <grpc++/config.h>
-#include <grpc++/server.h>
-#include <grpc++/server_builder.h>
-#include <grpc++/server_context.h>
-#include <grpc++/server_credentials.h>
-#include <grpc++/status.h>
-#include "src/cpp/server/thread_pool.h"
-#include "test/core/util/grpc_profiler.h"
-#include "test/cpp/qps/qpstest.pb.h"
-
-#include <grpc/grpc.h>
-#include <grpc/support/log.h>
-
-DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
-DEFINE_int32(port, 0, "Server port.");
-DEFINE_int32(server_threads, 4, "Number of server threads.");
-
-using grpc::Server;
-using grpc::ServerBuilder;
-using grpc::ServerContext;
-using grpc::ThreadPool;
-using grpc::testing::Payload;
-using grpc::testing::PayloadType;
-using grpc::testing::ServerStats;
-using grpc::testing::SimpleRequest;
-using grpc::testing::SimpleResponse;
-using grpc::testing::StatsRequest;
-using grpc::testing::TestService;
-using grpc::Status;
-
-// In some distros, gflags is in the namespace google, and in some others,
-// in gflags. This hack is enabling us to find both.
-namespace google {}
-namespace gflags {}
-using namespace google;
-using namespace gflags;
-
-static bool got_sigint = false;
-
-static void sigint_handler(int x) { got_sigint = 1; }
-
-static double time_double(struct timeval* tv) {
- return tv->tv_sec + 1e-6 * tv->tv_usec;
-}
-
-static bool SetPayload(PayloadType type, int size, Payload* payload) {
- PayloadType response_type = type;
- // TODO(yangg): Support UNCOMPRESSABLE payload.
- if (type != PayloadType::COMPRESSABLE) {
- return false;
- }
- payload->set_type(response_type);
- std::unique_ptr<char[]> body(new char[size]());
- payload->set_body(body.get(), size);
- return true;
-}
-
-namespace {
-
-class TestServiceImpl GRPC_FINAL : public TestService::Service {
- public:
- Status CollectServerStats(ServerContext* context, const StatsRequest*,
- ServerStats* response) {
- struct rusage usage;
- struct timeval tv;
- gettimeofday(&tv, NULL);
- getrusage(RUSAGE_SELF, &usage);
- response->set_time_now(time_double(&tv));
- response->set_time_user(time_double(&usage.ru_utime));
- response->set_time_system(time_double(&usage.ru_stime));
- return Status::OK;
- }
- Status UnaryCall(ServerContext* context, const SimpleRequest* request,
- SimpleResponse* response) {
- if (request->has_response_size() && request->response_size() > 0) {
- if (!SetPayload(request->response_type(), request->response_size(),
- response->mutable_payload())) {
- return Status(grpc::StatusCode::INTERNAL, "Error creating payload.");
- }
- }
- return Status::OK;
- }
-};
-
-} // namespace
-
-static void RunServer() {
- char* server_address = NULL;
- gpr_join_host_port(&server_address, "::", FLAGS_port);
-
- TestServiceImpl service;
-
- SimpleRequest request;
- SimpleResponse response;
-
- ServerBuilder builder;
- builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
- builder.RegisterService(&service);
-
- std::unique_ptr<ThreadPool> pool(new ThreadPool(FLAGS_server_threads));
- builder.SetThreadPool(pool.get());
-
- std::unique_ptr<Server> server(builder.BuildAndStart());
- gpr_log(GPR_INFO, "Server listening on %s\n", server_address);
-
- grpc_profiler_start("qps_server.prof");
-
- while (!got_sigint) {
- sleep(5);
- }
-
- grpc_profiler_stop();
-
- gpr_free(server_address);
-}
-
-int main(int argc, char** argv) {
- grpc_init();
- ParseCommandLineFlags(&argc, &argv, true);
-
- signal(SIGINT, sigint_handler);
-
- GPR_ASSERT(FLAGS_port != 0);
- GPR_ASSERT(!FLAGS_enable_ssl);
- RunServer();
-
- grpc_shutdown();
- return 0;
-}
diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h
index ef71cb94d0..68e0115410 100644
--- a/test/cpp/qps/server.h
+++ b/test/cpp/qps/server.h
@@ -35,7 +35,7 @@
#define TEST_QPS_SERVER_H
#include "test/cpp/qps/timer.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
namespace grpc {
namespace testing {
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index 586b6e7abe..b19c443c82 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -33,6 +33,7 @@
#include <forward_list>
#include <functional>
+#include <mutex>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/signal.h>
@@ -48,10 +49,10 @@
#include <grpc++/server_context.h>
#include <grpc++/server_credentials.h>
#include <grpc++/status.h>
+#include <grpc++/stream.h>
#include <gtest/gtest.h>
#include "src/cpp/server/thread_pool.h"
-#include "test/core/util/grpc_profiler.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
#include "test/cpp/qps/server.h"
#include <grpc/grpc.h>
@@ -63,7 +64,8 @@ namespace testing {
class AsyncQpsServerTest : public Server {
public:
AsyncQpsServerTest(const ServerConfig& config, int port)
- : srv_cq_(), async_service_(&srv_cq_), server_(nullptr) {
+ : srv_cq_(), async_service_(&srv_cq_), server_(nullptr),
+ shutdown_(false) {
char* server_address = NULL;
gpr_join_host_port(&server_address, "::", port);
@@ -78,10 +80,16 @@ class AsyncQpsServerTest : public Server {
using namespace std::placeholders;
request_unary_ = std::bind(&TestService::AsyncService::RequestUnaryCall,
&async_service_, _1, _2, _3, &srv_cq_, _4);
+ request_streaming_ =
+ std::bind(&TestService::AsyncService::RequestStreamingCall,
+ &async_service_, _1, _2, &srv_cq_, _3);
for (int i = 0; i < 100; i++) {
contexts_.push_front(
new ServerRpcContextUnaryImpl<SimpleRequest, SimpleResponse>(
- request_unary_, UnaryCall));
+ request_unary_, ProcessRPC));
+ contexts_.push_front(
+ new ServerRpcContextStreamingImpl<SimpleRequest, SimpleResponse>(
+ request_streaming_, ProcessRPC));
}
for (int i = 0; i < config.threads(); i++) {
threads_.push_back(std::thread([=]() {
@@ -89,11 +97,12 @@ class AsyncQpsServerTest : public Server {
bool ok;
void* got_tag;
while (srv_cq_.Next(&got_tag, &ok)) {
- if (ok) {
- ServerRpcContext* ctx = detag(got_tag);
- // The tag is a pointer to an RPC context to invoke
- if (ctx->RunNextState() == false) {
- // this RPC context is done, so refresh it
+ ServerRpcContext* ctx = detag(got_tag);
+ // The tag is a pointer to an RPC context to invoke
+ if (ctx->RunNextState(ok) == false) {
+ // this RPC context is done, so refresh it
+ std::lock_guard<std::mutex> g(shutdown_mutex_);
+ if (!shutdown_) {
ctx->Reset();
}
}
@@ -104,9 +113,13 @@ class AsyncQpsServerTest : public Server {
}
~AsyncQpsServerTest() {
server_->Shutdown();
- srv_cq_.Shutdown();
- for (auto& thr : threads_) {
- thr.join();
+ {
+ std::lock_guard<std::mutex> g(shutdown_mutex_);
+ shutdown_ = true;
+ srv_cq_.Shutdown();
+ }
+ for (auto thr = threads_.begin(); thr != threads_.end(); thr++) {
+ thr->join();
}
while (!contexts_.empty()) {
delete contexts_.front();
@@ -119,7 +132,7 @@ class AsyncQpsServerTest : public Server {
public:
ServerRpcContext() {}
virtual ~ServerRpcContext(){};
- virtual bool RunNextState() = 0; // do next state, return false if all done
+ virtual bool RunNextState(bool) = 0; // next state, return false if done
virtual void Reset() = 0; // start this back at a clean state
};
static void* tag(ServerRpcContext* func) {
@@ -130,7 +143,7 @@ class AsyncQpsServerTest : public Server {
}
template <class RequestType, class ResponseType>
- class ServerRpcContextUnaryImpl : public ServerRpcContext {
+ class ServerRpcContextUnaryImpl GRPC_FINAL : public ServerRpcContext {
public:
ServerRpcContextUnaryImpl(
std::function<void(ServerContext*, RequestType*,
@@ -146,7 +159,7 @@ class AsyncQpsServerTest : public Server {
AsyncQpsServerTest::tag(this));
}
~ServerRpcContextUnaryImpl() GRPC_OVERRIDE {}
- bool RunNextState() GRPC_OVERRIDE { return (this->*next_state_)(); }
+ bool RunNextState(bool ok) GRPC_OVERRIDE {return (this->*next_state_)(ok);}
void Reset() GRPC_OVERRIDE {
srv_ctx_ = ServerContext();
req_ = RequestType();
@@ -160,8 +173,12 @@ class AsyncQpsServerTest : public Server {
}
private:
- bool finisher() { return false; }
- bool invoker() {
+ bool finisher(bool) { return false; }
+ bool invoker(bool ok) {
+ if (!ok) {
+ return false;
+ }
+
ResponseType response;
// Call the RPC processing function
@@ -174,7 +191,7 @@ class AsyncQpsServerTest : public Server {
}
ServerContext srv_ctx_;
RequestType req_;
- bool (ServerRpcContextUnaryImpl::*next_state_)();
+ bool (ServerRpcContextUnaryImpl::*next_state_)(bool);
std::function<void(ServerContext*, RequestType*,
grpc::ServerAsyncResponseWriter<ResponseType>*, void*)>
request_method_;
@@ -183,9 +200,89 @@ class AsyncQpsServerTest : public Server {
grpc::ServerAsyncResponseWriter<ResponseType> response_writer_;
};
- static Status UnaryCall(const SimpleRequest* request,
- SimpleResponse* response) {
- if (request->has_response_size() && request->response_size() > 0) {
+ template <class RequestType, class ResponseType>
+ class ServerRpcContextStreamingImpl GRPC_FINAL : public ServerRpcContext {
+ public:
+ ServerRpcContextStreamingImpl(
+ std::function<void(ServerContext *,
+ grpc::ServerAsyncReaderWriter<ResponseType,
+ RequestType> *, void *)> request_method,
+ std::function<grpc::Status(const RequestType *, ResponseType *)>
+ invoke_method)
+ : next_state_(&ServerRpcContextStreamingImpl::request_done),
+ request_method_(request_method),
+ invoke_method_(invoke_method),
+ stream_(&srv_ctx_) {
+ request_method_(&srv_ctx_, &stream_, AsyncQpsServerTest::tag(this));
+ }
+ ~ServerRpcContextStreamingImpl() GRPC_OVERRIDE {
+ }
+ bool RunNextState(bool ok) GRPC_OVERRIDE {return (this->*next_state_)(ok);}
+ void Reset() GRPC_OVERRIDE {
+ srv_ctx_ = ServerContext();
+ req_ = RequestType();
+ stream_ = grpc::ServerAsyncReaderWriter<ResponseType,
+ RequestType>(&srv_ctx_);
+
+ // Then request the method
+ next_state_ = &ServerRpcContextStreamingImpl::request_done;
+ request_method_(&srv_ctx_, &stream_, AsyncQpsServerTest::tag(this));
+ }
+
+ private:
+ bool request_done(bool ok) {
+ if (!ok) {
+ return false;
+ }
+ stream_.Read(&req_, AsyncQpsServerTest::tag(this));
+ next_state_ = &ServerRpcContextStreamingImpl::read_done;
+ return true;
+ }
+
+ bool read_done(bool ok) {
+ if (ok) {
+ // invoke the method
+ ResponseType response;
+ // Call the RPC processing function
+ grpc::Status status = invoke_method_(&req_, &response);
+ // initiate the write
+ stream_.Write(response, AsyncQpsServerTest::tag(this));
+ next_state_ = &ServerRpcContextStreamingImpl::write_done;
+ } else { // client has sent writes done
+ // finish the stream
+ stream_.Finish(Status::OK, AsyncQpsServerTest::tag(this));
+ next_state_ = &ServerRpcContextStreamingImpl::finish_done;
+ }
+ return true;
+ }
+ bool write_done(bool ok) {
+ // now go back and get another streaming read!
+ if (ok) {
+ stream_.Read(&req_, AsyncQpsServerTest::tag(this));
+ next_state_ = &ServerRpcContextStreamingImpl::read_done;
+ }
+ else {
+ stream_.Finish(Status::OK, AsyncQpsServerTest::tag(this));
+ next_state_ = &ServerRpcContextStreamingImpl::finish_done;
+ }
+ return true;
+ }
+ bool finish_done(bool ok) {return false; /* reset the context */ }
+
+ ServerContext srv_ctx_;
+ RequestType req_;
+ bool (ServerRpcContextStreamingImpl::*next_state_)(bool);
+ std::function<void(ServerContext *,
+ grpc::ServerAsyncReaderWriter<ResponseType,
+ RequestType> *, void *)> request_method_;
+ std::function<grpc::Status(const RequestType *, ResponseType *)>
+ invoke_method_;
+ grpc::ServerAsyncReaderWriter<ResponseType,RequestType> stream_;
+ };
+
+ static Status ProcessRPC(const SimpleRequest* request,
+ SimpleResponse* response) {
+ if (request->response_size() > 0) {
if (!SetPayload(request->response_type(), request->response_size(),
response->mutable_payload())) {
return Status(grpc::StatusCode::INTERNAL, "Error creating payload.");
@@ -200,7 +297,13 @@ class AsyncQpsServerTest : public Server {
std::function<void(ServerContext*, SimpleRequest*,
grpc::ServerAsyncResponseWriter<SimpleResponse>*, void*)>
request_unary_;
+ std::function<void(ServerContext*, grpc::ServerAsyncReaderWriter<
+ SimpleResponse,SimpleRequest>*, void*)>
+ request_streaming_;
std::forward_list<ServerRpcContext*> contexts_;
+
+ std::mutex shutdown_mutex_;
+ bool shutdown_;
};
std::unique_ptr<Server> CreateAsyncServer(const ServerConfig& config,
diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc
index 3e15fb61c0..2770233a7c 100644
--- a/test/cpp/qps/server_sync.cc
+++ b/test/cpp/qps/server_sync.cc
@@ -47,8 +47,7 @@
#include <grpc++/status.h>
#include <grpc++/stream.h>
#include "src/cpp/server/thread_pool.h"
-#include "test/core/util/grpc_profiler.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
#include "test/cpp/qps/server.h"
#include "test/cpp/qps/timer.h"
@@ -62,7 +61,7 @@ class TestServiceImpl GRPC_FINAL : public TestService::Service {
public:
Status UnaryCall(ServerContext* context, const SimpleRequest* request,
SimpleResponse* response) GRPC_OVERRIDE {
- if (request->has_response_size() && request->response_size() > 0) {
+ if (request->response_size() > 0) {
if (!Server::SetPayload(request->response_type(),
request->response_size(),
response->mutable_payload())) {
@@ -71,6 +70,23 @@ class TestServiceImpl GRPC_FINAL : public TestService::Service {
}
return Status::OK;
}
+ Status StreamingCall(ServerContext *context,
+ ServerReaderWriter<SimpleResponse, SimpleRequest>*
+ stream) GRPC_OVERRIDE {
+ SimpleRequest request;
+ while (stream->Read(&request)) {
+ SimpleResponse response;
+ if (request.response_size() > 0) {
+ if (!Server::SetPayload(request.response_type(),
+ request.response_size(),
+ response.mutable_payload())) {
+ return Status(grpc::StatusCode::INTERNAL, "Error creating payload.");
+ }
+ }
+ stream->Write(response);
+ }
+ return Status::OK;
+ }
};
class SynchronousServer GRPC_FINAL : public grpc::testing::Server {
diff --git a/test/cpp/qps/smoke_test.cc b/test/cpp/qps/smoke_test.cc
new file mode 100644
index 0000000000..c9d321f133
--- /dev/null
+++ b/test/cpp/qps/smoke_test.cc
@@ -0,0 +1,149 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/log.h>
+
+#include "test/cpp/qps/driver.h"
+#include "test/cpp/qps/report.h"
+
+namespace grpc {
+namespace testing {
+
+static const int WARMUP = 5;
+static const int BENCHMARK = 10;
+
+static void RunSynchronousUnaryPingPong() {
+ gpr_log(GPR_INFO, "Running Synchronous Unary Ping Pong");
+
+ ClientConfig client_config;
+ client_config.set_client_type(SYNCHRONOUS_CLIENT);
+ client_config.set_enable_ssl(false);
+ client_config.set_outstanding_rpcs_per_channel(1);
+ client_config.set_client_channels(1);
+ client_config.set_payload_size(1);
+ client_config.set_rpc_type(UNARY);
+
+ ServerConfig server_config;
+ server_config.set_server_type(SYNCHRONOUS_SERVER);
+ server_config.set_enable_ssl(false);
+ server_config.set_threads(1);
+
+ auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK);
+
+ ReportQPS(result);
+ ReportLatency(result);
+}
+
+static void RunSynchronousStreamingPingPong() {
+ gpr_log(GPR_INFO, "Running Synchronous Streaming Ping Pong");
+
+ ClientConfig client_config;
+ client_config.set_client_type(SYNCHRONOUS_CLIENT);
+ client_config.set_enable_ssl(false);
+ client_config.set_outstanding_rpcs_per_channel(1);
+ client_config.set_client_channels(1);
+ client_config.set_payload_size(1);
+ client_config.set_rpc_type(STREAMING);
+
+ ServerConfig server_config;
+ server_config.set_server_type(SYNCHRONOUS_SERVER);
+ server_config.set_enable_ssl(false);
+ server_config.set_threads(1);
+
+ auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK);
+
+ ReportQPS(result);
+ ReportLatency(result);
+}
+
+static void RunAsyncUnaryPingPong() {
+ gpr_log(GPR_INFO, "Running Async Unary Ping Pong");
+
+ ClientConfig client_config;
+ client_config.set_client_type(ASYNC_CLIENT);
+ client_config.set_enable_ssl(false);
+ client_config.set_outstanding_rpcs_per_channel(1);
+ client_config.set_client_channels(1);
+ client_config.set_payload_size(1);
+ client_config.set_async_client_threads(1);
+ client_config.set_rpc_type(UNARY);
+
+ ServerConfig server_config;
+ server_config.set_server_type(ASYNC_SERVER);
+ server_config.set_enable_ssl(false);
+ server_config.set_threads(1);
+
+ auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK);
+
+ ReportQPS(result);
+ ReportLatency(result);
+}
+
+static void RunQPS() {
+ gpr_log(GPR_INFO, "Running QPS test");
+
+ ClientConfig client_config;
+ client_config.set_client_type(ASYNC_CLIENT);
+ client_config.set_enable_ssl(false);
+ client_config.set_outstanding_rpcs_per_channel(1000);
+ client_config.set_client_channels(8);
+ client_config.set_payload_size(1);
+ client_config.set_async_client_threads(8);
+ client_config.set_rpc_type(UNARY);
+
+ ServerConfig server_config;
+ server_config.set_server_type(ASYNC_SERVER);
+ server_config.set_enable_ssl(false);
+ server_config.set_threads(4);
+
+ auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK);
+
+ ReportQPSPerCore(result, server_config);
+ ReportLatency(result);
+}
+
+} // namespace testing
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ grpc_init();
+
+ using namespace grpc::testing;
+ RunSynchronousStreamingPingPong();
+ RunSynchronousUnaryPingPong();
+ RunAsyncUnaryPingPong();
+ RunQPS();
+
+ grpc_shutdown();
+ return 0;
+}
diff --git a/test/cpp/qps/smoke_test.sh b/test/cpp/qps/smoke_test.sh
new file mode 100755
index 0000000000..ba7f0a4f27
--- /dev/null
+++ b/test/cpp/qps/smoke_test.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+# performs a single qps run with one client and one server
+
+set -ex
+
+cd $(dirname $0)/../../..
+
+killall qps_worker || true
+
+config=opt
+
+NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'`
+
+make CONFIG=$config qps_worker qps_smoke_test -j$NUMCPUS
+
+bins/$config/qps_worker -driver_port 10000 -server_port 10001 &
+PID1=$!
+bins/$config/qps_worker -driver_port 10010 -server_port 10011 &
+PID2=$!
+
+export QPS_WORKERS="localhost:10000,localhost:10010"
+
+bins/$config/qps_smoke_test $*
+
+kill -2 $PID1 $PID2
+wait
+
diff --git a/test/cpp/qps/stats.h b/test/cpp/qps/stats.h
index ca59390ad7..82dc03e3da 100644
--- a/test/cpp/qps/stats.h
+++ b/test/cpp/qps/stats.h
@@ -43,8 +43,8 @@ namespace testing {
template <class T, class F>
double sum(const T& container, F functor) {
double r = 0;
- for (auto v : container) {
- r += functor(v);
+ for (auto v = container.begin(); v != container.end(); v++) {
+ r += functor(*v);
}
return r;
}
diff --git a/test/cpp/qps/timer.cc b/test/cpp/qps/timer.cc
index 3c1342041c..d1b6bc1e55 100644
--- a/test/cpp/qps/timer.cc
+++ b/test/cpp/qps/timer.cc
@@ -36,6 +36,7 @@
#include <sys/time.h>
#include <sys/resource.h>
#include <grpc/support/time.h>
+#include <grpc++/config.h>
Timer::Timer() : start_(Sample()) {}
diff --git a/test/cpp/qps/worker.cc b/test/cpp/qps/worker.cc
index fdcd9d5069..101eb9f969 100644
--- a/test/cpp/qps/worker.cc
+++ b/test/cpp/qps/worker.cc
@@ -55,7 +55,7 @@
#include <grpc++/stream.h>
#include "test/core/util/grpc_profiler.h"
#include "test/cpp/util/create_test_channel.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
#include "test/cpp/qps/client.h"
#include "test/cpp/qps/server.h"
@@ -71,15 +71,20 @@ using namespace gflags;
static bool got_sigint = false;
+static void sigint_handler(int x) {got_sigint = true;}
+
namespace grpc {
namespace testing {
std::unique_ptr<Client> CreateClient(const ClientConfig& config) {
switch (config.client_type()) {
case ClientType::SYNCHRONOUS_CLIENT:
- return CreateSynchronousClient(config);
+ return (config.rpc_type() == RpcType::UNARY) ?
+ CreateSynchronousUnaryClient(config) :
+ CreateSynchronousStreamingClient(config);
case ClientType::ASYNC_CLIENT:
- return CreateAsyncClient(config);
+ return (config.rpc_type() == RpcType::UNARY) ?
+ CreateAsyncUnaryClient(config) : CreateAsyncStreamingClient(config);
}
abort();
}
@@ -106,6 +111,60 @@ class WorkerImpl GRPC_FINAL : public Worker::Service {
return Status(RESOURCE_EXHAUSTED);
}
+ grpc_profiler_start("qps_client.prof");
+ Status ret = RunTestBody(ctx,stream);
+ grpc_profiler_stop();
+ return ret;
+ }
+
+ Status RunServer(ServerContext* ctx,
+ ServerReaderWriter<ServerStatus, ServerArgs>* stream)
+ GRPC_OVERRIDE {
+ InstanceGuard g(this);
+ if (!g.Acquired()) {
+ return Status(RESOURCE_EXHAUSTED);
+ }
+
+ grpc_profiler_start("qps_server.prof");
+ Status ret = RunServerBody(ctx,stream);
+ grpc_profiler_stop();
+ return ret;
+ }
+
+ private:
+ // Protect against multiple clients using this worker at once.
+ class InstanceGuard {
+ public:
+ InstanceGuard(WorkerImpl* impl)
+ : impl_(impl), acquired_(impl->TryAcquireInstance()) {}
+ ~InstanceGuard() {
+ if (acquired_) {
+ impl_->ReleaseInstance();
+ }
+ }
+
+ bool Acquired() const { return acquired_; }
+
+ private:
+ WorkerImpl* const impl_;
+ const bool acquired_;
+ };
+
+ bool TryAcquireInstance() {
+ std::lock_guard<std::mutex> g(mu_);
+ if (acquired_) return false;
+ acquired_ = true;
+ return true;
+ }
+
+ void ReleaseInstance() {
+ std::lock_guard<std::mutex> g(mu_);
+ GPR_ASSERT(acquired_);
+ acquired_ = false;
+ }
+
+ Status RunTestBody(ServerContext* ctx,
+ ServerReaderWriter<ClientStatus, ClientArgs>* stream) {
ClientArgs args;
if (!stream->Read(&args)) {
return Status(INVALID_ARGUMENT);
@@ -132,14 +191,8 @@ class WorkerImpl GRPC_FINAL : public Worker::Service {
return Status::OK;
}
- Status RunServer(ServerContext* ctx,
- ServerReaderWriter<ServerStatus, ServerArgs>* stream)
- GRPC_OVERRIDE {
- InstanceGuard g(this);
- if (!g.Acquired()) {
- return Status(RESOURCE_EXHAUSTED);
- }
-
+ Status RunServerBody(ServerContext* ctx,
+ ServerReaderWriter<ServerStatus, ServerArgs>* stream) {
ServerArgs args;
if (!stream->Read(&args)) {
return Status(INVALID_ARGUMENT);
@@ -167,38 +220,6 @@ class WorkerImpl GRPC_FINAL : public Worker::Service {
return Status::OK;
}
- private:
- // Protect against multiple clients using this worker at once.
- class InstanceGuard {
- public:
- InstanceGuard(WorkerImpl* impl)
- : impl_(impl), acquired_(impl->TryAcquireInstance()) {}
- ~InstanceGuard() {
- if (acquired_) {
- impl_->ReleaseInstance();
- }
- }
-
- bool Acquired() const { return acquired_; }
-
- private:
- WorkerImpl* const impl_;
- const bool acquired_;
- };
-
- bool TryAcquireInstance() {
- std::lock_guard<std::mutex> g(mu_);
- if (acquired_) return false;
- acquired_ = true;
- return true;
- }
-
- void ReleaseInstance() {
- std::lock_guard<std::mutex> g(mu_);
- GPR_ASSERT(acquired_);
- acquired_ = false;
- }
-
std::mutex mu_;
bool acquired_;
};
@@ -229,6 +250,8 @@ int main(int argc, char** argv) {
grpc_init();
ParseCommandLineFlags(&argc, &argv, true);
+ signal(SIGINT, sigint_handler);
+
grpc::testing::RunServer();
grpc_shutdown();
diff --git a/test/cpp/util/cli_call.cc b/test/cpp/util/cli_call.cc
new file mode 100644
index 0000000000..eb67b8d314
--- /dev/null
+++ b/test/cpp/util/cli_call.cc
@@ -0,0 +1,106 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/cpp/util/cli_call.h"
+
+#include <iostream>
+
+#include <grpc++/byte_buffer.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/client_context.h>
+#include <grpc++/generic_stub.h>
+#include <grpc++/status.h>
+#include <grpc++/stream.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice.h>
+
+namespace grpc {
+namespace testing {
+namespace {
+void* tag(int i) { return (void*)(gpr_intptr) i; }
+} // namespace
+
+void CliCall::Call(std::shared_ptr<grpc::ChannelInterface> channel,
+ const grpc::string& method, const grpc::string& request,
+ grpc::string* response) {
+ std::unique_ptr<grpc::GenericStub> stub(new grpc::GenericStub(channel));
+ grpc::ClientContext ctx;
+ grpc::CompletionQueue cq;
+ std::unique_ptr<grpc::GenericClientAsyncReaderWriter> call(
+ stub->Call(&ctx, method, &cq, tag(1)));
+ void* got_tag;
+ bool ok;
+ cq.Next(&got_tag, &ok);
+ GPR_ASSERT(ok);
+
+ gpr_slice s = gpr_slice_from_copied_string(request.c_str());
+ grpc::Slice req_slice(s, grpc::Slice::STEAL_REF);
+ grpc::ByteBuffer send_buffer(&req_slice, 1);
+ call->Write(send_buffer, tag(2));
+ cq.Next(&got_tag, &ok);
+ GPR_ASSERT(ok);
+ call->WritesDone(tag(3));
+ cq.Next(&got_tag, &ok);
+ GPR_ASSERT(ok);
+ grpc::ByteBuffer recv_buffer;
+ call->Read(&recv_buffer, tag(4));
+ cq.Next(&got_tag, &ok);
+ if (!ok) {
+ std::cout << "Failed to read response." << std::endl;
+ return;
+ }
+ grpc::Status status;
+ call->Finish(&status, tag(5));
+ cq.Next(&got_tag, &ok);
+ GPR_ASSERT(ok);
+
+ if (status.IsOk()) {
+ std::cout << "RPC finished with OK status." << std::endl;
+ std::vector<grpc::Slice> slices;
+ recv_buffer.Dump(&slices);
+
+ response->clear();
+ for (size_t i = 0; i < slices.size(); i++) {
+ response->append(reinterpret_cast<const char*>(slices[i].begin()),
+ slices[i].size());
+ }
+ } else {
+ std::cout << "RPC finished with status code " << status.code()
+ << " details: " << status.details() << std::endl;
+ }
+}
+
+} // namespace testing
+} // namespace grpc
diff --git a/test/cpp/util/cli_call.h b/test/cpp/util/cli_call.h
new file mode 100644
index 0000000000..7be8bb63c4
--- /dev/null
+++ b/test/cpp/util/cli_call.h
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_TEST_CPP_UTIL_CLI_CALL_H
+#define GRPC_TEST_CPP_UTIL_CLI_CALL_H
+
+#include <grpc++/channel_interface.h>
+#include <grpc++/config.h>
+
+namespace grpc {
+namespace testing {
+
+class CliCall GRPC_FINAL {
+ public:
+ static void Call(std::shared_ptr<grpc::ChannelInterface> channel,
+ const grpc::string& method, const grpc::string& request,
+ grpc::string* response);
+};
+
+} // namespace testing
+} // namespace grpc
+
+#endif // GRPC_TEST_CPP_UTIL_CLI_CALL_H
diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc
new file mode 100644
index 0000000000..32ef392cc4
--- /dev/null
+++ b/test/cpp/util/cli_call_test.cc
@@ -0,0 +1,131 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/util/test_config.h"
+#include "test/cpp/util/cli_call.h"
+#include "test/cpp/util/echo.grpc.pb.h"
+#include "src/cpp/server/thread_pool.h"
+#include <grpc++/channel_arguments.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/credentials.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
+#include <grpc++/status.h>
+#include "test/core/util/port.h"
+#include <gtest/gtest.h>
+
+#include <grpc/grpc.h>
+
+using grpc::cpp::test::util::EchoRequest;
+using grpc::cpp::test::util::EchoResponse;
+
+namespace grpc {
+namespace testing {
+
+class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
+ public:
+ Status Echo(ServerContext* context, const EchoRequest* request,
+ EchoResponse* response) GRPC_OVERRIDE {
+ response->set_message(request->message());
+ return Status::OK;
+ }
+};
+
+class CliCallTest : public ::testing::Test {
+ protected:
+ CliCallTest() : thread_pool_(2) {}
+
+ void SetUp() GRPC_OVERRIDE {
+ int port = grpc_pick_unused_port_or_die();
+ server_address_ << "localhost:" << port;
+ // Setup server
+ ServerBuilder builder;
+ builder.AddListeningPort(server_address_.str(),
+ InsecureServerCredentials());
+ builder.RegisterService(&service_);
+ builder.SetThreadPool(&thread_pool_);
+ server_ = builder.BuildAndStart();
+ }
+
+ void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
+
+ void ResetStub() {
+ channel_ = CreateChannel(server_address_.str(), InsecureCredentials(),
+ ChannelArguments());
+ stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel_));
+ }
+
+ std::shared_ptr<ChannelInterface> channel_;
+ std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
+ std::unique_ptr<Server> server_;
+ std::ostringstream server_address_;
+ TestServiceImpl service_;
+ ThreadPool thread_pool_;
+};
+
+// Send a rpc with a normal stub and then a CliCall. Verify they match.
+TEST_F(CliCallTest, SimpleRpc) {
+ ResetStub();
+ // Normal stub.
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+
+ ClientContext context;
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_EQ(response.message(), request.message());
+ EXPECT_TRUE(s.IsOk());
+
+ const grpc::string kMethod("/grpc.cpp.test.util.TestService/Echo");
+ grpc::string request_bin, response_bin, expected_response_bin;
+ EXPECT_TRUE(request.SerializeToString(&request_bin));
+ EXPECT_TRUE(response.SerializeToString(&expected_response_bin));
+ CliCall::Call(channel_, kMethod, request_bin, &response_bin);
+ EXPECT_EQ(expected_response_bin, response_bin);
+}
+
+} // namespace testing
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ grpc_test_init(argc, argv);
+ grpc_init();
+ ::testing::InitGoogleTest(&argc, argv);
+ int result = RUN_ALL_TESTS();
+ grpc_shutdown();
+ return result;
+}
diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc
new file mode 100644
index 0000000000..f2271d9365
--- /dev/null
+++ b/test/cpp/util/grpc_cli.cc
@@ -0,0 +1,139 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ A command line tool to talk to any grpc server.
+ Example of talking to grpc interop server:
+ 1. Prepare request binary file:
+ a. create a text file input.txt, containing the following:
+ response_size: 10
+ payload: {
+ body: "hello world"
+ }
+ b. under grpc/ run
+ protoc --proto_path=test/cpp/interop/ \
+ --encode=grpc.testing.SimpleRequest test/cpp/interop/messages.proto \
+ < input.txt > input.bin
+ 2. Start a server
+ make interop_server && bins/opt/interop_server --port=50051
+ 3. Run the tool
+ make grpc_cli && bins/opt/grpc_cli call localhost:50051 \
+ /grpc.testing.TestService/UnaryCall --enable_ssl=false \
+ --input_binary_file=input.bin --output_binary_file=output.bin
+ 4. Decode response
+ protoc --proto_path=test/cpp/interop/ \
+ --decode=grpc.testing.SimpleResponse test/cpp/interop/messages.proto \
+ < output.bin > output.txt
+ 5. Now the text form of response should be in output.txt
+*/
+
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
+#include <gflags/gflags.h>
+#include "test/cpp/util/cli_call.h"
+#include <grpc++/channel_arguments.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/credentials.h>
+
+#include <grpc/grpc.h>
+
+// In some distros, gflags is in the namespace google, and in some others,
+// in gflags. This hack is enabling us to find both.
+namespace google {}
+namespace gflags {}
+using namespace google;
+using namespace gflags;
+
+DEFINE_bool(enable_ssl, true, "Whether to use ssl/tls.");
+DEFINE_bool(use_auth, false, "Whether to create default google credentials.");
+DEFINE_string(input_binary_file, "",
+ "Path to input file containing serialized request.");
+DEFINE_string(output_binary_file, "output.bin",
+ "Path to output file to write serialized response.");
+
+int main(int argc, char** argv) {
+ grpc_init();
+
+ ParseCommandLineFlags(&argc, &argv, true);
+
+ if (argc < 4 || grpc::string(argv[1]) != "call") {
+ std::cout << "Usage: grpc_cli call server_host:port full_method_string\n"
+ << "Example: grpc_cli call service.googleapis.com "
+ << "/grpc.testing.TestService/UnaryCall "
+ << "--input_binary_file=input.bin --output_binary_file=output.bin"
+ << std::endl;
+ }
+ grpc::string server_address(argv[2]);
+ // TODO(yangg) basic check of method string
+ grpc::string method(argv[3]);
+
+ if (FLAGS_input_binary_file.empty()) {
+ std::cout << "Missing --input_binary_file for serialized request."
+ << std::endl;
+ return 1;
+ }
+ std::cout << "connecting to " << server_address << std::endl;
+
+ std::ifstream input_file(FLAGS_input_binary_file,
+ std::ios::in | std::ios::binary);
+ std::stringstream input_stream;
+ input_stream << input_file.rdbuf();
+
+ std::unique_ptr<grpc::Credentials> creds;
+ if (!FLAGS_enable_ssl) {
+ creds = grpc::InsecureCredentials();
+ } else {
+ if (FLAGS_use_auth) {
+ creds = grpc::GoogleDefaultCredentials();
+ } else {
+ creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
+ }
+ }
+ std::shared_ptr<grpc::ChannelInterface> channel =
+ grpc::CreateChannel(server_address, creds, grpc::ChannelArguments());
+
+ grpc::string response;
+ grpc::testing::CliCall::Call(channel, method, input_stream.str(), &response);
+ if (!response.empty()) {
+ std::ofstream output_file(FLAGS_output_binary_file,
+ std::ios::trunc | std::ios::binary);
+ output_file << response;
+ }
+
+ channel.reset();
+ grpc_shutdown();
+ return 0;
+}
diff --git a/test/cpp/util/messages.proto b/test/cpp/util/messages.proto
index 9c27f6869e..a79bce1f30 100644
--- a/test/cpp/util/messages.proto
+++ b/test/cpp/util/messages.proto
@@ -34,6 +34,8 @@ package grpc.cpp.test.util;
message RequestParams {
optional bool echo_deadline = 1;
+ optional int32 client_cancel_after_us = 2;
+ optional int32 server_cancel_after_us = 3;
}
message EchoRequest {
diff --git a/test/cpp/util/time_test.cc b/test/cpp/util/time_test.cc
index 2e17add67f..4641fdb4da 100644
--- a/test/cpp/util/time_test.cc
+++ b/test/cpp/util/time_test.cc
@@ -61,11 +61,24 @@ TEST_F(TimeTest, AbsolutePointTest) {
EXPECT_TRUE(tp == tp_converted_2);
}
-// gpr_inf_future is treated specially and mapped to time_point::max()
+// gpr_inf_future is treated specially and mapped to/from time_point::max()
TEST_F(TimeTest, InfFuture) {
EXPECT_EQ(system_clock::time_point::max(),
Timespec2Timepoint(gpr_inf_future));
+ gpr_timespec from_time_point_max;
+ Timepoint2Timespec(system_clock::time_point::max(), &from_time_point_max);
+ EXPECT_EQ(0, gpr_time_cmp(gpr_inf_future, from_time_point_max));
+ // This will cause an overflow
+ Timepoint2Timespec(
+ std::chrono::time_point<system_clock, std::chrono::seconds>::max(),
+ &from_time_point_max);
+ EXPECT_EQ(0, gpr_time_cmp(gpr_inf_future, from_time_point_max));
}
} // namespace
} // namespace grpc
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/third_party/openssl b/third_party/openssl
-Subproject 4ac0329582829f5378d8078c8d314ad37db8773
+Subproject 3df69d3aefde7671053d4e3c242b228e5d79c83
diff --git a/tools/distpackages/build_deb_packages.sh b/tools/distpackages/build_deb_packages.sh
index 7b2acb6577..0beb41ed0a 100755
--- a/tools/distpackages/build_deb_packages.sh
+++ b/tools/distpackages/build_deb_packages.sh
@@ -30,11 +30,28 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Where to put resulting .deb packages.
-deb_dest="deb_out"
+set -x
+deb_dest="/tmp/deb_out"
mkdir -p $deb_dest
-version='0.5.0.0'
+# Where the grpc disto is
+grpc_root="/var/local/git/grpc"
+
+# Update version from default values if the file /version.txt exists
+#
+# - when present, /version.txt will added by the docker build.
pkg_version='0.5.0'
+if [ -f /version.txt ]; then
+ pkg_version=$(cat /version.txt)
+fi
+version="${pkg_version}.0"
+release_tag="release-${pkg_version//./_}"
+echo "Target release => $pkg_version, will checkout tag $release_tag"
+
+# Switch grpc_root to the release tag
+pushd $grpc_root
+git checkout $release_tag || { echo "bad release tag ${release_tag}"; exit 1; }
+popd
if [ -f /.dockerinit ]; then
# We're in Docker where uname -p returns "unknown".
@@ -64,7 +81,9 @@ do
if [ $pkg_name == "libgrpc" ]
then
# Copy shared libraries
- (cd ../..; make install-shared_c prefix=$tmp_dir/$pkg_name/usr/lib)
+ pushd $grpc_root
+ make install-shared_c prefix=$tmp_dir/$pkg_name/usr/lib
+ popd
mv $tmp_dir/$pkg_name/usr/lib/lib $arch_lib_dir
# non-dev package should contain so.0 symlinks
@@ -77,7 +96,10 @@ do
if [ $pkg_name == "libgrpc-dev" ]
then
# Copy headers and static libraries
- (cd ../..; make install-headers_c install-static_c prefix=$tmp_dir/$pkg_name/usr/lib)
+ pushd $grpc_root
+ make install-headers_c install-static_c prefix=$tmp_dir/$pkg_name/usr/lib
+ popd
+
mv $tmp_dir/$pkg_name/usr/lib/include $tmp_dir/$pkg_name/usr/include
mv $tmp_dir/$pkg_name/usr/lib/lib $arch_lib_dir
@@ -110,8 +132,5 @@ do
dpkg-deb -c $deb_path
echo "Problems reported by lintian:"
lintian $deb_path
-
echo
done
-
-
diff --git a/tools/distpackages/templates/libgrpc/DEBIAN/control b/tools/distpackages/templates/libgrpc/DEBIAN/control
index 417a825827..5854b1f4a1 100644
--- a/tools/distpackages/templates/libgrpc/DEBIAN/control
+++ b/tools/distpackages/templates/libgrpc/DEBIAN/control
@@ -2,7 +2,8 @@ Package: libgrpc
Version: 0.5.0
Architecture: amd64
Maintainer: Jan Tattermusch <jtattermusch@google.com>
-Depends: libc6
+Depends: libc6, openssl (1.0.2-1)
+Build-Depends-Indep: openssl (1.0.2-1)
Section: libs
Priority: optional
Homepage: https://github.com/grpc/grpc
diff --git a/tools/distrib/python/submit.py b/tools/distrib/python/submit.py
new file mode 100755
index 0000000000..79ebb93e57
--- /dev/null
+++ b/tools/distrib/python/submit.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import argparse
+import os
+import shutil
+import subprocess
+
+parser = argparse.ArgumentParser(
+ description='Submit the package to a PyPI repository.')
+parser.add_argument(
+ '--repository', '-r', metavar='r', type=str, default='pypi',
+ help='The repository to push the package to. '
+ 'Ensure the value appears in your .pypirc file. '
+ 'Defaults to "pypi".'
+)
+parser.add_argument(
+ '--identity', '-i', metavar='i', type=str,
+ help='GPG identity to sign the files with.'
+)
+parser.add_argument(
+ '--username', '-u', metavar='u', type=str,
+ help='Username to authenticate with the repository. Not needed if you have '
+ 'configured your .pypirc to include your username.'
+)
+parser.add_argument(
+ '--password', '-p', metavar='p', type=str,
+ help='Password to authenticate with the repository. Not needed if you have '
+ 'configured your .pypirc to include your password.'
+)
+args = parser.parse_args()
+
+# Move to the root directory of Python GRPC.
+pkgdir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
+ '../../../src/python/src')
+# Remove previous distributions; they somehow confuse twine.
+try:
+ shutil.rmtree(os.path.join(pkgdir, 'dist/'))
+except:
+ pass
+
+# Make the push.
+cmd = ['python', 'setup.py', 'sdist']
+subprocess.call(cmd, cwd=pkgdir)
+
+cmd = ['twine', 'upload', '-r', args.repository]
+if args.identity is not None:
+ cmd.extend(['-i', args.identity])
+if args.username is not None:
+ cmd.extend(['-u', args.username])
+if args.password is not None:
+ cmd.extend(['-p', args.password])
+cmd.append('dist/*')
+
+subprocess.call(cmd, cwd=pkgdir)
diff --git a/tools/dockerfile/grpc_build_deb/Dockerfile b/tools/dockerfile/grpc_build_deb/Dockerfile
index 24ffc7379c..7f025b6712 100644
--- a/tools/dockerfile/grpc_build_deb/Dockerfile
+++ b/tools/dockerfile/grpc_build_deb/Dockerfile
@@ -30,8 +30,17 @@
# Dockerfile to build Debian packages for gRPC C core.
FROM grpc/base
+# Add the file containing the gRPC version
+ADD version.txt version.txt
+
+# Add the update-to-date distpackages folder
+ADD distpackages distpackages
+
# Install dependencies
-RUN apt-get update && apt-get install -y lintian
+RUN echo 'deb http://http.debian.net/debian experimental main contrib non-free' >> /etc/apt/sources.list
+RUN apt-get update \
+ && apt-get -t experimental install -y openssl=1.0.2-1 \
+ && apt-get install -y lintian
# Get the source from GitHub
RUN git clone https://github.com/grpc/grpc.git /var/local/git/grpc
@@ -39,4 +48,4 @@ RUN cd /var/local/git/grpc && \
git pull --recurse-submodules && \
git submodule update --init --recursive
-RUN /bin/bash -l -c 'cd /var/local/git/grpc/tools/distpackages && ./build_deb_packages.sh'
+RUN /bin/bash -l -c 'cd /distpackages && ./build_deb_packages.sh'
diff --git a/tools/dockerfile/grpc_build_deb/version.txt b/tools/dockerfile/grpc_build_deb/version.txt
new file mode 100644
index 0000000000..a918a2aa18
--- /dev/null
+++ b/tools/dockerfile/grpc_build_deb/version.txt
@@ -0,0 +1 @@
+0.6.0
diff --git a/tools/dockerfile/grpc_dist_proto/version.txt b/tools/dockerfile/grpc_dist_proto/version.txt
index 8f0916f768..a918a2aa18 100644
--- a/tools/dockerfile/grpc_dist_proto/version.txt
+++ b/tools/dockerfile/grpc_dist_proto/version.txt
@@ -1 +1 @@
-0.5.0
+0.6.0
diff --git a/tools/dockerfile/grpc_java_base/Dockerfile b/tools/dockerfile/grpc_java_base/Dockerfile
index 2ee0a623c7..57b1b90fcd 100644
--- a/tools/dockerfile/grpc_java_base/Dockerfile
+++ b/tools/dockerfile/grpc_java_base/Dockerfile
@@ -57,8 +57,6 @@ RUN wget -O - https://github.com/google/protobuf/archive/v3.0.0-alpha-2.tar.gz |
./autogen.sh && \
./configure --prefix=/usr && \
make -j12 && make check && make install && \
- cd java && mvn install && cd .. && \
- cd javanano && mvn install && cd .. && \
rm -r "$(pwd)"
# Trigger download of as many Maven and Gradle artifacts as possible. We don't build grpc-java
diff --git a/tools/dockerfile/grpc_php/Dockerfile b/tools/dockerfile/grpc_php/Dockerfile
index 100d7b3bdb..770d0d2627 100644
--- a/tools/dockerfile/grpc_php/Dockerfile
+++ b/tools/dockerfile/grpc_php/Dockerfile
@@ -45,3 +45,9 @@ RUN cd /var/local/git/grpc/src/php/ext/grpc && git pull && phpize
RUN cd /var/local/git/grpc/src/php/ext/grpc \
&& ./configure \
&& make
+
+RUN cd /var/local/git/grpc/src/php && composer install
+
+RUN cd /var/local/git/grpc/src/php && protoc-gen-php -i tests/interop/ -o tests/interop/ tests/interop/test.proto
+
+RUN cd /var/local/git/grpc/src/php && ./bin/run_tests.sh \ No newline at end of file
diff --git a/tools/dockerfile/grpc_php_base/Dockerfile b/tools/dockerfile/grpc_php_base/Dockerfile
index cc874fd7c5..c49d3fef66 100644
--- a/tools/dockerfile/grpc_php_base/Dockerfile
+++ b/tools/dockerfile/grpc_php_base/Dockerfile
@@ -32,6 +32,10 @@
# Includes PHP installation dependencies, things that are unlikely to vary.
FROM grpc/base
+RUN echo "deb http://packages.dotdeb.org wheezy-php55 all" >> /etc/apt/sources.list.d/dotdeb.list
+RUN echo "deb-src http://packages.dotdeb.org wheezy-php55 all" >> /etc/apt/sources.list.d/dotdeb.list
+RUN wget http://www.dotdeb.org/dotdeb.gpg -O- |apt-key add -
+
# Install RVM dependencies and other packages
RUN apt-get update && apt-get install -y \
autoconf \
@@ -50,29 +54,25 @@ RUN apt-get update && apt-get install -y \
libsqlite3-dev \
libssl-dev \
libtool \
+ libxml2 \
libyaml-dev \
make \
patch \
procps \
-# TODO(mlumish): Uncomment these lines when building against them works
-# php5-common \
-# php5-cli \
-# php5-dev \
-# php-pear \
+ php5-common \
+ php5-cli \
+ php5-dev \
+ php-pear \
pkg-config \
procps \
sqlite3 \
zlib1g-dev
-# Install the version of PHP gRPC is tested against
ENV DEBIAN_FRONTEND noniteractive
-RUN apt-get update && apt-get install -y libxml2 libxml2-dev # used by PHP
-RUN cd /var/local \
- && curl -o php-5.5.17.tar.gz http://php.net/distributions/php-5.5.17.tar.gz \
- && tar -xf php-5.5.17.tar.gz \
- && cd php-5.5.17 \
- && ./configure --with-zlib=/usr --with-libxml-dir=ext/libxml \
- && make -j12 && make install
+
+# Install composer
+RUN curl -sS https://getcomposer.org/installer | php
+RUN mv composer.phar /usr/local/bin/composer
# Download the patched PHP protobuf so that PHP gRPC clients can be generated
# from proto3 schemas.
diff --git a/tools/dockerfile/grpc_scan_build/Dockerfile b/tools/dockerfile/grpc_scan_build/Dockerfile
new file mode 100644
index 0000000000..9f263849c9
--- /dev/null
+++ b/tools/dockerfile/grpc_scan_build/Dockerfile
@@ -0,0 +1,47 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+FROM grpc/clang:latest
+
+RUN apt-get update && apt-get install -y \
+ autoconf \
+ libtool \
+ libgflags-dev \
+ libgtest-dev \
+ && apt-get clean
+
+RUN git clone --recursive https://github.com/grpc/grpc.git
+
+EXPOSE 8181
+
+CMD \
+ (cd grpc ; git pull) && \
+ (cd grpc ; git submodule update --init --recursive) && \
+ llvm/tools/clang/tools/scan-build/scan-build -o /tmp/grpc --use-analyzer=/usr/local/bin/clang make -C grpc buildtests && \
+ llvm/tools/clang/tools/scan-view/scan-view /tmp/grpc/`ls /tmp/grpc` --host 0.0.0.0 --no-browser --allow-all-hosts
diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh
index 497112ce39..40634291cf 100755
--- a/tools/gce_setup/grpc_docker.sh
+++ b/tools/gce_setup/grpc_docker.sh
@@ -673,7 +673,7 @@ _grpc_build_proto_bins_args() {
}
# grpc_build_proto_bins
-#
+#
# - rebuilds the dist_proto docker image
# * doing this builds the protoc and the ruby, python and cpp bins statically
#
@@ -693,11 +693,11 @@ grpc_build_proto_bins() {
gce_has_instance $grpc_project $host || return 1;
local project_opt="--project $grpc_project"
local zone_opt="--zone $grpc_zone"
-
+
# rebuild the dist_proto image
local label='dist_proto'
grpc_update_image -- -h $host $label || return 1
-
+
# run a command to copy the generated archive to the docker host
local docker_prefix='sudo docker run -v /tmp:/tmp/proto_bins_out'
local tar_name='proto-bins*.tar.gz'
@@ -715,6 +715,63 @@ grpc_build_proto_bins() {
gcloud compute copy-files $rmt_tar $local_copy $project_opt $zone_opt || return 1
}
+_grpc_build_debs_args() {
+ [[ -n $1 ]] && { # host
+ host=$1
+ shift
+ } || {
+ host='grpc-docker-builder'
+ }
+}
+
+# grpc_build_debs
+#
+# - rebuilds the build_debs
+# * doing this builds a deb package for release debs
+#
+# - runs a docker command that copies the debs from the docker instance to its
+# host
+# - copies the debs from the host to the local machine
+grpc_build_debs() {
+ _grpc_ensure_gcloud_ssh || return 1;
+
+ # declare vars local so that they don't pollute the shell environment
+ # where this func is used.
+ local grpc_zone grpc_project dry_run # set by _grpc_set_project_and_zone
+ # set by _grpc_build_debs_args
+ local host
+
+ # set the project zone and check that all necessary args are provided
+ _grpc_set_project_and_zone -f _grpc_build_debs_args "$@" || return 1
+ gce_has_instance $grpc_project $host || return 1;
+ local project_opt="--project $grpc_project"
+ local zone_opt="--zone $grpc_zone"
+
+ # Update the remote distpackages_dir
+ local src_dist_dir='tools/distpackages'
+ local rmt_dist_dir="$host:~"
+ gcloud compute copy-files $src_dist_dir $rmt_dist_dir $project_opt $zone_opt || return 1
+
+ # rebuild the build_deb image
+ local label='build_deb'
+ grpc_update_image -- -h $host $label || return 1
+
+ # run a command to copy the debs from the docker instance to the host.
+ local docker_prefix='sudo docker run -v /tmp:/tmp/host_deb_out'
+ local cp_cmd="/bin/bash -c 'cp -v /tmp/deb_out/*.deb /tmp/host_deb_out'"
+ local cmd="$docker_prefix grpc/$label $cp_cmd"
+ local ssh_cmd="bash -l -c \"$cmd\""
+ echo "will run:"
+ echo " $ssh_cmd"
+ echo "on $host"
+ gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" || return 1
+
+ # copy the debs from host machine to the local one.
+ local rmt_debs="$host:/tmp/*.deb"
+ local local_copy="$(pwd)"
+ gcloud compute copy-files $rmt_debs $local_copy $project_opt $zone_opt || return 1
+}
+
_grpc_launch_servers_args() {
[[ -n $1 ]] && { # host
host=$1
@@ -984,6 +1041,35 @@ grpc_interop_gen_python_cmd() {
echo $the_cmd
}
+# constructs the full dockerized python service_account auth interop test cmd.
+#
+# call-seq:
+# flags= .... # generic flags to include the command
+# cmd=$($grpc_gen_test_cmd $flags)
+grpc_cloud_prod_auth_service_account_creds_gen_python_cmd() {
+ local cmd_prefix="sudo docker run grpc/ruby bin/bash -l -c";
+ local gfe_flags=$(_grpc_prod_gfe_flags)
+ local added_gfe_flags=$(_grpc_default_creds_test_flags)
+ local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem"
+ env_prefix+=" GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json"
+ local the_cmd="$cmd_prefix '$env_prefix python -B -m interop.client --use_tls $gfe_flags $added_gfe_flags $@'"
+ echo $the_cmd
+}
+
+# constructs the full dockerized python gce auth interop test cmd.
+#
+# call-seq:
+# flags= .... # generic flags to include the command
+# cmd=$($grpc_gen_test_cmd $flags)
+grpc_cloud_prod_auth_compute_engine_creds_gen_python_cmd() {
+ local cmd_prefix="sudo docker run grpc/ruby bin/bash -l -c";
+ local gfe_flags=$(_grpc_prod_gfe_flags)
+ local added_gfe_flags=$(_grpc_gce_test_flags)
+ local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem"
+ local the_cmd="$cmd_prefix '$env_prefix python -B -m interop.client --use_tls $gfe_flags $added_gfe_flags $@'"
+ echo $the_cmd
+}
+
# constructs the full dockerized java interop test cmd.
#
# call-seq:
@@ -1310,5 +1396,3 @@ _grpc_default_creds_test_flags() {
_grpc_gce_test_flags() {
echo " --default_service_account=155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel@developer.gserviceaccount.com --oauth_scope=https://www.googleapis.com/auth/xapi.zoo"
}
-
-# TODO(grpc-team): add grpc_interop_gen_xxx_cmd for python
diff --git a/tools/gce_setup/interop_test_runner.sh b/tools/gce_setup/interop_test_runner.sh
index 7f0b5bab1a..1c6122e9ae 100755
--- a/tools/gce_setup/interop_test_runner.sh
+++ b/tools/gce_setup/interop_test_runner.sh
@@ -36,7 +36,7 @@ echo $result_file_name
main() {
source grpc_docker.sh
test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_begin cancel_after_first_response)
- clients=(cxx java go ruby node python csharp_mono)
+ clients=(cxx java go ruby node python csharp_mono php)
servers=(cxx java go ruby node python csharp_mono)
for test_case in "${test_cases[@]}"
do
diff --git a/tools/gce_setup/shared_startup_funcs.sh b/tools/gce_setup/shared_startup_funcs.sh
index e6eecc56db..c4a076757a 100755
--- a/tools/gce_setup/shared_startup_funcs.sh
+++ b/tools/gce_setup/shared_startup_funcs.sh
@@ -434,6 +434,12 @@ grpc_dockerfile_install() {
grpc_docker_sync_service_account $dockerfile_dir/service_account || return 1;
}
+ # For deb builds, copy the distpackages folder into the docker directory so
+ # that it can be installed using ADD distpackages distpackages.
+ [[ $image_label == "grpc/build_deb" ]] && {
+ cp -vR ~/distpackages $dockerfile_dir
+ }
+
# TODO(temiola): maybe make cache/no-cache a func option?
sudo docker build $cache_opt -t $image_label $dockerfile_dir || {
echo "$FUNCNAME:: build of $image_label <- $dockerfile_dir"
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 6b8cd1111e..14ee1790c6 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -224,6 +224,24 @@ class CSharpLanguage(object):
def __str__(self):
return 'csharp'
+class Build(object):
+
+ def test_specs(self, config, travis):
+ return []
+
+ def make_targets(self):
+ return ['all']
+
+ def build_steps(self):
+ return []
+
+ def supports_multi_config(self):
+ return True
+
+ def __str__(self):
+ return self.make_target
+
+
# different configurations we can run under
_CONFIGS = {
'dbg': SimpleConfig('dbg'),
@@ -248,7 +266,8 @@ _LANGUAGES = {
'php': PhpLanguage(),
'python': PythonLanguage(),
'ruby': RubyLanguage(),
- 'csharp': CSharpLanguage()
+ 'csharp': CSharpLanguage(),
+ 'build': Build(),
}
# parse command line
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 355d5735cd..eab07040e7 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -349,11 +349,21 @@
{
"flaky": false,
"language": "c++",
+ "name": "cli_call_test"
+ },
+ {
+ "flaky": false,
+ "language": "c++",
"name": "credentials_test"
},
{
"flaky": false,
"language": "c++",
+ "name": "cxx_time_test"
+ },
+ {
+ "flaky": false,
+ "language": "c++",
"name": "end2end_test"
},
{
diff --git a/vsprojects/vs2010/Grpc.mak b/vsprojects/vs2010/Grpc.mak
new file mode 100644
index 0000000000..203c787287
--- /dev/null
+++ b/vsprojects/vs2010/Grpc.mak
@@ -0,0 +1,712 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# NMake file to build secondary gRPC targets on Windows.
+# Use grpc.sln to solution to build the gRPC libraries.
+
+OUT_DIR=test_bin
+
+CC=cl.exe
+LINK=link.exe
+
+INCLUDES=/I..\.. /I..\..\include /I..\..\third_party\zlib /I..\third_party /I..\..\third_party\openssl\inc32
+DEFINES=/D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /D _CRT_SECURE_NO_WARNINGS
+CFLAGS=/c $(INCLUDES) /nologo /Z7 /W3 /WX- /sdl $(DEFINES) /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze-
+LFLAGS=/DEBUG /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86
+
+OPENSSL_LIBS=..\..\third_party\openssl\out32\ssleay32.lib ..\..\third_party\openssl\out32\libeay32.lib
+WINSOCK_LIBS=ws2_32.lib
+ZLIB_LIBS=Debug\zlibwapi.lib
+LIBS=$(OPENSSL_LIBS) $(WINSOCK_LIBS) $(ZLIB_LIBS)
+
+gpr_test_util:
+ MSBuild.exe gpr_test_util.vcxproj /p:Configuration=Debug
+
+grpc_test_util:
+ MSBuild.exe grpc_test_util.vcxproj /p:Configuration=Debug
+
+$(OUT_DIR):
+ mkdir $(OUT_DIR)
+
+buildtests: alarm_heap_test.exe alarm_list_test.exe alarm_test.exe alpn_test.exe bin_encoder_test.exe census_hash_table_test.exe census_statistics_multiple_writers_circular_buffer_test.exe census_statistics_multiple_writers_test.exe census_statistics_performance_test.exe census_statistics_quick_test.exe census_statistics_small_log_test.exe census_stats_store_test.exe census_stub_test.exe census_trace_store_test.exe census_window_stats_test.exe chttp2_status_conversion_test.exe chttp2_stream_encoder_test.exe chttp2_stream_map_test.exe chttp2_transport_end2end_test.exe dualstack_socket_test.exe echo_test.exe fd_posix_test.exe fling_stream_test.exe fling_test.exe gpr_cancellable_test.exe gpr_cmdline_test.exe gpr_env_test.exe gpr_file_test.exe gpr_histogram_test.exe gpr_host_port_test.exe gpr_log_test.exe gpr_slice_buffer_test.exe gpr_slice_test.exe gpr_string_test.exe gpr_sync_test.exe gpr_thd_test.exe gpr_time_test.exe gpr_useful_test.exe grpc_base64_test.exe grpc_byte_buffer_reader_test.exe grpc_channel_stack_test.exe grpc_completion_queue_test.exe grpc_credentials_test.exe grpc_json_token_test.exe grpc_stream_op_test.exe hpack_parser_test.exe hpack_table_test.exe httpcli_format_request_test.exe httpcli_parser_test.exe httpcli_test.exe json_rewrite_test.exe json_test.exe lame_client_test.exe message_compress_test.exe metadata_buffer_test.exe multi_init_test.exe murmur_hash_test.exe no_server_test.exe poll_kick_posix_test.exe resolve_address_test.exe secure_endpoint_test.exe sockaddr_utils_test.exe tcp_client_posix_test.exe tcp_posix_test.exe tcp_server_posix_test.exe time_averaged_stats_test.exe time_test.exe timeout_encoding_test.exe transport_metadata_test.exe transport_security_test.exe
+ echo All tests built.
+
+test: alarm_heap_test alarm_list_test alarm_test alpn_test bin_encoder_test census_hash_table_test census_statistics_multiple_writers_circular_buffer_test census_statistics_multiple_writers_test census_statistics_performance_test census_statistics_quick_test census_statistics_small_log_test census_stats_store_test census_stub_test census_trace_store_test census_window_stats_test chttp2_status_conversion_test chttp2_stream_encoder_test chttp2_stream_map_test chttp2_transport_end2end_test dualstack_socket_test echo_test fd_posix_test fling_stream_test fling_test gpr_cancellable_test gpr_cmdline_test gpr_env_test gpr_file_test gpr_histogram_test gpr_host_port_test gpr_log_test gpr_slice_buffer_test gpr_slice_test gpr_string_test gpr_sync_test gpr_thd_test gpr_time_test gpr_useful_test grpc_base64_test grpc_byte_buffer_reader_test grpc_channel_stack_test grpc_completion_queue_test grpc_credentials_test grpc_json_token_test grpc_stream_op_test hpack_parser_test hpack_table_test httpcli_format_request_test httpcli_parser_test httpcli_test json_rewrite_test json_test lame_client_test message_compress_test metadata_buffer_test multi_init_test murmur_hash_test no_server_test poll_kick_posix_test resolve_address_test secure_endpoint_test sockaddr_utils_test tcp_client_posix_test tcp_posix_test tcp_server_posix_test time_averaged_stats_test time_test timeout_encoding_test transport_metadata_test transport_security_test
+ echo All tests ran.
+
+test_gpr: gpr_cancellable_test gpr_cmdline_test gpr_env_test gpr_file_test gpr_histogram_test gpr_host_port_test gpr_log_test gpr_slice_buffer_test gpr_slice_test gpr_string_test gpr_sync_test gpr_thd_test gpr_time_test gpr_useful_test
+ echo All tests ran.
+
+alarm_heap_test.exe: grpc_test_util
+ echo Building alarm_heap_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\alarm_heap_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\alarm_heap_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\alarm_heap_test.obj
+alarm_heap_test: alarm_heap_test.exe
+ echo Running alarm_heap_test
+ $(OUT_DIR)\alarm_heap_test.exe
+
+alarm_list_test.exe: grpc_test_util
+ echo Building alarm_list_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\alarm_list_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\alarm_list_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\alarm_list_test.obj
+alarm_list_test: alarm_list_test.exe
+ echo Running alarm_list_test
+ $(OUT_DIR)\alarm_list_test.exe
+
+alarm_test.exe: grpc_test_util
+ echo Building alarm_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\alarm_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\alarm_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\alarm_test.obj
+alarm_test: alarm_test.exe
+ echo Running alarm_test
+ $(OUT_DIR)\alarm_test.exe
+
+alpn_test.exe: grpc_test_util
+ echo Building alpn_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\alpn_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\alpn_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\alpn_test.obj
+alpn_test: alpn_test.exe
+ echo Running alpn_test
+ $(OUT_DIR)\alpn_test.exe
+
+bin_encoder_test.exe: grpc_test_util
+ echo Building bin_encoder_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\bin_encoder_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\bin_encoder_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\bin_encoder_test.obj
+bin_encoder_test: bin_encoder_test.exe
+ echo Running bin_encoder_test
+ $(OUT_DIR)\bin_encoder_test.exe
+
+census_hash_table_test.exe: grpc_test_util
+ echo Building census_hash_table_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\hash_table_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_hash_table_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\hash_table_test.obj
+census_hash_table_test: census_hash_table_test.exe
+ echo Running census_hash_table_test
+ $(OUT_DIR)\census_hash_table_test.exe
+
+census_statistics_multiple_writers_circular_buffer_test.exe: grpc_test_util
+ echo Building census_statistics_multiple_writers_circular_buffer_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\multiple_writers_circular_buffer_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_multiple_writers_circular_buffer_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\multiple_writers_circular_buffer_test.obj
+census_statistics_multiple_writers_circular_buffer_test: census_statistics_multiple_writers_circular_buffer_test.exe
+ echo Running census_statistics_multiple_writers_circular_buffer_test
+ $(OUT_DIR)\census_statistics_multiple_writers_circular_buffer_test.exe
+
+census_statistics_multiple_writers_test.exe: grpc_test_util
+ echo Building census_statistics_multiple_writers_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\multiple_writers_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_multiple_writers_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\multiple_writers_test.obj
+census_statistics_multiple_writers_test: census_statistics_multiple_writers_test.exe
+ echo Running census_statistics_multiple_writers_test
+ $(OUT_DIR)\census_statistics_multiple_writers_test.exe
+
+census_statistics_performance_test.exe: grpc_test_util
+ echo Building census_statistics_performance_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\performance_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_performance_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\performance_test.obj
+census_statistics_performance_test: census_statistics_performance_test.exe
+ echo Running census_statistics_performance_test
+ $(OUT_DIR)\census_statistics_performance_test.exe
+
+census_statistics_quick_test.exe: grpc_test_util
+ echo Building census_statistics_quick_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\quick_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_quick_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\quick_test.obj
+census_statistics_quick_test: census_statistics_quick_test.exe
+ echo Running census_statistics_quick_test
+ $(OUT_DIR)\census_statistics_quick_test.exe
+
+census_statistics_small_log_test.exe: grpc_test_util
+ echo Building census_statistics_small_log_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\small_log_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_small_log_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\small_log_test.obj
+census_statistics_small_log_test: census_statistics_small_log_test.exe
+ echo Running census_statistics_small_log_test
+ $(OUT_DIR)\census_statistics_small_log_test.exe
+
+census_stats_store_test.exe: grpc_test_util
+ echo Building census_stats_store_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\rpc_stats_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_stats_store_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\rpc_stats_test.obj
+census_stats_store_test: census_stats_store_test.exe
+ echo Running census_stats_store_test
+ $(OUT_DIR)\census_stats_store_test.exe
+
+census_stub_test.exe: grpc_test_util
+ echo Building census_stub_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\census_stub_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_stub_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\census_stub_test.obj
+census_stub_test: census_stub_test.exe
+ echo Running census_stub_test
+ $(OUT_DIR)\census_stub_test.exe
+
+census_trace_store_test.exe: grpc_test_util
+ echo Building census_trace_store_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\trace_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_trace_store_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\trace_test.obj
+census_trace_store_test: census_trace_store_test.exe
+ echo Running census_trace_store_test
+ $(OUT_DIR)\census_trace_store_test.exe
+
+census_window_stats_test.exe: grpc_test_util
+ echo Building census_window_stats_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\window_stats_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_window_stats_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\window_stats_test.obj
+census_window_stats_test: census_window_stats_test.exe
+ echo Running census_window_stats_test
+ $(OUT_DIR)\census_window_stats_test.exe
+
+chttp2_status_conversion_test.exe: grpc_test_util
+ echo Building chttp2_status_conversion_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\status_conversion_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\chttp2_status_conversion_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\status_conversion_test.obj
+chttp2_status_conversion_test: chttp2_status_conversion_test.exe
+ echo Running chttp2_status_conversion_test
+ $(OUT_DIR)\chttp2_status_conversion_test.exe
+
+chttp2_stream_encoder_test.exe: grpc_test_util
+ echo Building chttp2_stream_encoder_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\stream_encoder_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\chttp2_stream_encoder_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\stream_encoder_test.obj
+chttp2_stream_encoder_test: chttp2_stream_encoder_test.exe
+ echo Running chttp2_stream_encoder_test
+ $(OUT_DIR)\chttp2_stream_encoder_test.exe
+
+chttp2_stream_map_test.exe: grpc_test_util
+ echo Building chttp2_stream_map_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\stream_map_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\chttp2_stream_map_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\stream_map_test.obj
+chttp2_stream_map_test: chttp2_stream_map_test.exe
+ echo Running chttp2_stream_map_test
+ $(OUT_DIR)\chttp2_stream_map_test.exe
+
+chttp2_transport_end2end_test.exe: grpc_test_util
+ echo Building chttp2_transport_end2end_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2_transport_end2end_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\chttp2_transport_end2end_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\chttp2_transport_end2end_test.obj
+chttp2_transport_end2end_test: chttp2_transport_end2end_test.exe
+ echo Running chttp2_transport_end2end_test
+ $(OUT_DIR)\chttp2_transport_end2end_test.exe
+
+dualstack_socket_test.exe: grpc_test_util
+ echo Building dualstack_socket_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\end2end\dualstack_socket_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\dualstack_socket_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\dualstack_socket_test.obj
+dualstack_socket_test: dualstack_socket_test.exe
+ echo Running dualstack_socket_test
+ $(OUT_DIR)\dualstack_socket_test.exe
+
+echo_client.exe: grpc_test_util
+ echo Building echo_client
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\echo\client.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\echo_client.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\client.obj
+echo_client: echo_client.exe
+ echo Running echo_client
+ $(OUT_DIR)\echo_client.exe
+
+echo_server.exe: grpc_test_util
+ echo Building echo_server
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\echo\server.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\echo_server.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\server.obj
+echo_server: echo_server.exe
+ echo Running echo_server
+ $(OUT_DIR)\echo_server.exe
+
+echo_test.exe: grpc_test_util
+ echo Building echo_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\echo\echo_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\echo_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\echo_test.obj
+echo_test: echo_test.exe
+ echo Running echo_test
+ $(OUT_DIR)\echo_test.exe
+
+fd_posix_test.exe: grpc_test_util
+ echo Building fd_posix_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\fd_posix_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\fd_posix_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\fd_posix_test.obj
+fd_posix_test: fd_posix_test.exe
+ echo Running fd_posix_test
+ $(OUT_DIR)\fd_posix_test.exe
+
+fling_client.exe: grpc_test_util
+ echo Building fling_client
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\fling\client.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\fling_client.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\client.obj
+fling_client: fling_client.exe
+ echo Running fling_client
+ $(OUT_DIR)\fling_client.exe
+
+fling_server.exe: grpc_test_util
+ echo Building fling_server
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\fling\server.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\fling_server.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\server.obj
+fling_server: fling_server.exe
+ echo Running fling_server
+ $(OUT_DIR)\fling_server.exe
+
+fling_stream_test.exe: grpc_test_util
+ echo Building fling_stream_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\fling\fling_stream_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\fling_stream_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\fling_stream_test.obj
+fling_stream_test: fling_stream_test.exe
+ echo Running fling_stream_test
+ $(OUT_DIR)\fling_stream_test.exe
+
+fling_test.exe: grpc_test_util
+ echo Building fling_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\fling\fling_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\fling_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\fling_test.obj
+fling_test: fling_test.exe
+ echo Running fling_test
+ $(OUT_DIR)\fling_test.exe
+
+gen_hpack_tables.exe: grpc_test_util
+ echo Building gen_hpack_tables
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\src\core\transport\chttp2\gen_hpack_tables.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gen_hpack_tables.exe" Debug\grpc_test_util.lib Debug\gpr.lib Debug\grpc.lib $(LIBS) $(OUT_DIR)\gen_hpack_tables.obj
+gen_hpack_tables: gen_hpack_tables.exe
+ echo Running gen_hpack_tables
+ $(OUT_DIR)\gen_hpack_tables.exe
+
+gpr_cancellable_test.exe: grpc_test_util
+ echo Building gpr_cancellable_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\cancellable_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_cancellable_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\cancellable_test.obj
+gpr_cancellable_test: gpr_cancellable_test.exe
+ echo Running gpr_cancellable_test
+ $(OUT_DIR)\gpr_cancellable_test.exe
+
+gpr_cmdline_test.exe: grpc_test_util
+ echo Building gpr_cmdline_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\cmdline_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_cmdline_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\cmdline_test.obj
+gpr_cmdline_test: gpr_cmdline_test.exe
+ echo Running gpr_cmdline_test
+ $(OUT_DIR)\gpr_cmdline_test.exe
+
+gpr_env_test.exe: grpc_test_util
+ echo Building gpr_env_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\env_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_env_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\env_test.obj
+gpr_env_test: gpr_env_test.exe
+ echo Running gpr_env_test
+ $(OUT_DIR)\gpr_env_test.exe
+
+gpr_file_test.exe: grpc_test_util
+ echo Building gpr_file_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\file_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_file_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\file_test.obj
+gpr_file_test: gpr_file_test.exe
+ echo Running gpr_file_test
+ $(OUT_DIR)\gpr_file_test.exe
+
+gpr_histogram_test.exe: grpc_test_util
+ echo Building gpr_histogram_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\histogram_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_histogram_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\histogram_test.obj
+gpr_histogram_test: gpr_histogram_test.exe
+ echo Running gpr_histogram_test
+ $(OUT_DIR)\gpr_histogram_test.exe
+
+gpr_host_port_test.exe: grpc_test_util
+ echo Building gpr_host_port_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\host_port_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_host_port_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\host_port_test.obj
+gpr_host_port_test: gpr_host_port_test.exe
+ echo Running gpr_host_port_test
+ $(OUT_DIR)\gpr_host_port_test.exe
+
+gpr_log_test.exe: grpc_test_util
+ echo Building gpr_log_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\log_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_log_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\log_test.obj
+gpr_log_test: gpr_log_test.exe
+ echo Running gpr_log_test
+ $(OUT_DIR)\gpr_log_test.exe
+
+gpr_slice_buffer_test.exe: grpc_test_util
+ echo Building gpr_slice_buffer_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\slice_buffer_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_slice_buffer_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\slice_buffer_test.obj
+gpr_slice_buffer_test: gpr_slice_buffer_test.exe
+ echo Running gpr_slice_buffer_test
+ $(OUT_DIR)\gpr_slice_buffer_test.exe
+
+gpr_slice_test.exe: grpc_test_util
+ echo Building gpr_slice_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\slice_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_slice_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\slice_test.obj
+gpr_slice_test: gpr_slice_test.exe
+ echo Running gpr_slice_test
+ $(OUT_DIR)\gpr_slice_test.exe
+
+gpr_string_test.exe: grpc_test_util
+ echo Building gpr_string_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\string_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_string_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\string_test.obj
+gpr_string_test: gpr_string_test.exe
+ echo Running gpr_string_test
+ $(OUT_DIR)\gpr_string_test.exe
+
+gpr_sync_test.exe: grpc_test_util
+ echo Building gpr_sync_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\sync_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_sync_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\sync_test.obj
+gpr_sync_test: gpr_sync_test.exe
+ echo Running gpr_sync_test
+ $(OUT_DIR)\gpr_sync_test.exe
+
+gpr_thd_test.exe: grpc_test_util
+ echo Building gpr_thd_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\thd_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_thd_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\thd_test.obj
+gpr_thd_test: gpr_thd_test.exe
+ echo Running gpr_thd_test
+ $(OUT_DIR)\gpr_thd_test.exe
+
+gpr_time_test.exe: grpc_test_util
+ echo Building gpr_time_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\time_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_time_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\time_test.obj
+gpr_time_test: gpr_time_test.exe
+ echo Running gpr_time_test
+ $(OUT_DIR)\gpr_time_test.exe
+
+gpr_useful_test.exe: grpc_test_util
+ echo Building gpr_useful_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\useful_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_useful_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\useful_test.obj
+gpr_useful_test: gpr_useful_test.exe
+ echo Running gpr_useful_test
+ $(OUT_DIR)\gpr_useful_test.exe
+
+grpc_base64_test.exe: grpc_test_util
+ echo Building grpc_base64_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\base64_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_base64_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\base64_test.obj
+grpc_base64_test: grpc_base64_test.exe
+ echo Running grpc_base64_test
+ $(OUT_DIR)\grpc_base64_test.exe
+
+grpc_byte_buffer_reader_test.exe: grpc_test_util
+ echo Building grpc_byte_buffer_reader_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\surface\byte_buffer_reader_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_byte_buffer_reader_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\byte_buffer_reader_test.obj
+grpc_byte_buffer_reader_test: grpc_byte_buffer_reader_test.exe
+ echo Running grpc_byte_buffer_reader_test
+ $(OUT_DIR)\grpc_byte_buffer_reader_test.exe
+
+grpc_channel_stack_test.exe: grpc_test_util
+ echo Building grpc_channel_stack_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\channel\channel_stack_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_channel_stack_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\channel_stack_test.obj
+grpc_channel_stack_test: grpc_channel_stack_test.exe
+ echo Running grpc_channel_stack_test
+ $(OUT_DIR)\grpc_channel_stack_test.exe
+
+grpc_completion_queue_benchmark.exe: grpc_test_util
+ echo Building grpc_completion_queue_benchmark
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\surface\completion_queue_benchmark.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_completion_queue_benchmark.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\completion_queue_benchmark.obj
+grpc_completion_queue_benchmark: grpc_completion_queue_benchmark.exe
+ echo Running grpc_completion_queue_benchmark
+ $(OUT_DIR)\grpc_completion_queue_benchmark.exe
+
+grpc_completion_queue_test.exe: grpc_test_util
+ echo Building grpc_completion_queue_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\surface\completion_queue_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_completion_queue_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\completion_queue_test.obj
+grpc_completion_queue_test: grpc_completion_queue_test.exe
+ echo Running grpc_completion_queue_test
+ $(OUT_DIR)\grpc_completion_queue_test.exe
+
+grpc_create_jwt.exe: grpc_test_util
+ echo Building grpc_create_jwt
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\create_jwt.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_create_jwt.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\create_jwt.obj
+grpc_create_jwt: grpc_create_jwt.exe
+ echo Running grpc_create_jwt
+ $(OUT_DIR)\grpc_create_jwt.exe
+
+grpc_credentials_test.exe: grpc_test_util
+ echo Building grpc_credentials_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\credentials_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_credentials_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\credentials_test.obj
+grpc_credentials_test: grpc_credentials_test.exe
+ echo Running grpc_credentials_test
+ $(OUT_DIR)\grpc_credentials_test.exe
+
+grpc_fetch_oauth2.exe: grpc_test_util
+ echo Building grpc_fetch_oauth2
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\fetch_oauth2.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_fetch_oauth2.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\fetch_oauth2.obj
+grpc_fetch_oauth2: grpc_fetch_oauth2.exe
+ echo Running grpc_fetch_oauth2
+ $(OUT_DIR)\grpc_fetch_oauth2.exe
+
+grpc_json_token_test.exe: grpc_test_util
+ echo Building grpc_json_token_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\json_token_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_json_token_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\json_token_test.obj
+grpc_json_token_test: grpc_json_token_test.exe
+ echo Running grpc_json_token_test
+ $(OUT_DIR)\grpc_json_token_test.exe
+
+grpc_print_google_default_creds_token.exe: grpc_test_util
+ echo Building grpc_print_google_default_creds_token
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\print_google_default_creds_token.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_print_google_default_creds_token.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\print_google_default_creds_token.obj
+grpc_print_google_default_creds_token: grpc_print_google_default_creds_token.exe
+ echo Running grpc_print_google_default_creds_token
+ $(OUT_DIR)\grpc_print_google_default_creds_token.exe
+
+grpc_stream_op_test.exe: grpc_test_util
+ echo Building grpc_stream_op_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\stream_op_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_stream_op_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\stream_op_test.obj
+grpc_stream_op_test: grpc_stream_op_test.exe
+ echo Running grpc_stream_op_test
+ $(OUT_DIR)\grpc_stream_op_test.exe
+
+hpack_parser_test.exe: grpc_test_util
+ echo Building hpack_parser_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\hpack_parser_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\hpack_parser_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\hpack_parser_test.obj
+hpack_parser_test: hpack_parser_test.exe
+ echo Running hpack_parser_test
+ $(OUT_DIR)\hpack_parser_test.exe
+
+hpack_table_test.exe: grpc_test_util
+ echo Building hpack_table_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\hpack_table_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\hpack_table_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\hpack_table_test.obj
+hpack_table_test: hpack_table_test.exe
+ echo Running hpack_table_test
+ $(OUT_DIR)\hpack_table_test.exe
+
+httpcli_format_request_test.exe: grpc_test_util
+ echo Building httpcli_format_request_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\httpcli\format_request_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\httpcli_format_request_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\format_request_test.obj
+httpcli_format_request_test: httpcli_format_request_test.exe
+ echo Running httpcli_format_request_test
+ $(OUT_DIR)\httpcli_format_request_test.exe
+
+httpcli_parser_test.exe: grpc_test_util
+ echo Building httpcli_parser_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\httpcli\parser_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\httpcli_parser_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\parser_test.obj
+httpcli_parser_test: httpcli_parser_test.exe
+ echo Running httpcli_parser_test
+ $(OUT_DIR)\httpcli_parser_test.exe
+
+httpcli_test.exe: grpc_test_util
+ echo Building httpcli_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\httpcli\httpcli_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\httpcli_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\httpcli_test.obj
+httpcli_test: httpcli_test.exe
+ echo Running httpcli_test
+ $(OUT_DIR)\httpcli_test.exe
+
+json_rewrite.exe: grpc_test_util
+ echo Building json_rewrite
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\json\json_rewrite.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\json_rewrite.exe" Debug\grpc.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\json_rewrite.obj
+json_rewrite: json_rewrite.exe
+ echo Running json_rewrite
+ $(OUT_DIR)\json_rewrite.exe
+
+json_rewrite_test.exe: grpc_test_util
+ echo Building json_rewrite_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\json\json_rewrite_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\json_rewrite_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\json_rewrite_test.obj
+json_rewrite_test: json_rewrite_test.exe
+ echo Running json_rewrite_test
+ $(OUT_DIR)\json_rewrite_test.exe
+
+json_test.exe: grpc_test_util
+ echo Building json_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\json\json_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\json_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\json_test.obj
+json_test: json_test.exe
+ echo Running json_test
+ $(OUT_DIR)\json_test.exe
+
+lame_client_test.exe: grpc_test_util
+ echo Building lame_client_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\surface\lame_client_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\lame_client_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\lame_client_test.obj
+lame_client_test: lame_client_test.exe
+ echo Running lame_client_test
+ $(OUT_DIR)\lame_client_test.exe
+
+low_level_ping_pong_benchmark.exe: grpc_test_util
+ echo Building low_level_ping_pong_benchmark
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\network_benchmarks\low_level_ping_pong.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\low_level_ping_pong_benchmark.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\low_level_ping_pong.obj
+low_level_ping_pong_benchmark: low_level_ping_pong_benchmark.exe
+ echo Running low_level_ping_pong_benchmark
+ $(OUT_DIR)\low_level_ping_pong_benchmark.exe
+
+message_compress_test.exe: grpc_test_util
+ echo Building message_compress_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\compression\message_compress_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\message_compress_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\message_compress_test.obj
+message_compress_test: message_compress_test.exe
+ echo Running message_compress_test
+ $(OUT_DIR)\message_compress_test.exe
+
+metadata_buffer_test.exe: grpc_test_util
+ echo Building metadata_buffer_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\channel\metadata_buffer_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\metadata_buffer_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\metadata_buffer_test.obj
+metadata_buffer_test: metadata_buffer_test.exe
+ echo Running metadata_buffer_test
+ $(OUT_DIR)\metadata_buffer_test.exe
+
+multi_init_test.exe: grpc_test_util
+ echo Building multi_init_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\surface\multi_init_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\multi_init_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\multi_init_test.obj
+multi_init_test: multi_init_test.exe
+ echo Running multi_init_test
+ $(OUT_DIR)\multi_init_test.exe
+
+murmur_hash_test.exe: grpc_test_util
+ echo Building murmur_hash_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\murmur_hash_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\murmur_hash_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\murmur_hash_test.obj
+murmur_hash_test: murmur_hash_test.exe
+ echo Running murmur_hash_test
+ $(OUT_DIR)\murmur_hash_test.exe
+
+no_server_test.exe: grpc_test_util
+ echo Building no_server_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\end2end\no_server_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\no_server_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\no_server_test.obj
+no_server_test: no_server_test.exe
+ echo Running no_server_test
+ $(OUT_DIR)\no_server_test.exe
+
+poll_kick_posix_test.exe: grpc_test_util
+ echo Building poll_kick_posix_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\poll_kick_posix_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\poll_kick_posix_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\poll_kick_posix_test.obj
+poll_kick_posix_test: poll_kick_posix_test.exe
+ echo Running poll_kick_posix_test
+ $(OUT_DIR)\poll_kick_posix_test.exe
+
+resolve_address_test.exe: grpc_test_util
+ echo Building resolve_address_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\resolve_address_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\resolve_address_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\resolve_address_test.obj
+resolve_address_test: resolve_address_test.exe
+ echo Running resolve_address_test
+ $(OUT_DIR)\resolve_address_test.exe
+
+secure_endpoint_test.exe: grpc_test_util
+ echo Building secure_endpoint_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\secure_endpoint_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\secure_endpoint_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\secure_endpoint_test.obj
+secure_endpoint_test: secure_endpoint_test.exe
+ echo Running secure_endpoint_test
+ $(OUT_DIR)\secure_endpoint_test.exe
+
+sockaddr_utils_test.exe: grpc_test_util
+ echo Building sockaddr_utils_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\sockaddr_utils_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\sockaddr_utils_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\sockaddr_utils_test.obj
+sockaddr_utils_test: sockaddr_utils_test.exe
+ echo Running sockaddr_utils_test
+ $(OUT_DIR)\sockaddr_utils_test.exe
+
+tcp_client_posix_test.exe: grpc_test_util
+ echo Building tcp_client_posix_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\tcp_client_posix_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\tcp_client_posix_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\tcp_client_posix_test.obj
+tcp_client_posix_test: tcp_client_posix_test.exe
+ echo Running tcp_client_posix_test
+ $(OUT_DIR)\tcp_client_posix_test.exe
+
+tcp_posix_test.exe: grpc_test_util
+ echo Building tcp_posix_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\tcp_posix_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\tcp_posix_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\tcp_posix_test.obj
+tcp_posix_test: tcp_posix_test.exe
+ echo Running tcp_posix_test
+ $(OUT_DIR)\tcp_posix_test.exe
+
+tcp_server_posix_test.exe: grpc_test_util
+ echo Building tcp_server_posix_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\tcp_server_posix_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\tcp_server_posix_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\tcp_server_posix_test.obj
+tcp_server_posix_test: tcp_server_posix_test.exe
+ echo Running tcp_server_posix_test
+ $(OUT_DIR)\tcp_server_posix_test.exe
+
+time_averaged_stats_test.exe: grpc_test_util
+ echo Building time_averaged_stats_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\time_averaged_stats_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\time_averaged_stats_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\time_averaged_stats_test.obj
+time_averaged_stats_test: time_averaged_stats_test.exe
+ echo Running time_averaged_stats_test
+ $(OUT_DIR)\time_averaged_stats_test.exe
+
+time_test.exe: grpc_test_util
+ echo Building time_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\time_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\time_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\time_test.obj
+time_test: time_test.exe
+ echo Running time_test
+ $(OUT_DIR)\time_test.exe
+
+timeout_encoding_test.exe: grpc_test_util
+ echo Building timeout_encoding_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\timeout_encoding_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\timeout_encoding_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\timeout_encoding_test.obj
+timeout_encoding_test: timeout_encoding_test.exe
+ echo Running timeout_encoding_test
+ $(OUT_DIR)\timeout_encoding_test.exe
+
+transport_metadata_test.exe: grpc_test_util
+ echo Building transport_metadata_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\metadata_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\transport_metadata_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\metadata_test.obj
+transport_metadata_test: transport_metadata_test.exe
+ echo Running transport_metadata_test
+ $(OUT_DIR)\transport_metadata_test.exe
+
+transport_security_test.exe: grpc_test_util
+ echo Building transport_security_test
+ $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\tsi\transport_security_test.c
+ $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\transport_security_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\transport_security_test.obj
+transport_security_test: transport_security_test.exe
+ echo Running transport_security_test
+ $(OUT_DIR)\transport_security_test.exe
+
diff --git a/vsprojects/vs2010/build_openssl_x86.bat b/vsprojects/vs2010/build_openssl_x86.bat
new file mode 100644
index 0000000000..9f7a01324f
--- /dev/null
+++ b/vsprojects/vs2010/build_openssl_x86.bat
@@ -0,0 +1,8 @@
+@echo Building OpenSSL 32bits using Visual Studio 2010.
+
+@call "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" x86
+
+cd ..\..\third_party\openssl
+nmake /F ..\..\vsprojects\third_party\openssl\OpenSSL.mak init out32\ssleay32.lib out32\libeay32.lib
+
+pause
diff --git a/vsprojects/vs2010/global.props b/vsprojects/vs2010/global.props
new file mode 100644
index 0000000000..ae44e18d4e
--- /dev/null
+++ b/vsprojects/vs2010/global.props
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SolutionDir)\..\..;$(SolutionDir)\..\..\include;$(SolutionDir)\..\..\third_party\zlib;$(SolutionDir)\..\third_party;$(SolutionDir)\..\..\third_party\openssl\inc32;$(SolutionDir)\..\..\third_party\protobuf\src</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/vsprojects/vs2013/gpr_shared.vcxproj b/vsprojects/vs2010/gpr.vcxproj
index 892490e324..d23124c86c 100644
--- a/vsprojects/vs2013/gpr_shared.vcxproj
+++ b/vsprojects/vs2010/gpr.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -11,20 +11,18 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}</ProjectGuid>
+ <ProjectGuid>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<IntDir>$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<IntDir>$(Configuration)\$(ProjectName)\</IntDir>
@@ -85,6 +83,7 @@
<ClInclude Include="..\..\include\grpc\support\atm_win32.h" />
<ClInclude Include="..\..\include\grpc\support\cancellable_platform.h" />
<ClInclude Include="..\..\include\grpc\support\cmdline.h" />
+ <ClInclude Include="..\..\include\grpc\support\cpu.h" />
<ClInclude Include="..\..\include\grpc\support\histogram.h" />
<ClInclude Include="..\..\include\grpc\support\host_port.h" />
<ClInclude Include="..\..\include\grpc\support\log.h" />
@@ -115,6 +114,8 @@
</ClCompile>
<ClCompile Include="..\..\src\core\support\cmdline.c">
</ClCompile>
+ <ClCompile Include="..\..\src\core\support\cpu_iphone.c">
+ </ClCompile>
<ClCompile Include="..\..\src\core\support\cpu_linux.c">
</ClCompile>
<ClCompile Include="..\..\src\core\support\cpu_posix.c">
@@ -165,6 +166,8 @@
</ClCompile>
<ClCompile Include="..\..\src\core\support\sync_win32.c">
</ClCompile>
+ <ClCompile Include="..\..\src\core\support\thd.c">
+ </ClCompile>
<ClCompile Include="..\..\src\core\support\thd_posix.c">
</ClCompile>
<ClCompile Include="..\..\src\core\support\thd_win32.c">
diff --git a/vsprojects/vs2013/gpr_shared.vcxproj.filters b/vsprojects/vs2010/gpr.vcxproj.filters
index 9b78c3a390..1f8794441b 100644
--- a/vsprojects/vs2013/gpr_shared.vcxproj.filters
+++ b/vsprojects/vs2010/gpr.vcxproj.filters
@@ -10,6 +10,9 @@
<ClCompile Include="..\..\src\core\support\cmdline.c">
<Filter>src\core\support</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\core\support\cpu_iphone.c">
+ <Filter>src\core\support</Filter>
+ </ClCompile>
<ClCompile Include="..\..\src\core\support\cpu_linux.c">
<Filter>src\core\support</Filter>
</ClCompile>
@@ -85,6 +88,9 @@
<ClCompile Include="..\..\src\core\support\sync_win32.c">
<Filter>src\core\support</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\core\support\thd.c">
+ <Filter>src\core\support</Filter>
+ </ClCompile>
<ClCompile Include="..\..\src\core\support\thd_posix.c">
<Filter>src\core\support</Filter>
</ClCompile>
@@ -123,6 +129,9 @@
<ClInclude Include="..\..\include\grpc\support\cmdline.h">
<Filter>include\grpc\support</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\grpc\support\cpu.h">
+ <Filter>include\grpc\support</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\grpc\support\histogram.h">
<Filter>include\grpc\support</Filter>
</ClInclude>
diff --git a/vsprojects/vs2010/gpr_test_util.vcxproj b/vsprojects/vs2010/gpr_test_util.vcxproj
new file mode 100644
index 0000000000..0568fcf719
--- /dev/null
+++ b/vsprojects/vs2010/gpr_test_util.vcxproj
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <IntDir>$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <IntDir>$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="global.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="global.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>gpr_test_util</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>gpr_test_util</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\test\core\util\test_config.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\test\core\util\test_config.c">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="gpr.vcxproj">
+ <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/vsprojects/vs2010/grpc++.vcxproj b/vsprojects/vs2010/grpc++.vcxproj
new file mode 100644
index 0000000000..003355eabf
--- /dev/null
+++ b/vsprojects/vs2010/grpc++.vcxproj
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <IntDir>$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <IntDir>$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="global.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="global.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>grpc++</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>grpc++</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\include\grpc++\async_generic_service.h" />
+ <ClInclude Include="..\..\include\grpc++\async_unary_call.h" />
+ <ClInclude Include="..\..\include\grpc++\byte_buffer.h" />
+ <ClInclude Include="..\..\include\grpc++\channel_arguments.h" />
+ <ClInclude Include="..\..\include\grpc++\channel_interface.h" />
+ <ClInclude Include="..\..\include\grpc++\client_context.h" />
+ <ClInclude Include="..\..\include\grpc++\completion_queue.h" />
+ <ClInclude Include="..\..\include\grpc++\config.h" />
+ <ClInclude Include="..\..\include\grpc++\create_channel.h" />
+ <ClInclude Include="..\..\include\grpc++\credentials.h" />
+ <ClInclude Include="..\..\include\grpc++\generic_stub.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\call.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\client_unary_call.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\internal_stub.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\rpc_method.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\rpc_service_method.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\service_type.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\sync.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\thd.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h" />
+ <ClInclude Include="..\..\include\grpc++\server.h" />
+ <ClInclude Include="..\..\include\grpc++\server_builder.h" />
+ <ClInclude Include="..\..\include\grpc++\server_context.h" />
+ <ClInclude Include="..\..\include\grpc++\server_credentials.h" />
+ <ClInclude Include="..\..\include\grpc++\slice.h" />
+ <ClInclude Include="..\..\include\grpc++\status.h" />
+ <ClInclude Include="..\..\include\grpc++\status_code_enum.h" />
+ <ClInclude Include="..\..\include\grpc++\stream.h" />
+ <ClInclude Include="..\..\include\grpc++\thread_pool_interface.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\cpp\client\secure_credentials.h" />
+ <ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h" />
+ <ClInclude Include="..\..\src\cpp\client\channel.h" />
+ <ClInclude Include="..\..\src\cpp\proto\proto_utils.h" />
+ <ClInclude Include="..\..\src\cpp\server\thread_pool.h" />
+ <ClInclude Include="..\..\src\cpp\util\time.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\cpp\client\secure_credentials.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\secure_server_credentials.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\channel.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\channel_arguments.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\client_context.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\client_unary_call.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\create_channel.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\credentials.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\generic_stub.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\insecure_credentials.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\internal_stub.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\common\call.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\common\completion_queue.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\common\rpc_method.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\proto\proto_utils.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\async_generic_service.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\insecure_server_credentials.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\server.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\server_builder.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\server_context.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\server_credentials.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\thread_pool.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\util\byte_buffer.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\util\slice.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\util\status.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\util\time.cc">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="gpr.vcxproj">
+ <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+ </ProjectReference>
+ <ProjectReference Include="grpc.vcxproj">
+ <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/vsprojects/vs2010/grpc++.vcxproj.filters b/vsprojects/vs2010/grpc++.vcxproj.filters
new file mode 100644
index 0000000000..6466a0fa26
--- /dev/null
+++ b/vsprojects/vs2010/grpc++.vcxproj.filters
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="..\..\src\cpp\client\secure_credentials.cc">
+ <Filter>src\cpp\client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\secure_server_credentials.cc">
+ <Filter>src\cpp\server</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\channel.cc">
+ <Filter>src\cpp\client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\channel_arguments.cc">
+ <Filter>src\cpp\client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\client_context.cc">
+ <Filter>src\cpp\client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\client_unary_call.cc">
+ <Filter>src\cpp\client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\create_channel.cc">
+ <Filter>src\cpp\client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\credentials.cc">
+ <Filter>src\cpp\client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\generic_stub.cc">
+ <Filter>src\cpp\client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\insecure_credentials.cc">
+ <Filter>src\cpp\client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\internal_stub.cc">
+ <Filter>src\cpp\client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\common\call.cc">
+ <Filter>src\cpp\common</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\common\completion_queue.cc">
+ <Filter>src\cpp\common</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\common\rpc_method.cc">
+ <Filter>src\cpp\common</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\proto\proto_utils.cc">
+ <Filter>src\cpp\proto</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\async_generic_service.cc">
+ <Filter>src\cpp\server</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\insecure_server_credentials.cc">
+ <Filter>src\cpp\server</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\server.cc">
+ <Filter>src\cpp\server</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\server_builder.cc">
+ <Filter>src\cpp\server</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\server_context.cc">
+ <Filter>src\cpp\server</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\server_credentials.cc">
+ <Filter>src\cpp\server</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\thread_pool.cc">
+ <Filter>src\cpp\server</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\util\byte_buffer.cc">
+ <Filter>src\cpp\util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\util\slice.cc">
+ <Filter>src\cpp\util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\util\status.cc">
+ <Filter>src\cpp\util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\util\time.cc">
+ <Filter>src\cpp\util</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\include\grpc++\async_generic_service.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\async_unary_call.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\byte_buffer.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\channel_arguments.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\channel_interface.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\client_context.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\completion_queue.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\config.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\create_channel.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\credentials.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\generic_stub.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\call.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\client_unary_call.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\internal_stub.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\rpc_method.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\rpc_service_method.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\service_type.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\sync.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\thd.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\server.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\server_builder.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\server_context.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\server_credentials.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\slice.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\status.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\status_code_enum.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\stream.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\thread_pool_interface.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\cpp\client\secure_credentials.h">
+ <Filter>src\cpp\client</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h">
+ <Filter>src\cpp\server</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\cpp\client\channel.h">
+ <Filter>src\cpp\client</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\cpp\proto\proto_utils.h">
+ <Filter>src\cpp\proto</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\cpp\server\thread_pool.h">
+ <Filter>src\cpp\server</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\cpp\util\time.h">
+ <Filter>src\cpp\util</Filter>
+ </ClInclude>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Filter Include="include">
+ <UniqueIdentifier>{82445414-24cd-8198-1fe1-4267c3f3df00}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="include\grpc++">
+ <UniqueIdentifier>{784a0281-f547-aeb0-9f55-b26b7de9c769}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="include\grpc++\impl">
+ <UniqueIdentifier>{0da8cd95-314f-da1b-5ce7-7791a5be1f1a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src">
+ <UniqueIdentifier>{328ff211-2886-406e-56f9-18ba1686f363}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\cpp">
+ <UniqueIdentifier>{2420a905-e4f1-a5aa-a364-6a112878a39e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\cpp\client">
+ <UniqueIdentifier>{7febf32a-d7a6-76fa-9e17-f189f591c062}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\cpp\common">
+ <UniqueIdentifier>{2336e396-7e0b-8bf9-3b09-adc6ad1f0e5b}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\cpp\proto">
+ <UniqueIdentifier>{c22e8b9b-d2eb-a2e8-0cb8-3f7e3c902a7b}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\cpp\server">
+ <UniqueIdentifier>{321b0980-74ad-e8ca-f23b-deffa5d6bb8f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\cpp\util">
+ <UniqueIdentifier>{f842537a-2bf1-1ec3-b495-7d62c64a1c06}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vs2010/grpc.sln b/vsprojects/vs2010/grpc.sln
new file mode 100644
index 0000000000..8d1f87789d
--- /dev/null
+++ b/vsprojects/vs2010/grpc.sln
@@ -0,0 +1,97 @@
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual C++ Express 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr", "gpr.vcxproj", "{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_test_util", "gpr_test_util.vcxproj", "{EAB0A629-17A9-44DB-B5FF-E91A721FE037}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc", "grpc.vcxproj", "{29D16885-7228-4C31-81ED-5F9187C7F2A9}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_test_util", "grpc_test_util.vcxproj", "{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+ {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+ {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_unsecure", "grpc_unsecure.vcxproj", "{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++", "grpc++.vcxproj", "{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+ {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_csharp_ext", "grpc_csharp_ext.vcxproj", "{D64C6D63-4458-4A88-AB38-35678384A7E4}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+ {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_csharp_ext_shared", "grpc_csharp_ext_shared.vcxproj", "{C26D04A8-37C6-44C7-B458-906C9FCE928C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "third_party\zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug|Win32.Build.0 = Debug|Win32
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release|Win32.ActiveCfg = Release|Win32
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release|Win32.Build.0 = Release|Win32
+ {EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug|Win32.ActiveCfg = Debug|Win32
+ {EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug|Win32.Build.0 = Debug|Win32
+ {EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release|Win32.ActiveCfg = Release|Win32
+ {EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release|Win32.Build.0 = Release|Win32
+ {29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug|Win32.ActiveCfg = Debug|Win32
+ {29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug|Win32.Build.0 = Debug|Win32
+ {29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|Win32.ActiveCfg = Release|Win32
+ {29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|Win32.Build.0 = Release|Win32
+ {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|Win32.Build.0 = Debug|Win32
+ {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|Win32.ActiveCfg = Release|Win32
+ {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|Win32.Build.0 = Release|Win32
+ {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|Win32.Build.0 = Debug|Win32
+ {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|Win32.ActiveCfg = Release|Win32
+ {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|Win32.Build.0 = Release|Win32
+ {C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug|Win32.Build.0 = Debug|Win32
+ {C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release|Win32.ActiveCfg = Release|Win32
+ {C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release|Win32.Build.0 = Release|Win32
+ {D64C6D63-4458-4A88-AB38-35678384A7E4}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D64C6D63-4458-4A88-AB38-35678384A7E4}.Debug|Win32.Build.0 = Debug|Win32
+ {D64C6D63-4458-4A88-AB38-35678384A7E4}.Release|Win32.ActiveCfg = Release|Win32
+ {D64C6D63-4458-4A88-AB38-35678384A7E4}.Release|Win32.Build.0 = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32
+ {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Debug|Win32.Build.0 = Debug|Win32
+ {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Release|Win32.ActiveCfg = Release|Win32
+ {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Release|Win32.Build.0 = Release|Win32
+ {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Debug|Win32.Build.0 = Debug|Win32
+ {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Release|Win32.ActiveCfg = Release|Win32
+ {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Release|Win32.Build.0 = Release|Win32
+ {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Debug|Win32.Build.0 = Debug|Win32
+ {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Release|Win32.ActiveCfg = Release|Win32
+ {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/vsprojects/vs2013/grpc_shared.vcxproj b/vsprojects/vs2010/grpc.vcxproj
index f5575dc3f1..203ca347d3 100644
--- a/vsprojects/vs2013/grpc_shared.vcxproj
+++ b/vsprojects/vs2010/grpc.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -11,20 +11,18 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}</ProjectGuid>
+ <ProjectGuid>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<IntDir>$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<IntDir>$(Configuration)\$(ProjectName)\</IntDir>
@@ -35,14 +33,10 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="global.props" />
- <Import Project="ssl.props" />
- <Import Project="winsock.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="global.props" />
- <Import Project="ssl.props" />
- <Import Project="winsock.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@@ -86,6 +80,7 @@
<ClInclude Include="..\..\include\grpc\byte_buffer.h" />
<ClInclude Include="..\..\include\grpc\byte_buffer_reader.h" />
<ClInclude Include="..\..\include\grpc\grpc.h" />
+ <ClInclude Include="..\..\include\grpc\grpc_http.h" />
<ClInclude Include="..\..\include\grpc\status.h" />
</ItemGroup>
<ItemGroup>
@@ -97,6 +92,7 @@
<ClInclude Include="..\..\src\core\security\base64.h" />
<ClInclude Include="..\..\src\core\security\credentials.h" />
<ClInclude Include="..\..\src\core\security\json_token.h" />
+ <ClInclude Include="..\..\src\core\security\secure_endpoint.h" />
<ClInclude Include="..\..\src\core\security\secure_transport_setup.h" />
<ClInclude Include="..\..\src\core\security\security_context.h" />
<ClInclude Include="..\..\src\core\tsi\fake_transport_security.h" />
@@ -167,6 +163,7 @@
<ClInclude Include="..\..\src\core\surface\init.h" />
<ClInclude Include="..\..\src\core\surface\server.h" />
<ClInclude Include="..\..\src\core\surface\surface_trace.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h" />
<ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h" />
<ClInclude Include="..\..\src\core\transport\chttp2\frame.h" />
<ClInclude Include="..\..\src\core\transport\chttp2\frame_data.h" />
@@ -359,6 +356,8 @@
</ClCompile>
<ClCompile Include="..\..\src\core\surface\call_details.c">
</ClCompile>
+ <ClCompile Include="..\..\src\core\surface\call_log_batch.c">
+ </ClCompile>
<ClCompile Include="..\..\src\core\surface\channel.c">
</ClCompile>
<ClCompile Include="..\..\src\core\surface\channel_create.c">
@@ -428,12 +427,8 @@
<ProjectReference Include="gpr.vcxproj">
<Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
</ProjectReference>
- <ProjectReference Include="third_party\zlibvc.vcxproj">
- <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
- </ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
-
diff --git a/vsprojects/vs2013/grpc_shared.vcxproj.filters b/vsprojects/vs2010/grpc.vcxproj.filters
index af38d8de35..20dbe8c444 100644
--- a/vsprojects/vs2013/grpc_shared.vcxproj.filters
+++ b/vsprojects/vs2010/grpc.vcxproj.filters
@@ -253,6 +253,9 @@
<ClCompile Include="..\..\src\core\surface\call_details.c">
<Filter>src\core\surface</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\core\surface\call_log_batch.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
<ClCompile Include="..\..\src\core\surface\channel.c">
<Filter>src\core\surface</Filter>
</ClCompile>
@@ -363,6 +366,9 @@
<ClInclude Include="..\..\include\grpc\grpc.h">
<Filter>include\grpc</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\grpc\grpc_http.h">
+ <Filter>include\grpc</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\grpc\status.h">
<Filter>include\grpc</Filter>
</ClInclude>
@@ -392,6 +398,9 @@
<ClInclude Include="..\..\src\core\security\json_token.h">
<Filter>src\core\security</Filter>
</ClInclude>
+ <ClInclude Include="..\..\src\core\security\secure_endpoint.h">
+ <Filter>src\core\security</Filter>
+ </ClInclude>
<ClInclude Include="..\..\src\core\security\secure_transport_setup.h">
<Filter>src\core\security</Filter>
</ClInclude>
@@ -602,6 +611,9 @@
<ClInclude Include="..\..\src\core\surface\surface_trace.h">
<Filter>src\core\surface</Filter>
</ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
<ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h">
<Filter>src\core\transport\chttp2</Filter>
</ClInclude>
diff --git a/vsprojects/vs2010/grpc_csharp_ext.vcxproj b/vsprojects/vs2010/grpc_csharp_ext.vcxproj
new file mode 100644
index 0000000000..a507a9b714
--- /dev/null
+++ b/vsprojects/vs2010/grpc_csharp_ext.vcxproj
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{D64C6D63-4458-4A88-AB38-35678384A7E4}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <IntDir>$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <IntDir>$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="global.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="global.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>grpc_csharp_ext</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>grpc_csharp_ext</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\csharp\ext\grpc_csharp_ext.c">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="gpr.vcxproj">
+ <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+ </ProjectReference>
+ <ProjectReference Include="grpc.vcxproj">
+ <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
+
diff --git a/vsprojects/vs2010/grpc_csharp_ext_shared.vcxproj b/vsprojects/vs2010/grpc_csharp_ext_shared.vcxproj
new file mode 100644
index 0000000000..b17f927de4
--- /dev/null
+++ b/vsprojects/vs2010/grpc_csharp_ext_shared.vcxproj
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C26D04A8-37C6-44C7-B458-906C9FCE928C}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <IntDir>$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <IntDir>$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="global.props" />
+ <Import Project="winsock.props" />
+ <Import Project="ssl.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="global.props" />
+ <Import Project="winsock.props" />
+ <Import Project="ssl.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>grpc_csharp_ext</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>grpc_csharp_ext</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\csharp\ext\grpc_csharp_ext.c">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="gpr.vcxproj">
+ <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+ </ProjectReference>
+ <ProjectReference Include="grpc.vcxproj">
+ <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
+
diff --git a/vsprojects/vs2010/grpc_test_util.vcxproj b/vsprojects/vs2010/grpc_test_util.vcxproj
new file mode 100644
index 0000000000..967543f78a
--- /dev/null
+++ b/vsprojects/vs2010/grpc_test_util.vcxproj
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <IntDir>$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <IntDir>$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="global.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="global.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>grpc_test_util</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>grpc_test_util</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\test\core\end2end\cq_verifier.c">
+ </ClCompile>
+ <ClCompile Include="..\..\test\core\end2end\data\server1_cert.c">
+ </ClCompile>
+ <ClCompile Include="..\..\test\core\end2end\data\server1_key.c">
+ </ClCompile>
+ <ClCompile Include="..\..\test\core\end2end\data\test_root_cert.c">
+ </ClCompile>
+ <ClCompile Include="..\..\test\core\iomgr\endpoint_tests.c">
+ </ClCompile>
+ <ClCompile Include="..\..\test\core\statistics\census_log_tests.c">
+ </ClCompile>
+ <ClCompile Include="..\..\test\core\transport\transport_end2end_tests.c">
+ </ClCompile>
+ <ClCompile Include="..\..\test\core\util\grpc_profiler.c">
+ </ClCompile>
+ <ClCompile Include="..\..\test\core\util\parse_hexstring.c">
+ </ClCompile>
+ <ClCompile Include="..\..\test\core\util\port_posix.c">
+ </ClCompile>
+ <ClCompile Include="..\..\test\core\util\slice_splitter.c">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="gpr.vcxproj">
+ <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+ </ProjectReference>
+ <ProjectReference Include="gpr_test_util.vcxproj">
+ <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+ </ProjectReference>
+ <ProjectReference Include="grpc.vcxproj">
+ <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/vsprojects/vs2010/grpc_unsecure.vcxproj b/vsprojects/vs2010/grpc_unsecure.vcxproj
new file mode 100644
index 0000000000..1558d72514
--- /dev/null
+++ b/vsprojects/vs2010/grpc_unsecure.vcxproj
@@ -0,0 +1,378 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <IntDir>$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <IntDir>$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="global.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="global.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>grpc_unsecure</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>grpc_unsecure</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\include\grpc\byte_buffer.h" />
+ <ClInclude Include="..\..\include\grpc\byte_buffer_reader.h" />
+ <ClInclude Include="..\..\include\grpc\grpc.h" />
+ <ClInclude Include="..\..\include\grpc\grpc_http.h" />
+ <ClInclude Include="..\..\include\grpc\status.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\core\channel\census_filter.h" />
+ <ClInclude Include="..\..\src\core\channel\channel_args.h" />
+ <ClInclude Include="..\..\src\core\channel\channel_stack.h" />
+ <ClInclude Include="..\..\src\core\channel\child_channel.h" />
+ <ClInclude Include="..\..\src\core\channel\client_channel.h" />
+ <ClInclude Include="..\..\src\core\channel\client_setup.h" />
+ <ClInclude Include="..\..\src\core\channel\connected_channel.h" />
+ <ClInclude Include="..\..\src\core\channel\http_client_filter.h" />
+ <ClInclude Include="..\..\src\core\channel\http_filter.h" />
+ <ClInclude Include="..\..\src\core\channel\http_server_filter.h" />
+ <ClInclude Include="..\..\src\core\channel\metadata_buffer.h" />
+ <ClInclude Include="..\..\src\core\channel\noop_filter.h" />
+ <ClInclude Include="..\..\src\core\compression\algorithm.h" />
+ <ClInclude Include="..\..\src\core\compression\message_compress.h" />
+ <ClInclude Include="..\..\src\core\debug\trace.h" />
+ <ClInclude Include="..\..\src\core\iomgr\alarm.h" />
+ <ClInclude Include="..\..\src\core\iomgr\alarm_heap.h" />
+ <ClInclude Include="..\..\src\core\iomgr\alarm_internal.h" />
+ <ClInclude Include="..\..\src\core\iomgr\endpoint.h" />
+ <ClInclude Include="..\..\src\core\iomgr\endpoint_pair.h" />
+ <ClInclude Include="..\..\src\core\iomgr\fd_posix.h" />
+ <ClInclude Include="..\..\src\core\iomgr\iocp_windows.h" />
+ <ClInclude Include="..\..\src\core\iomgr\iomgr.h" />
+ <ClInclude Include="..\..\src\core\iomgr\iomgr_internal.h" />
+ <ClInclude Include="..\..\src\core\iomgr\iomgr_posix.h" />
+ <ClInclude Include="..\..\src\core\iomgr\pollset.h" />
+ <ClInclude Include="..\..\src\core\iomgr\pollset_kick.h" />
+ <ClInclude Include="..\..\src\core\iomgr\pollset_kick_posix.h" />
+ <ClInclude Include="..\..\src\core\iomgr\pollset_kick_windows.h" />
+ <ClInclude Include="..\..\src\core\iomgr\pollset_posix.h" />
+ <ClInclude Include="..\..\src\core\iomgr\pollset_windows.h" />
+ <ClInclude Include="..\..\src\core\iomgr\resolve_address.h" />
+ <ClInclude Include="..\..\src\core\iomgr\sockaddr.h" />
+ <ClInclude Include="..\..\src\core\iomgr\sockaddr_posix.h" />
+ <ClInclude Include="..\..\src\core\iomgr\sockaddr_utils.h" />
+ <ClInclude Include="..\..\src\core\iomgr\sockaddr_win32.h" />
+ <ClInclude Include="..\..\src\core\iomgr\socket_utils_posix.h" />
+ <ClInclude Include="..\..\src\core\iomgr\socket_windows.h" />
+ <ClInclude Include="..\..\src\core\iomgr\tcp_client.h" />
+ <ClInclude Include="..\..\src\core\iomgr\tcp_posix.h" />
+ <ClInclude Include="..\..\src\core\iomgr\tcp_server.h" />
+ <ClInclude Include="..\..\src\core\iomgr\tcp_windows.h" />
+ <ClInclude Include="..\..\src\core\iomgr\time_averaged_stats.h" />
+ <ClInclude Include="..\..\src\core\iomgr\wakeup_fd_pipe.h" />
+ <ClInclude Include="..\..\src\core\iomgr\wakeup_fd_posix.h" />
+ <ClInclude Include="..\..\src\core\json\json.h" />
+ <ClInclude Include="..\..\src\core\json\json_common.h" />
+ <ClInclude Include="..\..\src\core\json\json_reader.h" />
+ <ClInclude Include="..\..\src\core\json\json_writer.h" />
+ <ClInclude Include="..\..\src\core\statistics\census_interface.h" />
+ <ClInclude Include="..\..\src\core\statistics\census_log.h" />
+ <ClInclude Include="..\..\src\core\statistics\census_rpc_stats.h" />
+ <ClInclude Include="..\..\src\core\statistics\census_tracing.h" />
+ <ClInclude Include="..\..\src\core\statistics\hash_table.h" />
+ <ClInclude Include="..\..\src\core\statistics\window_stats.h" />
+ <ClInclude Include="..\..\src\core\surface\byte_buffer_queue.h" />
+ <ClInclude Include="..\..\src\core\surface\call.h" />
+ <ClInclude Include="..\..\src\core\surface\channel.h" />
+ <ClInclude Include="..\..\src\core\surface\client.h" />
+ <ClInclude Include="..\..\src\core\surface\completion_queue.h" />
+ <ClInclude Include="..\..\src\core\surface\event_string.h" />
+ <ClInclude Include="..\..\src\core\surface\init.h" />
+ <ClInclude Include="..\..\src\core\surface\server.h" />
+ <ClInclude Include="..\..\src\core\surface\surface_trace.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\frame.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\frame_data.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\frame_goaway.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\frame_ping.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\frame_rst_stream.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\frame_settings.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\frame_window_update.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\hpack_parser.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\hpack_table.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\http2_errors.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\huffsyms.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\status_conversion.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\stream_encoder.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\stream_map.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\timeout_encoding.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\varint.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2_transport.h" />
+ <ClInclude Include="..\..\src\core\transport\metadata.h" />
+ <ClInclude Include="..\..\src\core\transport\stream_op.h" />
+ <ClInclude Include="..\..\src\core\transport\transport.h" />
+ <ClInclude Include="..\..\src\core\transport\transport_impl.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\core\surface\init_unsecure.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\call_op_string.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\census_filter.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\channel_args.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\channel_stack.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\child_channel.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\client_channel.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\client_setup.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\connected_channel.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\http_client_filter.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\http_filter.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\http_server_filter.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\metadata_buffer.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\noop_filter.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\compression\algorithm.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\compression\message_compress.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\debug\trace.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\alarm.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\alarm_heap.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\endpoint.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\endpoint_pair_posix.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\fd_posix.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\iocp_windows.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\iomgr.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\iomgr_posix.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\iomgr_windows.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\pollset_kick.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\pollset_multipoller_with_epoll.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\pollset_multipoller_with_poll_posix.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\pollset_posix.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\pollset_windows.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\resolve_address_posix.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\resolve_address_windows.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\sockaddr_utils.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\socket_utils_common_posix.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\socket_utils_linux.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\socket_utils_posix.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\socket_windows.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\tcp_client_posix.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\tcp_client_windows.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\tcp_posix.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\tcp_server_posix.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\tcp_server_windows.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\tcp_windows.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\time_averaged_stats.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_eventfd.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_nospecial.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_pipe.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_posix.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\json\json.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\json\json_reader.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\json\json_string.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\json\json_writer.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\statistics\census_init.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\statistics\census_log.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\statistics\census_rpc_stats.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\statistics\census_tracing.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\statistics\hash_table.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\statistics\window_stats.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\byte_buffer.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\byte_buffer_queue.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\byte_buffer_reader.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\call.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\call_details.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\call_log_batch.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\channel.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\channel_create.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\client.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\completion_queue.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\event_string.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\init.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\lame_client.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\metadata_array.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\server.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\server_chttp2.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\server_create.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\surface_trace.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\alpn.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\bin_encoder.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\frame_data.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\frame_goaway.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\frame_ping.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\frame_rst_stream.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\frame_settings.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\frame_window_update.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\hpack_parser.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\hpack_table.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\huffsyms.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\status_conversion.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\stream_encoder.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\stream_map.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\timeout_encoding.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\varint.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2_transport.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\metadata.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\stream_op.c">
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\transport.c">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="gpr.vcxproj">
+ <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/vsprojects/vs2010/grpc_unsecure.vcxproj.filters b/vsprojects/vs2010/grpc_unsecure.vcxproj.filters
new file mode 100644
index 0000000000..4b758d6113
--- /dev/null
+++ b/vsprojects/vs2010/grpc_unsecure.vcxproj.filters
@@ -0,0 +1,619 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="..\..\src\core\surface\init_unsecure.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\call_op_string.c">
+ <Filter>src\core\channel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\census_filter.c">
+ <Filter>src\core\channel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\channel_args.c">
+ <Filter>src\core\channel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\channel_stack.c">
+ <Filter>src\core\channel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\child_channel.c">
+ <Filter>src\core\channel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\client_channel.c">
+ <Filter>src\core\channel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\client_setup.c">
+ <Filter>src\core\channel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\connected_channel.c">
+ <Filter>src\core\channel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\http_client_filter.c">
+ <Filter>src\core\channel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\http_filter.c">
+ <Filter>src\core\channel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\http_server_filter.c">
+ <Filter>src\core\channel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\metadata_buffer.c">
+ <Filter>src\core\channel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\channel\noop_filter.c">
+ <Filter>src\core\channel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\compression\algorithm.c">
+ <Filter>src\core\compression</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\compression\message_compress.c">
+ <Filter>src\core\compression</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\debug\trace.c">
+ <Filter>src\core\debug</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\alarm.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\alarm_heap.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\endpoint.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\endpoint_pair_posix.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\fd_posix.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\iocp_windows.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\iomgr.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\iomgr_posix.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\iomgr_windows.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\pollset_kick.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\pollset_multipoller_with_epoll.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\pollset_multipoller_with_poll_posix.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\pollset_posix.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\pollset_windows.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\resolve_address_posix.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\resolve_address_windows.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\sockaddr_utils.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\socket_utils_common_posix.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\socket_utils_linux.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\socket_utils_posix.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\socket_windows.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\tcp_client_posix.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\tcp_client_windows.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\tcp_posix.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\tcp_server_posix.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\tcp_server_windows.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\tcp_windows.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\time_averaged_stats.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_eventfd.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_nospecial.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_pipe.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_posix.c">
+ <Filter>src\core\iomgr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\json\json.c">
+ <Filter>src\core\json</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\json\json_reader.c">
+ <Filter>src\core\json</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\json\json_string.c">
+ <Filter>src\core\json</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\json\json_writer.c">
+ <Filter>src\core\json</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\statistics\census_init.c">
+ <Filter>src\core\statistics</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\statistics\census_log.c">
+ <Filter>src\core\statistics</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\statistics\census_rpc_stats.c">
+ <Filter>src\core\statistics</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\statistics\census_tracing.c">
+ <Filter>src\core\statistics</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\statistics\hash_table.c">
+ <Filter>src\core\statistics</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\statistics\window_stats.c">
+ <Filter>src\core\statistics</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\byte_buffer.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\byte_buffer_queue.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\byte_buffer_reader.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\call.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\call_details.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\call_log_batch.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\channel.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\channel_create.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\client.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\completion_queue.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\event_string.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\init.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\lame_client.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\metadata_array.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\server.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\server_chttp2.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\server_create.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\surface\surface_trace.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\alpn.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\bin_encoder.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\frame_data.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\frame_goaway.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\frame_ping.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\frame_rst_stream.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\frame_settings.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\frame_window_update.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\hpack_parser.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\hpack_table.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\huffsyms.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\status_conversion.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\stream_encoder.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\stream_map.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\timeout_encoding.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2\varint.c">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\chttp2_transport.c">
+ <Filter>src\core\transport</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\metadata.c">
+ <Filter>src\core\transport</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\stream_op.c">
+ <Filter>src\core\transport</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\core\transport\transport.c">
+ <Filter>src\core\transport</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\include\grpc\byte_buffer.h">
+ <Filter>include\grpc</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc\byte_buffer_reader.h">
+ <Filter>include\grpc</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc\grpc.h">
+ <Filter>include\grpc</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc\grpc_http.h">
+ <Filter>include\grpc</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc\status.h">
+ <Filter>include\grpc</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\core\channel\census_filter.h">
+ <Filter>src\core\channel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\channel\channel_args.h">
+ <Filter>src\core\channel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\channel\channel_stack.h">
+ <Filter>src\core\channel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\channel\child_channel.h">
+ <Filter>src\core\channel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\channel\client_channel.h">
+ <Filter>src\core\channel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\channel\client_setup.h">
+ <Filter>src\core\channel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\channel\connected_channel.h">
+ <Filter>src\core\channel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\channel\http_client_filter.h">
+ <Filter>src\core\channel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\channel\http_filter.h">
+ <Filter>src\core\channel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\channel\http_server_filter.h">
+ <Filter>src\core\channel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\channel\metadata_buffer.h">
+ <Filter>src\core\channel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\channel\noop_filter.h">
+ <Filter>src\core\channel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\compression\algorithm.h">
+ <Filter>src\core\compression</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\compression\message_compress.h">
+ <Filter>src\core\compression</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\debug\trace.h">
+ <Filter>src\core\debug</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\alarm.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\alarm_heap.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\alarm_internal.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\endpoint.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\endpoint_pair.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\fd_posix.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\iocp_windows.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\iomgr.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\iomgr_internal.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\iomgr_posix.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\pollset.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\pollset_kick.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\pollset_kick_posix.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\pollset_kick_windows.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\pollset_posix.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\pollset_windows.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\resolve_address.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\sockaddr.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\sockaddr_posix.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\sockaddr_utils.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\sockaddr_win32.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\socket_utils_posix.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\socket_windows.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\tcp_client.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\tcp_posix.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\tcp_server.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\tcp_windows.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\time_averaged_stats.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\wakeup_fd_pipe.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\iomgr\wakeup_fd_posix.h">
+ <Filter>src\core\iomgr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\json\json.h">
+ <Filter>src\core\json</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\json\json_common.h">
+ <Filter>src\core\json</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\json\json_reader.h">
+ <Filter>src\core\json</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\json\json_writer.h">
+ <Filter>src\core\json</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\statistics\census_interface.h">
+ <Filter>src\core\statistics</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\statistics\census_log.h">
+ <Filter>src\core\statistics</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\statistics\census_rpc_stats.h">
+ <Filter>src\core\statistics</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\statistics\census_tracing.h">
+ <Filter>src\core\statistics</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\statistics\hash_table.h">
+ <Filter>src\core\statistics</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\statistics\window_stats.h">
+ <Filter>src\core\statistics</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\surface\byte_buffer_queue.h">
+ <Filter>src\core\surface</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\surface\call.h">
+ <Filter>src\core\surface</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\surface\channel.h">
+ <Filter>src\core\surface</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\surface\client.h">
+ <Filter>src\core\surface</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\surface\completion_queue.h">
+ <Filter>src\core\surface</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\surface\event_string.h">
+ <Filter>src\core\surface</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\surface\init.h">
+ <Filter>src\core\surface</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\surface\server.h">
+ <Filter>src\core\surface</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\surface\surface_trace.h">
+ <Filter>src\core\surface</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\frame.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\frame_data.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\frame_goaway.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\frame_ping.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\frame_rst_stream.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\frame_settings.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\frame_window_update.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\hpack_parser.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\hpack_table.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\http2_errors.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\huffsyms.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\status_conversion.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\stream_encoder.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\stream_map.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\timeout_encoding.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\varint.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2_transport.h">
+ <Filter>src\core\transport</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\metadata.h">
+ <Filter>src\core\transport</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\stream_op.h">
+ <Filter>src\core\transport</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\transport.h">
+ <Filter>src\core\transport</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\core\transport\transport_impl.h">
+ <Filter>src\core\transport</Filter>
+ </ClInclude>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Filter Include="include">
+ <UniqueIdentifier>{10076c7e-7c8e-8005-0c81-64454af2cbc8}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="include\grpc">
+ <UniqueIdentifier>{77b9717b-b8d8-dd5f-14bb-a3e96809a70a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src">
+ <UniqueIdentifier>{aaf326a1-c884-46ea-875a-cbbd9983e539}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\core">
+ <UniqueIdentifier>{88491077-386b-2039-d14c-0c40136b5f7a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\core\channel">
+ <UniqueIdentifier>{cc102c4b-66ff-cf4c-2288-d76327e1a183}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\core\compression">
+ <UniqueIdentifier>{2e3aca1d-223d-10a1-b282-7f9fc68ee6f5}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\core\debug">
+ <UniqueIdentifier>{6d8d5774-7291-554d-fafa-583463cd3fd9}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\core\iomgr">
+ <UniqueIdentifier>{a9df8b24-ecea-ff6d-8999-d8fa54cd70bf}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\core\json">
+ <UniqueIdentifier>{443ffc61-1bea-2477-6e54-1ddf8c139264}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\core\statistics">
+ <UniqueIdentifier>{e084164c-a069-00e3-db35-4e0b1cd6f0b7}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\core\surface">
+ <UniqueIdentifier>{6cd0127e-c24b-d43c-38f5-198db8d4322a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\core\transport">
+ <UniqueIdentifier>{6687ff98-e36e-c0b1-2756-1bc79edec406}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\core\transport\chttp2">
+ <UniqueIdentifier>{5fcd6206-f774-9ae6-4b85-305d6a723843}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vs2010/ssl.props b/vsprojects/vs2010/ssl.props
new file mode 100644
index 0000000000..283bd17817
--- /dev/null
+++ b/vsprojects/vs2010/ssl.props
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <Link>
+ <AdditionalLibraryDirectories>..\..\third_party\openssl\out32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>ssleay32.lib;libeay32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/vsprojects/vs2010/third_party/zlibvc.vcxproj b/vsprojects/vs2010/third_party/zlibvc.vcxproj
new file mode 100644
index 0000000000..749e3fcafb
--- /dev/null
+++ b/vsprojects/vs2010/third_party/zlibvc.vcxproj
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{8FD826F8-3739-44E6-8CC8-997122E53B8D}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">zlibwapi</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\third_party\zlib;..\..\..\third_party\zlib\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 /SAFESEH:NO %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\..\third_party\zlib\contrib\masmx86\match686.obj;..\..\..\third_party\zlib\contrib\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\..\third_party\zlib\contrib\masmx86
+ bld_ml32.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..\third_party\zlib;..\..\..\third_party\zlib\contrib\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\..\third_party\zlib\contrib\masmx86\match686.obj;..\..\..\third_party\zlib\contrib\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\..\third_party\zlib\contrib\masmx86
+ bld_ml32.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\third_party\zlib\adler32.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\compress.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\crc32.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\deflate.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\gzclose.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\gzlib.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\gzread.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\gzwrite.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\infback.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\inffast.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\inflate.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\inftrees.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\contrib\minizip\ioapi.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\contrib\minizip\iowin32.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\trees.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\uncompr.c" />
+ <ClCompile Include="..\..\..\third_party\zlib\contrib\minizip\unzip.c">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="..\..\..\third_party\zlib\contrib\minizip\zip.c">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="..\..\..\third_party\zlib\zutil.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\third_party\zlib\deflate.h" />
+ <ClInclude Include="..\..\..\third_party\zlib\infblock.h" />
+ <ClInclude Include="..\..\..\third_party\zlib\infcodes.h" />
+ <ClInclude Include="..\..\..\third_party\zlib\inffast.h" />
+ <ClInclude Include="..\..\..\third_party\zlib\inftrees.h" />
+ <ClInclude Include="..\..\..\third_party\zlib\infutil.h" />
+ <ClInclude Include="..\..\..\third_party\zlib\zconf.h" />
+ <ClInclude Include="..\..\..\third_party\zlib\zlib.h" />
+ <ClInclude Include="..\..\..\third_party\zlib\zutil.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/vsprojects/vs2010/winsock.props b/vsprojects/vs2010/winsock.props
new file mode 100644
index 0000000000..1e84104911
--- /dev/null
+++ b/vsprojects/vs2010/winsock.props
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <Link>
+ <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/vsprojects/vs2013/gpr.vcxproj b/vsprojects/vs2013/gpr.vcxproj
index 3d970079a4..e0fa68e035 100644
--- a/vsprojects/vs2013/gpr.vcxproj
+++ b/vsprojects/vs2013/gpr.vcxproj
@@ -85,6 +85,7 @@
<ClInclude Include="..\..\include\grpc\support\atm_win32.h" />
<ClInclude Include="..\..\include\grpc\support\cancellable_platform.h" />
<ClInclude Include="..\..\include\grpc\support\cmdline.h" />
+ <ClInclude Include="..\..\include\grpc\support\cpu.h" />
<ClInclude Include="..\..\include\grpc\support\histogram.h" />
<ClInclude Include="..\..\include\grpc\support\host_port.h" />
<ClInclude Include="..\..\include\grpc\support\log.h" />
@@ -115,6 +116,8 @@
</ClCompile>
<ClCompile Include="..\..\src\core\support\cmdline.c">
</ClCompile>
+ <ClCompile Include="..\..\src\core\support\cpu_iphone.c">
+ </ClCompile>
<ClCompile Include="..\..\src\core\support\cpu_linux.c">
</ClCompile>
<ClCompile Include="..\..\src\core\support\cpu_posix.c">
@@ -165,6 +168,8 @@
</ClCompile>
<ClCompile Include="..\..\src\core\support\sync_win32.c">
</ClCompile>
+ <ClCompile Include="..\..\src\core\support\thd.c">
+ </ClCompile>
<ClCompile Include="..\..\src\core\support\thd_posix.c">
</ClCompile>
<ClCompile Include="..\..\src\core\support\thd_win32.c">
diff --git a/vsprojects/vs2013/gpr.vcxproj.filters b/vsprojects/vs2013/gpr.vcxproj.filters
index 9b78c3a390..1f8794441b 100644
--- a/vsprojects/vs2013/gpr.vcxproj.filters
+++ b/vsprojects/vs2013/gpr.vcxproj.filters
@@ -10,6 +10,9 @@
<ClCompile Include="..\..\src\core\support\cmdline.c">
<Filter>src\core\support</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\core\support\cpu_iphone.c">
+ <Filter>src\core\support</Filter>
+ </ClCompile>
<ClCompile Include="..\..\src\core\support\cpu_linux.c">
<Filter>src\core\support</Filter>
</ClCompile>
@@ -85,6 +88,9 @@
<ClCompile Include="..\..\src\core\support\sync_win32.c">
<Filter>src\core\support</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\core\support\thd.c">
+ <Filter>src\core\support</Filter>
+ </ClCompile>
<ClCompile Include="..\..\src\core\support\thd_posix.c">
<Filter>src\core\support</Filter>
</ClCompile>
@@ -123,6 +129,9 @@
<ClInclude Include="..\..\include\grpc\support\cmdline.h">
<Filter>include\grpc\support</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\grpc\support\cpu.h">
+ <Filter>include\grpc\support</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\grpc\support\histogram.h">
<Filter>include\grpc\support</Filter>
</ClInclude>
diff --git a/vsprojects/vs2013/gpr_test_util.vcxproj b/vsprojects/vs2013/gpr_test_util.vcxproj
index 04caa7e9b1..e0608b31fc 100644
--- a/vsprojects/vs2013/gpr_test_util.vcxproj
+++ b/vsprojects/vs2013/gpr_test_util.vcxproj
@@ -78,6 +78,9 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
+ <ClInclude Include="..\..\test\core\util\test_config.h" />
+ </ItemGroup>
+ <ItemGroup>
<ClCompile Include="..\..\test\core\util\test_config.c">
</ClCompile>
</ItemGroup>
diff --git a/vsprojects/vs2013/grpc++.vcxproj b/vsprojects/vs2013/grpc++.vcxproj
index f0a623b79f..dff588166b 100644
--- a/vsprojects/vs2013/grpc++.vcxproj
+++ b/vsprojects/vs2013/grpc++.vcxproj
@@ -78,7 +78,9 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
+ <ClInclude Include="..\..\include\grpc++\async_generic_service.h" />
<ClInclude Include="..\..\include\grpc++\async_unary_call.h" />
+ <ClInclude Include="..\..\include\grpc++\byte_buffer.h" />
<ClInclude Include="..\..\include\grpc++\channel_arguments.h" />
<ClInclude Include="..\..\include\grpc++\channel_interface.h" />
<ClInclude Include="..\..\include\grpc++\client_context.h" />
@@ -86,22 +88,32 @@
<ClInclude Include="..\..\include\grpc++\config.h" />
<ClInclude Include="..\..\include\grpc++\create_channel.h" />
<ClInclude Include="..\..\include\grpc++\credentials.h" />
+ <ClInclude Include="..\..\include\grpc++\generic_stub.h" />
<ClInclude Include="..\..\include\grpc++\impl\call.h" />
<ClInclude Include="..\..\include\grpc++\impl\client_unary_call.h" />
<ClInclude Include="..\..\include\grpc++\impl\internal_stub.h" />
<ClInclude Include="..\..\include\grpc++\impl\rpc_method.h" />
<ClInclude Include="..\..\include\grpc++\impl\rpc_service_method.h" />
<ClInclude Include="..\..\include\grpc++\impl\service_type.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\sync.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\thd.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h" />
<ClInclude Include="..\..\include\grpc++\server.h" />
<ClInclude Include="..\..\include\grpc++\server_builder.h" />
<ClInclude Include="..\..\include\grpc++\server_context.h" />
<ClInclude Include="..\..\include\grpc++\server_credentials.h" />
+ <ClInclude Include="..\..\include\grpc++\slice.h" />
<ClInclude Include="..\..\include\grpc++\status.h" />
<ClInclude Include="..\..\include\grpc++\status_code_enum.h" />
<ClInclude Include="..\..\include\grpc++\stream.h" />
<ClInclude Include="..\..\include\grpc++\thread_pool_interface.h" />
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="..\..\src\cpp\client\secure_credentials.h" />
+ <ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h" />
<ClInclude Include="..\..\src\cpp\client\channel.h" />
<ClInclude Include="..\..\src\cpp\proto\proto_utils.h" />
<ClInclude Include="..\..\src\cpp\server\thread_pool.h" />
@@ -124,6 +136,8 @@
</ClCompile>
<ClCompile Include="..\..\src\cpp\client\credentials.cc">
</ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\generic_stub.cc">
+ </ClCompile>
<ClCompile Include="..\..\src\cpp\client\insecure_credentials.cc">
</ClCompile>
<ClCompile Include="..\..\src\cpp\client\internal_stub.cc">
@@ -136,6 +150,8 @@
</ClCompile>
<ClCompile Include="..\..\src\cpp\proto\proto_utils.cc">
</ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\async_generic_service.cc">
+ </ClCompile>
<ClCompile Include="..\..\src\cpp\server\insecure_server_credentials.cc">
</ClCompile>
<ClCompile Include="..\..\src\cpp\server\server.cc">
@@ -148,6 +164,10 @@
</ClCompile>
<ClCompile Include="..\..\src\cpp\server\thread_pool.cc">
</ClCompile>
+ <ClCompile Include="..\..\src\cpp\util\byte_buffer.cc">
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\util\slice.cc">
+ </ClCompile>
<ClCompile Include="..\..\src\cpp\util\status.cc">
</ClCompile>
<ClCompile Include="..\..\src\cpp\util\time.cc">
diff --git a/vsprojects/vs2013/grpc++.vcxproj.filters b/vsprojects/vs2013/grpc++.vcxproj.filters
index 34ebb170ff..6466a0fa26 100644
--- a/vsprojects/vs2013/grpc++.vcxproj.filters
+++ b/vsprojects/vs2013/grpc++.vcxproj.filters
@@ -25,6 +25,9 @@
<ClCompile Include="..\..\src\cpp\client\credentials.cc">
<Filter>src\cpp\client</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\cpp\client\generic_stub.cc">
+ <Filter>src\cpp\client</Filter>
+ </ClCompile>
<ClCompile Include="..\..\src\cpp\client\insecure_credentials.cc">
<Filter>src\cpp\client</Filter>
</ClCompile>
@@ -43,6 +46,9 @@
<ClCompile Include="..\..\src\cpp\proto\proto_utils.cc">
<Filter>src\cpp\proto</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\async_generic_service.cc">
+ <Filter>src\cpp\server</Filter>
+ </ClCompile>
<ClCompile Include="..\..\src\cpp\server\insecure_server_credentials.cc">
<Filter>src\cpp\server</Filter>
</ClCompile>
@@ -61,6 +67,12 @@
<ClCompile Include="..\..\src\cpp\server\thread_pool.cc">
<Filter>src\cpp\server</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\cpp\util\byte_buffer.cc">
+ <Filter>src\cpp\util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\cpp\util\slice.cc">
+ <Filter>src\cpp\util</Filter>
+ </ClCompile>
<ClCompile Include="..\..\src\cpp\util\status.cc">
<Filter>src\cpp\util</Filter>
</ClCompile>
@@ -69,9 +81,15 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="..\..\include\grpc++\async_generic_service.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\grpc++\async_unary_call.h">
<Filter>include\grpc++</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\grpc++\byte_buffer.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\grpc++\channel_arguments.h">
<Filter>include\grpc++</Filter>
</ClInclude>
@@ -93,6 +111,9 @@
<ClInclude Include="..\..\include\grpc++\credentials.h">
<Filter>include\grpc++</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\grpc++\generic_stub.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\grpc++\impl\call.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
@@ -111,6 +132,24 @@
<ClInclude Include="..\..\include\grpc++\impl\service_type.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\sync.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\thd.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\grpc++\server.h">
<Filter>include\grpc++</Filter>
</ClInclude>
@@ -123,6 +162,9 @@
<ClInclude Include="..\..\include\grpc++\server_credentials.h">
<Filter>include\grpc++</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\grpc++\slice.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\grpc++\status.h">
<Filter>include\grpc++</Filter>
</ClInclude>
@@ -137,6 +179,12 @@
</ClInclude>
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="..\..\src\cpp\client\secure_credentials.h">
+ <Filter>src\cpp\client</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h">
+ <Filter>src\cpp\server</Filter>
+ </ClInclude>
<ClInclude Include="..\..\src\cpp\client\channel.h">
<Filter>src\cpp\client</Filter>
</ClInclude>
diff --git a/vsprojects/vs2013/grpc.sln b/vsprojects/vs2013/grpc.sln
index a3915b3591..dfefddfbbd 100644
--- a/vsprojects/vs2013/grpc.sln
+++ b/vsprojects/vs2013/grpc.sln
@@ -18,6 +18,7 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_test_util", "grpc_test_util.vcxproj", "{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}"
ProjectSection(ProjectDependencies) = postProject
{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+ {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
EndProjectSection
EndProject
@@ -38,10 +39,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_csharp_ext", "grpc_csh
{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_shared", "gpr_shared.vcxproj", "{3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_shared", "grpc_shared.vcxproj", "{F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}"
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_csharp_ext_shared", "grpc_csharp_ext_shared.vcxproj", "{C26D04A8-37C6-44C7-B458-906C9FCE928C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "third_party\zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
diff --git a/vsprojects/vs2013/grpc.vcxproj b/vsprojects/vs2013/grpc.vcxproj
index 9d0bcb3271..a88eb34ab8 100644
--- a/vsprojects/vs2013/grpc.vcxproj
+++ b/vsprojects/vs2013/grpc.vcxproj
@@ -82,6 +82,7 @@
<ClInclude Include="..\..\include\grpc\byte_buffer.h" />
<ClInclude Include="..\..\include\grpc\byte_buffer_reader.h" />
<ClInclude Include="..\..\include\grpc\grpc.h" />
+ <ClInclude Include="..\..\include\grpc\grpc_http.h" />
<ClInclude Include="..\..\include\grpc\status.h" />
</ItemGroup>
<ItemGroup>
@@ -93,6 +94,7 @@
<ClInclude Include="..\..\src\core\security\base64.h" />
<ClInclude Include="..\..\src\core\security\credentials.h" />
<ClInclude Include="..\..\src\core\security\json_token.h" />
+ <ClInclude Include="..\..\src\core\security\secure_endpoint.h" />
<ClInclude Include="..\..\src\core\security\secure_transport_setup.h" />
<ClInclude Include="..\..\src\core\security\security_context.h" />
<ClInclude Include="..\..\src\core\tsi\fake_transport_security.h" />
@@ -163,6 +165,7 @@
<ClInclude Include="..\..\src\core\surface\init.h" />
<ClInclude Include="..\..\src\core\surface\server.h" />
<ClInclude Include="..\..\src\core\surface\surface_trace.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h" />
<ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h" />
<ClInclude Include="..\..\src\core\transport\chttp2\frame.h" />
<ClInclude Include="..\..\src\core\transport\chttp2\frame_data.h" />
@@ -355,6 +358,8 @@
</ClCompile>
<ClCompile Include="..\..\src\core\surface\call_details.c">
</ClCompile>
+ <ClCompile Include="..\..\src\core\surface\call_log_batch.c">
+ </ClCompile>
<ClCompile Include="..\..\src\core\surface\channel.c">
</ClCompile>
<ClCompile Include="..\..\src\core\surface\channel_create.c">
diff --git a/vsprojects/vs2013/grpc.vcxproj.filters b/vsprojects/vs2013/grpc.vcxproj.filters
index af38d8de35..20dbe8c444 100644
--- a/vsprojects/vs2013/grpc.vcxproj.filters
+++ b/vsprojects/vs2013/grpc.vcxproj.filters
@@ -253,6 +253,9 @@
<ClCompile Include="..\..\src\core\surface\call_details.c">
<Filter>src\core\surface</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\core\surface\call_log_batch.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
<ClCompile Include="..\..\src\core\surface\channel.c">
<Filter>src\core\surface</Filter>
</ClCompile>
@@ -363,6 +366,9 @@
<ClInclude Include="..\..\include\grpc\grpc.h">
<Filter>include\grpc</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\grpc\grpc_http.h">
+ <Filter>include\grpc</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\grpc\status.h">
<Filter>include\grpc</Filter>
</ClInclude>
@@ -392,6 +398,9 @@
<ClInclude Include="..\..\src\core\security\json_token.h">
<Filter>src\core\security</Filter>
</ClInclude>
+ <ClInclude Include="..\..\src\core\security\secure_endpoint.h">
+ <Filter>src\core\security</Filter>
+ </ClInclude>
<ClInclude Include="..\..\src\core\security\secure_transport_setup.h">
<Filter>src\core\security</Filter>
</ClInclude>
@@ -602,6 +611,9 @@
<ClInclude Include="..\..\src\core\surface\surface_trace.h">
<Filter>src\core\surface</Filter>
</ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
<ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h">
<Filter>src\core\transport\chttp2</Filter>
</ClInclude>
diff --git a/vsprojects/vs2013/grpc_test_util.vcxproj b/vsprojects/vs2013/grpc_test_util.vcxproj
index 7269671bd3..4756f53928 100644
--- a/vsprojects/vs2013/grpc_test_util.vcxproj
+++ b/vsprojects/vs2013/grpc_test_util.vcxproj
@@ -105,6 +105,9 @@
<ProjectReference Include="gpr.vcxproj">
<Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
</ProjectReference>
+ <ProjectReference Include="gpr_test_util.vcxproj">
+ <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+ </ProjectReference>
<ProjectReference Include="grpc.vcxproj">
<Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
</ProjectReference>
diff --git a/vsprojects/vs2013/grpc_unsecure.vcxproj b/vsprojects/vs2013/grpc_unsecure.vcxproj
index ad7bf4762f..98c14c2fdb 100644
--- a/vsprojects/vs2013/grpc_unsecure.vcxproj
+++ b/vsprojects/vs2013/grpc_unsecure.vcxproj
@@ -81,6 +81,7 @@
<ClInclude Include="..\..\include\grpc\byte_buffer.h" />
<ClInclude Include="..\..\include\grpc\byte_buffer_reader.h" />
<ClInclude Include="..\..\include\grpc\grpc.h" />
+ <ClInclude Include="..\..\include\grpc\grpc_http.h" />
<ClInclude Include="..\..\include\grpc\status.h" />
</ItemGroup>
<ItemGroup>
@@ -148,6 +149,7 @@
<ClInclude Include="..\..\src\core\surface\init.h" />
<ClInclude Include="..\..\src\core\surface\server.h" />
<ClInclude Include="..\..\src\core\surface\surface_trace.h" />
+ <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h" />
<ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h" />
<ClInclude Include="..\..\src\core\transport\chttp2\frame.h" />
<ClInclude Include="..\..\src\core\transport\chttp2\frame_data.h" />
@@ -300,6 +302,8 @@
</ClCompile>
<ClCompile Include="..\..\src\core\surface\call_details.c">
</ClCompile>
+ <ClCompile Include="..\..\src\core\surface\call_log_batch.c">
+ </ClCompile>
<ClCompile Include="..\..\src\core\surface\channel.c">
</ClCompile>
<ClCompile Include="..\..\src\core\surface\channel_create.c">
diff --git a/vsprojects/vs2013/grpc_unsecure.vcxproj.filters b/vsprojects/vs2013/grpc_unsecure.vcxproj.filters
index 205942a450..4b758d6113 100644
--- a/vsprojects/vs2013/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vs2013/grpc_unsecure.vcxproj.filters
@@ -193,6 +193,9 @@
<ClCompile Include="..\..\src\core\surface\call_details.c">
<Filter>src\core\surface</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\core\surface\call_log_batch.c">
+ <Filter>src\core\surface</Filter>
+ </ClCompile>
<ClCompile Include="..\..\src\core\surface\channel.c">
<Filter>src\core\surface</Filter>
</ClCompile>
@@ -300,6 +303,9 @@
<ClInclude Include="..\..\include\grpc\grpc.h">
<Filter>include\grpc</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\grpc\grpc_http.h">
+ <Filter>include\grpc</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\grpc\status.h">
<Filter>include\grpc</Filter>
</ClInclude>
@@ -497,6 +503,9 @@
<ClInclude Include="..\..\src\core\surface\surface_trace.h">
<Filter>src\core\surface</Filter>
</ClInclude>
+ <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h">
+ <Filter>src\core\transport\chttp2</Filter>
+ </ClInclude>
<ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h">
<Filter>src\core\transport\chttp2</Filter>
</ClInclude>