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

Conflicts:
	templates/vsprojects/vs2013/grpc.sln.template
pull/40/head
Nicolas "Pixel" Noble 10 years ago
commit b049ba8fc4
  1. 62
      .clang-format
  2. 22
      .gitignore
  3. 149
      INSTALL
  4. 5813
      Makefile
  5. 1043
      build.json
  6. 60
      examples/tips/client.cc
  7. 36
      examples/tips/client.h
  8. 73
      examples/tips/client_main.cc
  9. 106
      examples/tips/client_test.cc
  10. 13
      examples/tips/empty.proto
  11. 48
      examples/tips/label.proto
  12. 702
      examples/tips/pubsub.proto
  13. 8
      include/grpc++/server_credentials.h
  14. 30
      include/grpc/grpc.h
  15. 56
      include/grpc/grpc_security.h
  16. 2
      include/grpc/support/slice.h
  17. 73
      src/compiler/cpp_generator.cc
  18. 10
      src/compiler/cpp_generator.h
  19. 27
      src/compiler/cpp_generator_helpers.h
  20. 20
      src/compiler/cpp_plugin.cc
  21. 35
      src/compiler/ruby_generator.cc
  22. 4
      src/compiler/ruby_generator.h
  23. 8
      src/compiler/ruby_generator_helpers-inl.h
  24. 9
      src/compiler/ruby_generator_map-inl.h
  25. 39
      src/compiler/ruby_generator_string-inl.h
  26. 15
      src/compiler/ruby_plugin.cc
  27. 12
      src/core/channel/census_filter.c
  28. 11
      src/core/channel/channel_stack.c
  29. 4
      src/core/channel/child_channel.c
  30. 2
      src/core/channel/child_channel.h
  31. 4
      src/core/channel/client_channel.c
  32. 6
      src/core/channel/connected_channel.c
  33. 4
      src/core/channel/http_client_filter.c
  34. 4
      src/core/channel/http_filter.c
  35. 4
      src/core/channel/http_server_filter.c
  36. 2
      src/core/channel/metadata_buffer.c
  37. 4
      src/core/channel/noop_filter.c
  38. 4
      src/core/iomgr/alarm.c
  39. 6
      src/core/iomgr/alarm_internal.h
  40. 10
      src/core/iomgr/iomgr.c
  41. 4
      src/core/iomgr/iomgr.h
  42. 8
      src/core/iomgr/iomgr_internal.h
  43. 4
      src/core/iomgr/iomgr_posix.c
  44. 4
      src/core/iomgr/iomgr_posix.h
  45. 68
      src/core/iomgr/pollset_kick.h
  46. 177
      src/core/iomgr/pollset_kick_posix.c
  47. 47
      src/core/iomgr/pollset_kick_posix.h
  48. 9
      src/core/iomgr/pollset_multipoller_with_poll_posix.c
  49. 90
      src/core/iomgr/pollset_posix.c
  50. 5
      src/core/iomgr/pollset_posix.h
  51. 8
      src/core/iomgr/socket_utils_common_posix.c
  52. 18
      src/core/iomgr/socket_utils_posix.c
  53. 2
      src/core/iomgr/socket_utils_posix.h
  54. 2
      src/core/iomgr/tcp_server.h
  55. 8
      src/core/iomgr/tcp_server_posix.c
  56. 5
      src/core/security/auth.c
  57. 117
      src/core/security/credentials.c
  58. 13
      src/core/security/credentials.h
  59. 12
      src/core/security/secure_endpoint.c
  60. 4
      src/core/security/secure_transport_setup.c
  61. 13
      src/core/security/security_context.c
  62. 2
      src/core/security/security_context.h
  63. 16
      src/core/security/server_secure_chttp2.c
  64. 4
      src/core/statistics/census_init.c
  65. 6
      src/core/statistics/census_interface.h
  66. 10
      src/core/statistics/census_log.c
  67. 8
      src/core/statistics/census_log.h
  68. 15
      src/core/statistics/census_rpc_stats.c
  69. 6
      src/core/statistics/census_rpc_stats.h
  70. 19
      src/core/statistics/census_tracing.c
  71. 8
      src/core/statistics/census_tracing.h
  72. 4
      src/core/support/cpu.h
  73. 4
      src/core/support/cpu_linux.c
  74. 4
      src/core/support/cpu_posix.c
  75. 2
      src/core/support/log_linux.c
  76. 2
      src/core/support/log_posix.c
  77. 8
      src/core/support/murmur_hash.c
  78. 2
      src/core/support/slice.c
  79. 2
      src/core/support/string.c
  80. 2
      src/core/support/time_posix.c
  81. 22
      src/core/surface/call.c
  82. 2
      src/core/surface/channel.c
  83. 4
      src/core/surface/client.c
  84. 11
      src/core/surface/completion_queue.c
  85. 2
      src/core/surface/completion_queue.h
  86. 3
      src/core/surface/event_string.c
  87. 4
      src/core/surface/init.c
  88. 4
      src/core/surface/lame_client.c
  89. 29
      src/core/surface/server.c
  90. 2
      src/core/transport/chttp2/alpn.c
  91. 2
      src/core/transport/chttp2/alpn.h
  92. 2
      src/core/transport/chttp2/frame_settings.c
  93. 2
      src/core/transport/chttp2/frame_settings.h
  94. 14
      src/core/transport/chttp2/gen_hpack_tables.c
  95. 124
      src/core/transport/chttp2/hpack_table.c
  96. 20
      src/core/transport/chttp2/varint.h
  97. 15
      src/core/transport/chttp2_transport.c
  98. 2
      src/core/transport/metadata.c
  99. 2
      src/core/transport/metadata.h
  100. 74
      src/core/tsi/fake_transport_security.c
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,65 +1,5 @@
---
Language: Cpp
# BasedOnStyle: Google
AccessModifierOffset: -1
AlignAfterOpenBracket: true
AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AlwaysBreakAfterDefinitionReturnType: false
AlwaysBreakTemplateDeclarations: true
AlwaysBreakBeforeMultilineStrings: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: true
BinPackArguments: true
ColumnLimit: 80
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
DerivePointerAlignment: true
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: true
IndentWrappedFunctionNames: false
IndentFunctionDeclarationAfterType: false
MaxEmptyLinesToKeep: 1
KeepEmptyLinesAtTheStartOfBlocks: false
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
SpacesBeforeTrailingComments: 2
Cpp11BracedListStyle: true
Standard: Auto
IndentWidth: 2
TabWidth: 8
UseTab: Never
BreakBeforeBraces: Attach
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpaceAfterCStyleCast: false
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
CommentPragmas: '^ IWYU pragma:'
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
SpaceBeforeParens: ControlStatements
DisableFormat: false
BasedOnStyle: Google
...

22
.gitignore vendored

@ -1,8 +1,24 @@
# C/C++ build outputs
bins
coverage
deps
*.gcno
gens
libs
objs
# Python virtual environment (pre-3.4 only)
python2.7_virtual_environment
# gcov coverage data
coverage
*.gcno
# profiler output
*.prof
# python compiled objects
*.pyc
# cache for run_tests.py
.run_tests_cache
# emacs temp files
*~

@ -1,83 +1,142 @@
Dependencies
============
These instructions only cover building grpc C and C++ libraries under
typical unix systems. If you need more information, please try grpc's
wiki pages:
grpc has few external dependencies. If needed, they are present in the
third_party directory, if you have cloned the github repository recursively.
If you didn't clone recursively, you can still get them later by running the
following command:
https://github.com/google/grpc/wiki
$ git submodule update --init
Note that the Makefile makes it much easier for you to compile from sources
if you were to clone recursively our git repository.
*************************
* If you are in a hurry *
*************************
A typical unix installation won't require any more steps than running:
grpc core currently depends on zlib and OpenSSL 1.0.2beta3.
$ make
# make install
grpc++'s tests depends on protobuf 3.0.0, gtests and gflags.
You don't need anything else than GNU Make and gcc. Under a Debian or
Ubuntu system, this should boil down to the following package:
OpenSSL
-------
# apt-get install build-essential python-all-dev python-virtualenv
Secure HTTP2 requires to have the TLS extension ALPN (see rfc 7301 and
http://http2.github.io/http2-spec/ section 3.3). Our HTTP2 implementation
relies on OpenSSL's implementation. OpenSSL 1.0.2beta3 is the first version
of OpenSSL that has ALPN support, and this explains our dependency on it.
Note that the Makefile supports compiling only the unsecure elements of grpc,
and if you do not have OpenSSL and do not want it, you can still proceed
with installing only the elements you require. However, it is recommended
to encrypt your network traffic, therefore we urge you to not use the unsecure
version of grpc if possible.
*******************************
* More detailled instructions *
*******************************
Setting up dependencies
=======================
Compiling
=========
Dependencies to compile the libraries
-------------------------------------
If you have all the dependencies in the third_party subfolder, you should
simply be able to go ahead and run "make" to compile grpc. The other targets
that you might find interesting are "buildtests" and "test".
grpc libraries have few external dependencies. If you need to compile and
install them, they are present in the third_party directory if you have
cloned the github repository recursively. If you didn't clone recursively,
you can still get them later by running the following command:
If you didn't clone from git, and thus are unable to get the required
dependencies, you can manually download and unpack the necessary packages,
and let the Makefile build them itself.
$ git submodule update --init
You may also install the dependencies yourself, from the sources, or from
your distribution's package manager.
Note that the Makefile makes it much easier for you to compile from sources
if you were to clone recursively our git repository: it will automatically
compile zlib and OpenSSL, which are core requirements for grpc. Note this
creates grpc libraries that will have zlib and OpenSSL built-in inside of them,
which significantly increases the libraries' size.
In order to decrease that size, you can manually install zlib and OpenSSL on
your system, so that the Makefile can use them instead.
Under a Debian or Ubuntu system, one can acquire the development package
for zlib this way:
The only development package needed for grpc is zlib.
The development packages needed for grpc++'s tests are gtests, and gflags.
# apt-get install zlib1g-dev
To the best of our knowledge, no distribution has an OpenSSL package that
supports ALPN yet, so you would still have to depend on installing from source
for that particular dependency.
for that particular dependency if you want to reduce the libraries' size.
The recommended version of OpenSSL that provides ALPN support is available
at this URL:
https://www.openssl.org/source/openssl-1.0.2-beta3.tar.gz
If you want to let the Makefile build them automatically for you, please
extract them in the third_party folder. You will need to rename the extracted
folder the following way:
openssl-1.0.2-beta3 --> openssl
Dependencies to compile and run the tests
-----------------------------------------
Compiling and running grpc plain-C tests dont't require any more dependency.
Compiling and running grpc C++ tests depend on protobuf 3.0.0, gtest and
gflags. Although gflags and protobuf are provided in third_party, you will
need to manually install these dependencies on your system to run these tests.
Under a Debian or Ubuntu system, you can install the gtests and gflags packages
using apt-get:
# apt-get install libgflags-dev libgtest-dev
However, protobuf 3.0.0 isn't in a debian package yet: you'll need to compile
and install it from the sources in the third_party. Note that if you already
have the protobuf and protoc packages installed on your system, they will most
likely interfere, and you'll need to uninstall them first.
Compiling and installing protobuf 3.0.0 requires a few more dependencies in
itself, notably the autoconf suite, curl, and unzip. If you have apt-get, you
can install these dependencies this way:
# apt-get install unzip curl autotools-dev
Then, you can build and install protobuf 3.0.0:
$ cd third_party/protobuf
$ ./configure
$ make
# make install
# ldconfig
A word on OpenSSL
-----------------
Secure HTTP2 requires to have the TLS extension ALPN (see rfc 7301 and
http://http2.github.io/http2-spec/ section 3.3). Our HTTP2 implementation
relies on OpenSSL's implementation. OpenSSL 1.0.2beta3 is the first version
of OpenSSL that has ALPN support, and this explains our dependency on it.
Note that the Makefile supports compiling only the unsecure elements of grpc,
and if you do not have OpenSSL and do not want it, you can still proceed
with installing only the elements you require. However, it is recommended
to encrypt your network traffic, therefore we urge you to not use the unsecure
version of grpc if possible.
Compiling
=========
If you have all the dependencies mentioned above, you should simply be able
to go ahead and run "make" to compile grpc's C and C++ libraries:
$ make
Testing
=======
At the moment, C++ tests aren't fully available yet. If you want to run tests
on the C core of grpc, you can do the following:
To build and run the tests, you can run the command:
$ make test
If you want to be able to run them in parallel, and get better output, you can
also use the python tool we have written:
$ make buildtests_c
$ make test_c
$ ./tools/run_tests/run_tests.py
Installing
==========
Once everything is compiled, you should be able to install grpc and grpc++
Once everything is compiled, you should be able to install grpc C and C++
libraries and headers:
$ sudo make install
# make install

5813
Makefile

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -0,0 +1,60 @@
/*
*
* Copyright 2014, 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++/client_context.h>
#include "examples/tips/client.h"
using tech::pubsub::Topic;
using tech::pubsub::PublisherService;
namespace grpc {
namespace examples {
namespace tips {
Client::Client(std::shared_ptr<ChannelInterface> channel)
: stub_(PublisherService::NewStub(channel)) {
}
Status Client::CreateTopic(grpc::string topic) {
Topic request;
Topic response;
request.set_name(topic);
ClientContext context;
return stub_->CreateTopic(&context, request, &response);
}
} // namespace tips
} // namespace examples
} // namespace grpc

@ -31,22 +31,24 @@
*
*/
var net = require('net');
#include <grpc++/channel_interface.h>
#include <grpc++/status.h>
/**
* Finds a free port that a server can bind to, in the format
* "address:port"
* @param {function(string)} cb The callback that should execute when the port
* is available
*/
function nextAvailablePort(cb) {
var server = net.createServer();
server.listen(function() {
var address = server.address();
server.close(function() {
cb(address.address + ':' + address.port.toString());
});
});
}
#include "examples/tips/pubsub.pb.h"
namespace grpc {
namespace examples {
namespace tips {
class Client {
public:
Client(std::shared_ptr<grpc::ChannelInterface> channel);
Status CreateTopic(grpc::string topic);
private:
std::unique_ptr<tech::pubsub::PublisherService::Stub> stub_;
};
exports.nextAvailablePort = nextAvailablePort;
} // namespace tips
} // namespace examples
} // namespace grpc

@ -0,0 +1,73 @@
/*
*
* Copyright 2014, 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/grpc.h>
#include <grpc/support/log.h>
#include <google/gflags.h>
#include <grpc++/channel_interface.h>
#include <grpc++/create_channel.h>
#include <grpc++/status.h>
#include "examples/tips/client.h"
#include "test/cpp/util/create_test_channel.h"
DEFINE_bool(enable_ssl, true, "Whether to use ssl/tls.");
DEFINE_bool(use_prod_roots, true, "True to use SSL roots for production GFE");
DEFINE_int32(server_port, 0, "Server port.");
DEFINE_string(server_host, "127.0.0.1", "Server host to connect to");
DEFINE_string(server_host_override, "foo.test.google.com",
"Override the server host which is sent in HTTP header");
int main(int argc, char** argv) {
grpc_init();
google::ParseCommandLineFlags(&argc, &argv, true);
gpr_log(GPR_INFO, "Start TIPS client");
GPR_ASSERT(FLAGS_server_port);
const int host_port_buf_size = 1024;
char host_port[host_port_buf_size];
snprintf(host_port, host_port_buf_size, "%s:%d", FLAGS_server_host.c_str(),
FLAGS_server_port);
std::shared_ptr<grpc::ChannelInterface> channel(
grpc::CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots));
grpc::examples::tips::Client client(channel);
grpc::Status s = client.CreateTopic("test");
GPR_ASSERT(s.IsOk());
channel.reset();
grpc_shutdown();
return 0;
}

@ -0,0 +1,106 @@
/*
*
* Copyright 2014, 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++/channel_arguments.h>
#include <grpc++/channel_interface.h>
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
#include <grpc++/status.h>
#include <gtest/gtest.h>
#include "examples/tips/client.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
using grpc::ChannelInterface;
namespace grpc {
namespace testing {
namespace {
const char kTopic[] = "test topic";
class PublishServiceImpl : public tech::pubsub::PublisherService::Service {
public:
Status CreateTopic(::grpc::ServerContext* context,
const ::tech::pubsub::Topic* request,
::tech::pubsub::Topic* response) override {
EXPECT_EQ(request->name(), kTopic);
return Status::OK;
}
};
class End2endTest : public ::testing::Test {
protected:
void SetUp() override {
int port = grpc_pick_unused_port_or_die();
server_address_ << "localhost:" << port;
// Setup server
ServerBuilder builder;
builder.AddPort(server_address_.str());
builder.RegisterService(service_.service());
server_ = builder.BuildAndStart();
channel_ = CreateChannel(server_address_.str(), ChannelArguments());
}
void TearDown() override { server_->Shutdown(); }
std::unique_ptr<Server> server_;
std::ostringstream server_address_;
PublishServiceImpl service_;
std::shared_ptr<ChannelInterface> channel_;
};
TEST_F(End2endTest, CreateTopic) {
grpc::examples::tips::Client client(channel_);
client.CreateTopic(kTopic);
}
} // namespace
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
grpc_test_init(argc, argv);
grpc_init();
::testing::InitGoogleTest(&argc, argv);
gpr_log(GPR_INFO, "Start test ...");
int result = RUN_ALL_TESTS();
grpc_shutdown();
return result;
}

@ -0,0 +1,13 @@
syntax = "proto2";
package proto2;
// 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 (proto2.Empty) returns (proto2.Empty) { };
// };
//
message Empty {}

@ -0,0 +1,48 @@
// Labels provide a way to associate user-defined metadata with various
// objects. Labels may be used to organize objects into non-hierarchical
// groups; think metadata tags attached to mp3s.
syntax = "proto2";
package tech.label;
// A key-value pair applied to a given object.
message Label {
// The key of a label is a syntactically valid URL (as per RFC 1738) with
// the "scheme" and initial slashes omitted and with the additional
// restrictions noted below. Each key should be globally unique. The
// "host" portion is called the "namespace" and is not necessarily
// resolvable to a network endpoint. Instead, the namespace indicates what
// system or entity defines the semantics of the label. Namespaces do not
// restrict the set of objects to which a label may be associated.
//
// Keys are defined by the following grammar:
//
// key = hostname "/" kpath
// kpath = ksegment *[ "/" ksegment ]
// ksegment = alphadigit | *[ alphadigit | "-" | "_" | "." ]
//
// where "hostname" and "alphadigit" are defined as in RFC 1738.
//
// Example key:
// spanner.google.com/universe
required string key = 1;
// The value of the label.
oneof value {
// A string value.
string str_value = 2;
// An integer value.
int64 num_value = 3;
}
}
// A collection of labels, such as the set of all labels attached to an
// object. Each label in the set must have a different key.
//
// Users should prefer to embed "repeated Label" directly when possible.
// This message should only be used in cases where that isn't possible (e.g.
// with oneof).
message Labels {
repeated Label label = 1;
}

@ -0,0 +1,702 @@
// Specification of the Pubsub API.
syntax = "proto2";
import "examples/tips/empty.proto";
import "examples/tips/label.proto";
package tech.pubsub;
// -----------------------------------------------------------------------------
// Overview of the Pubsub API
// -----------------------------------------------------------------------------
// This file describes an API for a Pubsub system. This system provides a
// reliable many-to-many communication mechanism between independently written
// publishers and subscribers where the publisher publishes messages to "topics"
// and each subscriber creates a "subscription" and consumes messages from it.
//
// (a) The pubsub system maintains bindings between topics and subscriptions.
// (b) A publisher publishes messages into a topic.
// (c) The pubsub system delivers messages from topics into relevant
// subscriptions.
// (d) A subscriber receives pending messages from its subscription and
// acknowledges or nacks each one to the pubsub system.
// (e) The pubsub system removes acknowledged messages from that subscription.
// -----------------------------------------------------------------------------
// Data Model
// -----------------------------------------------------------------------------
// The data model consists of the following:
//
// * Topic: A topic is a resource to which messages are published by publishers.
// Topics are named, and the name of the topic is unique within the pubsub
// system.
//
// * Subscription: A subscription records the subscriber's interest in a topic.
// It can optionally include a query to select a subset of interesting
// messages. The pubsub system maintains a logical cursor tracking the
// matching messages which still need to be delivered and acked so that
// they can retried as needed. The set of messages that have not been
// acknowledged is called the subscription backlog.
//
// * Message: A message is a unit of data that flows in the system. It contains
// opaque data from the publisher along with its labels.
//
// * Message Labels (optional): A set of opaque key, value pairs assigned
// by the publisher which the subscriber can use for filtering out messages
// in the topic. For example, a label with key "foo.com/device_type" and
// value "mobile" may be added for messages that are only relevant for a
// mobile subscriber; a subscriber on a phone may decide to create a
// subscription only for messages that have this label.
// -----------------------------------------------------------------------------
// Publisher Flow
// -----------------------------------------------------------------------------
// A publisher publishes messages to the topic using the Publish request:
//
// PubsubMessage message;
// message.set_data("....");
// Label label;
// label.set_key("foo.com/key1");
// label.set_str_value("value1");
// message.add_label(label);
// PublishRequest request;
// request.set_topic("topicName");
// request.set_message(message);
// PublisherService.Publish(request);
// -----------------------------------------------------------------------------
// Subscriber Flow
// -----------------------------------------------------------------------------
// The subscriber part of the API is richer than the publisher part and has a
// number of concepts w.r.t. subscription creation and monitoring:
//
// (1) A subscriber creates a subscription using the CreateSubscription call.
// It may specify an optional "query" to indicate that it wants to receive
// only messages with a certain set of labels using the label query syntax.
// It may also specify an optional truncation policy to indicate when old
// messages from the subcription can be removed.
//
// (2) A subscriber receives messages in one of two ways: via push or pull.
//
// (a) To receive messages via push, the PushConfig field must be specified in
// the Subscription parameter when creating a subscription. The PushConfig
// specifies an endpoint at which the subscriber must expose the
// PushEndpointService. Messages are received via the HandlePubsubEvent
// method. The push subscriber responds to the HandlePubsubEvent method
// with a result code that indicates one of three things: Ack (the message
// has been successfully processed and the Pubsub system may delete it),
// Nack (the message has been rejected, the Pubsub system should resend it
// at a later time), or Push-Back (this is a Nack with the additional
// semantics that the subscriber is overloaded and the pubsub system should
// back off on the rate at which it is invoking HandlePubsubEvent). The
// endpoint may be a load balancer for better scalability.
//
// (b) To receive messages via pull a subscriber calls the Pull method on the
// SubscriberService to get messages from the subscription. For each
// individual message, the subscriber may use the ack_id received in the
// PullResponse to Ack the message, Nack the message, or modify the ack
// deadline with ModifyAckDeadline. See the
// Subscription.ack_deadline_seconds field documentation for details on the
// ack deadline behavior.
//
// Note: Messages may be consumed in parallel by multiple subscribers making
// Pull calls to the same subscription; this will result in the set of
// messages from the subscription being shared and each subscriber
// receiving a subset of the messages.
//
// (4) The subscriber can explicitly truncate the current subscription.
//
// (5) "Truncated" events are delivered when a subscription is
// truncated, whether due to the subscription's truncation policy
// or an explicit request from the subscriber.
//
// Subscription creation:
//
// Subscription subscription;
// subscription.set_topic("topicName");
// subscription.set_name("subscriptionName");
// subscription.push_config().set_push_endpoint("machinename:8888");
// SubscriberService.CreateSubscription(subscription);
//
// Consuming messages via push:
//
// TODO(eschapira): Add HTTP push example.
//
// The port 'machinename:8888' must be bound to a stubby server that implements
// the PushEndpointService with the following method:
//
// int HandlePubsubEvent(PubsubEvent event) {
// if (event.subscription().equals("subscriptionName")) {
// if (event.has_message()) {
// Process(event.message().data());
// } else if (event.truncated()) {
// ProcessTruncatedEvent();
// }
// }
// return OK; // This return code implies an acknowledgment
// }
//
// Consuming messages via pull:
//
// The subscription must be created without setting the push_config field.
//
// PullRequest pull_request;
// pull_request.set_subscription("subscriptionName");
// pull_request.set_return_immediately(false);
// while (true) {
// PullResponse pull_response;
// if (SubscriberService.Pull(pull_request, pull_response) == OK) {
// PubsubEvent event = pull_response.pubsub_event();
// if (event.has_message()) {
// Process(event.message().data());
// } else if (event.truncated()) {
// ProcessTruncatedEvent();
// }
// AcknowledgeRequest ack_request;
// ackRequest.set_subscription("subscriptionName");
// ackRequest.set_ack_id(pull_response.ack_id());
// SubscriberService.Acknowledge(ack_request);
// }
// }
// -----------------------------------------------------------------------------
// Reliability Semantics
// -----------------------------------------------------------------------------
// When a subscriber successfully creates a subscription using
// Subscriber.CreateSubscription, it establishes a "subscription point" with
// respect to that subscription - the subscriber is guaranteed to receive any
// message published after this subscription point that matches the
// subscription's query. Note that messages published before the Subscription
// point may or may not be delivered.
//
// If the system truncates the subscription according to the specified
// truncation policy, the system delivers a subscription status event with the
// "truncated" field set to true. We refer to such events as "truncation
// events". A truncation event:
//
// * Informs the subscriber that part of the subscription messages have been
// discarded. The subscriber may want to recover from the message loss, e.g.,
// by resyncing its state with its backend.
// * Establishes a new subscription point, i.e., the subscriber is guaranteed to
// receive all changes published after the trunction event is received (or
// until another truncation event is received).
//
// Note that messages are not delivered in any particular order by the pubsub
// system. Furthermore, the system guarantees at-least-once delivery
// of each message or truncation events until acked.
// -----------------------------------------------------------------------------
// Deletion
// -----------------------------------------------------------------------------
// Both topics and subscriptions may be deleted. Deletion of a topic implies
// deletion of all attached subscriptions.
//
// When a subscription is deleted directly by calling DeleteSubscription, all
// messages are immediately dropped. If it is a pull subscriber, future pull
// requests will return NOT_FOUND.
//
// When a topic is deleted all corresponding subscriptions are immediately
// deleted, and subscribers experience the same behavior as directly deleting
// the subscription.
// -----------------------------------------------------------------------------
// The Publisher service and its protos.
// -----------------------------------------------------------------------------
// The service that an application uses to manipulate topics, and to send
// messages to a topic.
service PublisherService {
// Creates the given topic with the given name.
rpc CreateTopic(Topic) returns (Topic) {
}
// Adds a message to the topic. Returns NOT_FOUND if the topic does not
// exist.
// (-- For different error code values returned via Stubby, see
// util/task/codes.proto. --)
rpc Publish(PublishRequest) returns (proto2.Empty) {
}
// Adds one or more messages to the topic. Returns NOT_FOUND if the topic does
// not exist.
rpc PublishBatch(PublishBatchRequest) returns (PublishBatchResponse) {
}
// Gets the configuration of a topic. Since the topic only has the name
// attribute, this method is only useful to check the existence of a topic.
// If other attributes are added in the future, they will be returned here.
rpc GetTopic(GetTopicRequest) returns (Topic) {
}
// Lists matching topics.
rpc ListTopics(ListTopicsRequest) returns (ListTopicsResponse) {
}
// Deletes the topic with the given name. All subscriptions to this topic
// are also deleted. Returns NOT_FOUND if the topic does not exist.
// After a topic is deleted, a new topic may be created with the same name.
rpc DeleteTopic(DeleteTopicRequest) returns (proto2.Empty) {
}
}
// A topic resource.
message Topic {
// Name of the topic.
optional string name = 1;
}
// A message data and its labels.
message PubsubMessage {
// The message payload.
optional bytes data = 1;
// Optional list of labels for this message. Keys in this collection must
// be unique.
//(-- TODO(eschapira): Define how key namespace may be scoped to the topic.--)
repeated tech.label.Label label = 2;
// ID of this message assigned by the server at publication time. Guaranteed
// to be unique within the topic. This value may be read by a subscriber
// that receives a PubsubMessage via a Pull call or a push delivery. It must
// not be populated by a publisher in a Publish call.
optional string message_id = 3;
}
// Request for the GetTopic method.
message GetTopicRequest {
// The name of the topic to get.
optional string topic = 1;
}
// Request for the Publish method.
message PublishRequest {
// The message in the request will be published on this topic.
optional string topic = 1;
// The message to publish.
optional PubsubMessage message = 2;
}
// Request for the PublishBatch method.
message PublishBatchRequest {
// The messages in the request will be published on this topic.
optional string topic = 1;
// The messages to publish.
repeated PubsubMessage messages = 2;
}
// Response for the PublishBatch method.
message PublishBatchResponse {
// The server-assigned ID of each published message, in the same order as
// the messages in the request. IDs are guaranteed to be unique within
// the topic.
repeated string message_ids = 1;
}
// Request for the ListTopics method.
message ListTopicsRequest {
// A valid label query expression.
// (-- Which labels are required or supported is implementation-specific. --)
optional string query = 1;
// Maximum number of topics to return.
// (-- If not specified or <= 0, the implementation will select a reasonable
// value. --)
optional int32 max_results = 2;
// The value obtained in the last <code>ListTopicsResponse</code>
// for continuation.
optional string page_token = 3;
}
// Response for the ListTopics method.
message ListTopicsResponse {
// The resulting topics.
repeated Topic topic = 1;
// If not empty, indicates that there are more topics that match the request,
// and this value should be passed to the next <code>ListTopicsRequest</code>
// to continue.
optional string next_page_token = 2;
}
// Request for the Delete method.
message DeleteTopicRequest {
// Name of the topic to delete.
optional string topic = 1;
}
// -----------------------------------------------------------------------------
// The Subscriber service and its protos.
// -----------------------------------------------------------------------------
// The service that an application uses to manipulate subscriptions and to
// consume messages from a subscription via the pull method.
service SubscriberService {
// Creates a subscription on a given topic for a given subscriber.
// If the subscription already exists, returns ALREADY_EXISTS.
// If the corresponding topic doesn't exist, returns NOT_FOUND.
//
// If the name is not provided in the request, the server will assign a random
// name for this subscription on the same project as the topic.
rpc CreateSubscription(Subscription) returns (Subscription) {
}
// Gets the configuration details of a subscription.
rpc GetSubscription(GetSubscriptionRequest) returns (Subscription) {
}
// Lists matching subscriptions.
rpc ListSubscriptions(ListSubscriptionsRequest)
returns (ListSubscriptionsResponse) {
}
// Deletes an existing subscription. All pending messages in the subscription
// are immediately dropped. Calls to Pull after deletion will return
// NOT_FOUND.
rpc DeleteSubscription(DeleteSubscriptionRequest) returns (proto2.Empty) {
}
// Removes all the pending messages in the subscription and releases the
// storage associated with them. Results in a truncation event to be sent to
// the subscriber. Messages added after this call returns are stored in the
// subscription as before.
rpc TruncateSubscription(TruncateSubscriptionRequest) returns (proto2.Empty) {
}
//
// Push subscriber calls.
//
// Modifies the <code>PushConfig</code> for a specified subscription.
// This method can be used to suspend the flow of messages to an endpoint
// by clearing the <code>PushConfig</code> field in the request. Messages
// will be accumulated for delivery even if no push configuration is
// defined or while the configuration is modified.
rpc ModifyPushConfig(ModifyPushConfigRequest) returns (proto2.Empty) {
}
//
// Pull Subscriber calls
//
// Pulls a single message from the server.
// If return_immediately is true, and no messages are available in the
// subscription, this method returns FAILED_PRECONDITION. The system is free
// to return an UNAVAILABLE error if no messages are available in a
// reasonable amount of time (to reduce system load).
rpc Pull(PullRequest) returns (PullResponse) {
}
// Pulls messages from the server. Returns an empty list if there are no
// messages available in the backlog. The system is free to return UNAVAILABLE
// if there are too many pull requests outstanding for the given subscription.
rpc PullBatch(PullBatchRequest) returns (PullBatchResponse) {
}
// Modifies the Ack deadline for a message received from a pull request.
rpc ModifyAckDeadline(ModifyAckDeadlineRequest) returns (proto2.Empty) {
}
// Acknowledges a particular received message: the Pub/Sub system can remove
// the given message from the subscription. Acknowledging a message whose
// Ack deadline has expired may succeed, but the message could have been
// already redelivered. Acknowledging a message more than once will not
// result in an error. This is only used for messages received via pull.
rpc Acknowledge(AcknowledgeRequest) returns (proto2.Empty) {
}
// Refuses processing a particular received message. The system will
// redeliver this message to some consumer of the subscription at some
// future time. This is only used for messages received via pull.
rpc Nack(NackRequest) returns (proto2.Empty) {
}
}
// A subscription resource.
message Subscription {
// Name of the subscription.
optional string name = 1;
// The name of the topic from which this subscription is receiving messages.
optional string topic = 2;
// If <code>query</code> is non-empty, only messages on the subscriber's
// topic whose labels match the query will be returned. Otherwise all
// messages on the topic will be returned.
// (-- The query syntax is described in tech/label/proto/label_query.proto --)
optional string query = 3;
// The subscriber may specify requirements for truncating unacknowledged
// subscription entries. The system will honor the
// <code>CreateSubscription</code> request only if it can meet these
// requirements. If this field is not specified, messages are never truncated
// by the system.
optional TruncationPolicy truncation_policy = 4;
// Specifies which messages can be truncated by the system.
message TruncationPolicy {
oneof policy {
// If <code>max_bytes</code> is specified, the system is allowed to drop
// old messages to keep the combined size of stored messages under
// <code>max_bytes</code>. This is a hint; the system may keep more than
// this many bytes, but will make a best effort to keep the size from
// growing much beyond this parameter.
int64 max_bytes = 1;
// If <code>max_age_seconds</code> is specified, the system is allowed to
// drop messages that have been stored for at least this many seconds.
// This is a hint; the system may keep these messages, but will make a
// best effort to remove them when their maximum age is reached.
int64 max_age_seconds = 2;
}
}
// If push delivery is used with this subscription, this field is
// used to configure it.
optional PushConfig push_config = 5;
// For either push or pull delivery, the value is the maximum time after a
// subscriber receives a message before the subscriber should acknowledge or
// Nack the message. If the Ack deadline for a message passes without an
// Ack or a Nack, the Pub/Sub system will eventually redeliver the message.
// If a subscriber acknowledges after the deadline, the Pub/Sub system may
// accept the Ack, but it is possible that the message has been already
// delivered again. Multiple Acks to the message are allowed and will
// succeed.
//
// For push delivery, this value is used to set the request timeout for
// the call to the push endpoint.
//
// For pull delivery, this value is used as the initial value for the Ack
// deadline. It may be overridden for a specific pull request (message) with
// <code>ModifyAckDeadline</code>.
// While a message is outstanding (i.e. it has been delivered to a pull
// subscriber and the subscriber has not yet Acked or Nacked), the Pub/Sub
// system will not deliver that message to another pull subscriber
// (on a best-effort basis).
optional int32 ack_deadline_seconds = 6;
// If this parameter is set to n, the system is allowed to (but not required
// to) delete the subscription when at least n seconds have elapsed since the
// client presence was detected. (Presence is detected through any
// interaction using the subscription ID, including Pull(), Get(), or
// acknowledging a message.)
//
// If this parameter is not set, the subscription will stay live until
// explicitly deleted.
//
// Clients can detect such garbage collection when a Get call or a Pull call
// (for pull subscribers only) returns NOT_FOUND.
optional int64 garbage_collect_seconds = 7;
}
// Configuration for a push delivery endpoint.
message PushConfig {
// A URL locating the endpoint to which messages should be pushed.
// For example, a Webhook endpoint might use "https://example.com/push".
// (-- An Android application might use "gcm:<REGID>", where <REGID> is a
// GCM registration id allocated for pushing messages to the application. --)
optional string push_endpoint = 1;
}
// An event indicating a received message or truncation event.
message PubsubEvent {
// The subscription that received the event.
optional string subscription = 1;
oneof type {
// A received message.
PubsubMessage message = 2;
// Indicates that this subscription has been truncated.
bool truncated = 3;
// Indicates that this subscription has been deleted. (Note that pull
// subscribers will always receive NOT_FOUND in response in their pull
// request on the subscription, rather than seeing this boolean.)
bool deleted = 4;
}
}
// Request for the GetSubscription method.
message GetSubscriptionRequest {
// The name of the subscription to get.
optional string subscription = 1;
}
// Request for the ListSubscriptions method.
message ListSubscriptionsRequest {
// A valid label query expression.
// (-- Which labels are required or supported is implementation-specific.
// TODO(eschapira): This method must support to query by topic. We must
// define the key URI for the "topic" label. --)
optional string query = 1;
// Maximum number of subscriptions to return.
// (-- If not specified or <= 0, the implementation will select a reasonable
// value. --)
optional int32 max_results = 3;
// The value obtained in the last <code>ListSubscriptionsResponse</code>
// for continuation.
optional string page_token = 4;
}
// Response for the ListSubscriptions method.
message ListSubscriptionsResponse {
// The subscriptions that match the request.
repeated Subscription subscription = 1;
// If not empty, indicates that there are more subscriptions that match the
// request and this value should be passed to the next
// <code>ListSubscriptionsRequest</code> to continue.
optional string next_page_token = 2;
}
// Request for the TruncateSubscription method.
message TruncateSubscriptionRequest {
// The subscription that is being truncated.
optional string subscription = 1;
}
// Request for the DeleteSubscription method.
message DeleteSubscriptionRequest {
// The subscription to delete.
optional string subscription = 1;
}
// Request for the ModifyPushConfig method.
message ModifyPushConfigRequest {
// The name of the subscription.
optional string subscription = 1;
// An empty <code>push_config</code> indicates that the Pub/Sub system should
// pause pushing messages from the given subscription.
optional PushConfig push_config = 2;
}
// -----------------------------------------------------------------------------
// The protos used by a pull subscriber.
// -----------------------------------------------------------------------------
// Request for the Pull method.
message PullRequest {
// The subscription from which a message should be pulled.
optional string subscription = 1;
// If this is specified as true the system will respond immediately even if
// it is not able to return a message in the Pull response. Otherwise the
// system is allowed to wait until at least one message is available rather
// than returning FAILED_PRECONDITION. The client may cancel the request if
// it does not wish to wait any longer for the response.
optional bool return_immediately = 2;
}
// Either a <code>PubsubMessage</code> or a truncation event. One of these two
// must be populated.
message PullResponse {
// This ID must be used to acknowledge the received event or message.
optional string ack_id = 1;
// A pubsub message or truncation event.
optional PubsubEvent pubsub_event = 2;
}
// Request for the PullBatch method.
message PullBatchRequest {
// The subscription from which messages should be pulled.
optional string subscription = 1;
// If this is specified as true the system will respond immediately even if
// it is not able to return a message in the Pull response. Otherwise the
// system is allowed to wait until at least one message is available rather
// than returning no messages. The client may cancel the request if it does
// not wish to wait any longer for the response.
optional bool return_immediately = 2;
// The maximum number of PubsubEvents returned for this request. The Pub/Sub
// system may return fewer than the number of events specified.
optional int32 max_events = 3;
}
// Response for the PullBatch method.
message PullBatchResponse {
// Received Pub/Sub messages or status events. The Pub/Sub system will return
// zero messages if there are no more messages available in the backlog. The
// Pub/Sub system may return fewer than the max_events requested even if
// there are more messages available in the backlog.
repeated PullResponse pull_responses = 2;
}
// Request for the ModifyAckDeadline method.
message ModifyAckDeadlineRequest {
// The name of the subscription from which messages are being pulled.
optional string subscription = 1;
// The acknowledgment ID.
optional string ack_id = 2;
// The new Ack deadline. Must be >= 0.
optional int32 ack_deadline_seconds = 3;
}
// Request for the Acknowledge method.
message AcknowledgeRequest {
// The subscription whose message is being acknowledged.
optional string subscription = 1;
// The acknowledgment ID for the message being acknowledged. This was
// returned by the Pub/Sub system in the Pull response.
repeated string ack_id = 2;
}
// Request for the Nack method.
message NackRequest {
// The subscription whose message is being Nacked.
optional string subscription = 1;
// The acknowledgment ID for the message being refused. This was returned by
// the Pub/Sub system in the Pull response.
repeated string ack_id = 2;
}
// -----------------------------------------------------------------------------
// The service and protos used by a push subscriber.
// -----------------------------------------------------------------------------
// The service that a subscriber uses to handle messages sent via push
// delivery.
// This service is not currently exported for HTTP clients.
// TODO(eschapira): Explain HTTP subscribers.
service PushEndpointService {
// Sends a <code>PubsubMessage</code> or a subscription status event to a
// push endpoint.
// The push endpoint responds with an empty message and a code from
// util/task/codes.proto. The following codes have a particular meaning to the
// Pub/Sub system:
// OK - This is interpreted by Pub/Sub as Ack.
// ABORTED - This is intepreted by Pub/Sub as a Nack, without implying
// pushback for congestion control. The Pub/Sub system will
// retry this message at a later time.
// UNAVAILABLE - This is intepreted by Pub/Sub as a Nack, with the additional
// semantics of push-back. The Pub/Sub system will use an AIMD
// congestion control algorithm to backoff the rate of sending
// messages from this subscription.
// Any other code, or a failure to respond, will be interpreted in the same
// way as ABORTED; i.e. the system will retry the message at a later time to
// ensure reliable delivery.
rpc HandlePubsubEvent(PubsubEvent) returns (proto2.Empty);
}

@ -35,6 +35,7 @@
#define __GRPCPP_SERVER_CREDENTIALS_H_
#include <memory>
#include <vector>
#include <grpc++/config.h>
@ -60,9 +61,12 @@ class ServerCredentials final {
// Options to create ServerCredentials with SSL
struct SslServerCredentialsOptions {
struct PemKeyCertPair{
grpc::string private_key;
grpc::string cert_chain;
};
grpc::string pem_root_certs;
grpc::string pem_private_key;
grpc::string pem_cert_chain;
std::vector<PemKeyCertPair> pem_key_cert_pairs;
};
// Factory for building different types of ServerCredentials

@ -194,6 +194,7 @@ typedef enum grpc_completion_type {
GRPC_FINISHED, /* An RPC has finished. The event contains status.
On the server this will be OK or Cancelled. */
GRPC_SERVER_RPC_NEW, /* A new RPC has arrived at the server */
GRPC_SERVER_SHUTDOWN, /* The server has finished shutting down */
GRPC_COMPLETION_DO_NOT_USE /* must be last, forces users to include
a default: case */
} grpc_completion_type;
@ -232,12 +233,12 @@ typedef struct grpc_event {
} grpc_event;
/* Initialize the grpc library */
void grpc_init();
void grpc_init(void);
/* Shutdown the grpc library */
void grpc_shutdown();
void grpc_shutdown(void);
grpc_completion_queue *grpc_completion_queue_create();
grpc_completion_queue *grpc_completion_queue_create(void);
/* Blocks until an event is available, the completion queue is being shutdown,
or deadline is reached. Returns NULL on timeout, otherwise the event that
@ -325,22 +326,6 @@ grpc_call_error grpc_call_start_invoke(grpc_call *call,
void *metadata_read_tag,
void *finished_tag, gpr_uint32 flags);
/* DEPRECATED: users should use grpc_call_server_accept, and
grpc_call_server_end_initial_metadata instead now.
Accept an incoming RPC, binding a completion queue to it.
To be called after adding metadata to the call, but before sending
messages.
flags is a bit-field combination of the write flags defined above.
REQUIRES: Can be called at most once per call.
Can only be called on the server.
Produces a GRPC_FINISHED event with finished_tag when the call has been
completed (there may be other events for the call pending at this
time) */
grpc_call_error grpc_call_accept(grpc_call *call, grpc_completion_queue *cq,
void *finished_tag, gpr_uint32 flags);
/* Accept an incoming RPC, binding a completion queue to it.
To be called before sending or receiving messages.
REQUIRES: Can be called at most once per call.
@ -443,7 +428,8 @@ grpc_server *grpc_server_create(grpc_completion_queue *cq,
REQUIRES: server not started */
int grpc_server_add_http2_port(grpc_server *server, const char *addr);
/* Add a secure port to server; returns 1 on success, 0 on failure
/* Add a secure port to server.
Returns bound port number on success, 0 on failure.
REQUIRES: server not started */
int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr);
@ -455,6 +441,10 @@ void grpc_server_start(grpc_server *server);
Existing calls will be allowed to complete. */
void grpc_server_shutdown(grpc_server *server);
/* As per grpc_server_shutdown, but send a GRPC_SERVER_SHUTDOWN event when
there are no more calls being serviced. */
void grpc_server_shutdown_and_notify(grpc_server *server, void *tag);
/* Destroy a server.
Forcefully cancels all existing calls. */
void grpc_server_destroy(grpc_server *server);

@ -54,22 +54,26 @@ void grpc_credentials_release(grpc_credentials *creds);
/* Creates default credentials. */
grpc_credentials *grpc_default_credentials_create(void);
/* Object that holds a private key / certificate chain pair in PEM format. */
typedef struct {
/* private_key is the NULL-terminated string containing the PEM encoding of
the client's private key. */
const char *private_key;
/* cert_chain is the NULL-terminated string containing the PEM encoding of
the client's certificate chain. */
const char *cert_chain;
} grpc_ssl_pem_key_cert_pair;
/* Creates an SSL credentials object.
- pem_roots_cert is the buffer containing the PEM encoding of the server
root certificates. This parameter cannot be NULL.
- pem_roots_cert_size is the size of the associated buffer.
- pem_private_key is the buffer containing the PEM encoding of the client's
private key. This parameter can be NULL if the client does not have a
private key.
- pem_private_key_size is the size of the associated buffer.
- pem_cert_chain is the buffer containing the PEM encoding of the client's
certificate chain. This parameter can be NULL if the client does not have
a certificate chain.
- pem_cert_chain_size is the size of the associated buffer. */
- pem_roots_cert is the NULL-terminated string containing the PEM encoding
of the server root certificates. If this parameter is NULL, the default
roots will be used.
- pem_key_cert_pair is a pointer on the object containing client's private
key and certificate chain. This parameter can be NULL if the client does
not have such a key/cert pair. */
grpc_credentials *grpc_ssl_credentials_create(
const unsigned char *pem_root_certs, size_t pem_root_certs_size,
const unsigned char *pem_private_key, size_t pem_private_key_size,
const unsigned char *pem_cert_chain, size_t pem_cert_chain_size);
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair);
/* Creates a composite credentials object. */
grpc_credentials *grpc_composite_credentials_create(grpc_credentials *creds1,
@ -130,22 +134,16 @@ typedef struct grpc_server_credentials grpc_server_credentials;
void grpc_server_credentials_release(grpc_server_credentials *creds);
/* Creates an SSL server_credentials object.
TODO(jboeuf): Change the constructor so that it can support multiple
key/cert pairs.
- pem_roots_cert is the buffer containing the PEM encoding of the server
root certificates. This parameter may be NULL if the server does not want
the client to be authenticated with SSL.
- pem_roots_cert_size is the size of the associated buffer.
- pem_private_key is the buffer containing the PEM encoding of the client's
private key. This parameter cannot be NULL.
- pem_private_key_size is the size of the associated buffer.
- pem_cert_chain is the buffer containing the PEM encoding of the client's
certificate chain. This parameter cannot be NULL.
- pem_cert_chain_size is the size of the associated buffer. */
- pem_roots_cert is the NULL-terminated string containing the PEM encoding of
the client root certificates. This parameter may be NULL if the server does
not want the client to be authenticated with SSL.
- pem_key_cert_pairs is an array private key / certificate chains of the
server. This parameter cannot be NULL.
- num_key_cert_pairs indicates the number of items in the private_key_files
and cert_chain_files parameters. It should be at least 1. */
grpc_server_credentials *grpc_ssl_server_credentials_create(
const unsigned char *pem_root_certs, size_t pem_root_certs_size,
const unsigned char *pem_private_key, size_t pem_private_key_size,
const unsigned char *pem_cert_chain, size_t pem_cert_chain_size);
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs);
/* Creates a fake server transport security credentials object for testing. */
grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(

@ -163,7 +163,7 @@ gpr_slice gpr_slice_split_tail(gpr_slice *s, size_t split);
Requires s intialized, split <= s.length */
gpr_slice gpr_slice_split_head(gpr_slice *s, size_t split);
gpr_slice gpr_empty_slice();
gpr_slice gpr_empty_slice(void);
/* Returns <0 if a < b, ==0 if a == b, >0 if a > b */
int gpr_slice_cmp(gpr_slice a, gpr_slice b);

@ -31,6 +31,9 @@
*
*/
#include <string>
#include <map>
#include "src/compiler/cpp_generator.h"
#include "src/compiler/cpp_generator_helpers.h"
@ -42,23 +45,23 @@
namespace grpc_cpp_generator {
namespace {
bool NoStreaming(const google::protobuf::MethodDescriptor* method) {
bool NoStreaming(const google::protobuf::MethodDescriptor *method) {
return !method->client_streaming() && !method->server_streaming();
}
bool ClientOnlyStreaming(const google::protobuf::MethodDescriptor* method) {
bool ClientOnlyStreaming(const google::protobuf::MethodDescriptor *method) {
return method->client_streaming() && !method->server_streaming();
}
bool ServerOnlyStreaming(const google::protobuf::MethodDescriptor* method) {
bool ServerOnlyStreaming(const google::protobuf::MethodDescriptor *method) {
return !method->client_streaming() && method->server_streaming();
}
bool BidiStreaming(const google::protobuf::MethodDescriptor* method) {
bool BidiStreaming(const google::protobuf::MethodDescriptor *method) {
return method->client_streaming() && method->server_streaming();
}
bool HasClientOnlyStreaming(const google::protobuf::FileDescriptor* file) {
bool HasClientOnlyStreaming(const google::protobuf::FileDescriptor *file) {
for (int i = 0; i < file->service_count(); i++) {
for (int j = 0; j < file->service(i)->method_count(); j++) {
if (ClientOnlyStreaming(file->service(i)->method(j))) {
@ -69,7 +72,7 @@ bool HasClientOnlyStreaming(const google::protobuf::FileDescriptor* file) {
return false;
}
bool HasServerOnlyStreaming(const google::protobuf::FileDescriptor* file) {
bool HasServerOnlyStreaming(const google::protobuf::FileDescriptor *file) {
for (int i = 0; i < file->service_count(); i++) {
for (int j = 0; j < file->service(i)->method_count(); j++) {
if (ServerOnlyStreaming(file->service(i)->method(j))) {
@ -80,7 +83,7 @@ bool HasServerOnlyStreaming(const google::protobuf::FileDescriptor* file) {
return false;
}
bool HasBidiStreaming(const google::protobuf::FileDescriptor* file) {
bool HasBidiStreaming(const google::protobuf::FileDescriptor *file) {
for (int i = 0; i < file->service_count(); i++) {
for (int j = 0; j < file->service(i)->method_count(); j++) {
if (BidiStreaming(file->service(i)->method(j))) {
@ -92,8 +95,8 @@ bool HasBidiStreaming(const google::protobuf::FileDescriptor* file) {
}
} // namespace
string GetHeaderIncludes(const google::protobuf::FileDescriptor* file) {
string temp =
std::string GetHeaderIncludes(const google::protobuf::FileDescriptor *file) {
std::string temp =
"#include \"grpc++/impl/internal_stub.h\"\n"
"#include \"grpc++/status.h\"\n"
"\n"
@ -121,16 +124,16 @@ string GetHeaderIncludes(const google::protobuf::FileDescriptor* file) {
return temp;
}
string GetSourceIncludes() {
std::string GetSourceIncludes() {
return "#include \"grpc++/channel_interface.h\"\n"
"#include \"grpc++/impl/rpc_method.h\"\n"
"#include \"grpc++/impl/rpc_service_method.h\"\n"
"#include \"grpc++/stream.h\"\n";
}
void PrintHeaderClientMethod(google::protobuf::io::Printer* printer,
const google::protobuf::MethodDescriptor* method,
map<string, string>* vars) {
void PrintHeaderClientMethod(google::protobuf::io::Printer *printer,
const google::protobuf::MethodDescriptor *method,
std::map<std::string, std::string> *vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true);
@ -157,9 +160,9 @@ void PrintHeaderClientMethod(google::protobuf::io::Printer* printer,
}
}
void PrintHeaderServerMethod(google::protobuf::io::Printer* printer,
const google::protobuf::MethodDescriptor* method,
map<string, string>* vars) {
void PrintHeaderServerMethod(google::protobuf::io::Printer *printer,
const google::protobuf::MethodDescriptor *method,
std::map<std::string, std::string> *vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true);
@ -191,9 +194,9 @@ void PrintHeaderServerMethod(google::protobuf::io::Printer* printer,
}
}
void PrintHeaderService(google::protobuf::io::Printer* printer,
const google::protobuf::ServiceDescriptor* service,
map<string, string>* vars) {
void PrintHeaderService(google::protobuf::io::Printer *printer,
const google::protobuf::ServiceDescriptor *service,
std::map<std::string, std::string> *vars) {
(*vars)["Service"] = service->name();
printer->Print(*vars,
@ -238,11 +241,11 @@ void PrintHeaderService(google::protobuf::io::Printer* printer,
printer->Print("};\n");
}
string GetHeaderServices(const google::protobuf::FileDescriptor* file) {
string output;
std::string GetHeaderServices(const google::protobuf::FileDescriptor *file) {
std::string output;
google::protobuf::io::StringOutputStream output_stream(&output);
google::protobuf::io::Printer printer(&output_stream, '$');
map<string, string> vars;
std::map<std::string, std::string> vars;
for (int i = 0; i < file->service_count(); ++i) {
PrintHeaderService(&printer, file->service(i), &vars);
@ -251,9 +254,9 @@ string GetHeaderServices(const google::protobuf::FileDescriptor* file) {
return output;
}
void PrintSourceClientMethod(google::protobuf::io::Printer* printer,
const google::protobuf::MethodDescriptor* method,
map<string, string>* vars) {
void PrintSourceClientMethod(google::protobuf::io::Printer *printer,
const google::protobuf::MethodDescriptor *method,
std::map<std::string, std::string> *vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true);
@ -309,9 +312,9 @@ void PrintSourceClientMethod(google::protobuf::io::Printer* printer,
}
}
void PrintSourceServerMethod(google::protobuf::io::Printer* printer,
const google::protobuf::MethodDescriptor* method,
map<string, string>* vars) {
void PrintSourceServerMethod(google::protobuf::io::Printer *printer,
const google::protobuf::MethodDescriptor *method,
std::map<std::string, std::string> *vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true);
@ -359,9 +362,9 @@ void PrintSourceServerMethod(google::protobuf::io::Printer* printer,
}
}
void PrintSourceService(google::protobuf::io::Printer* printer,
const google::protobuf::ServiceDescriptor* service,
map<string, string>* vars) {
void PrintSourceService(google::protobuf::io::Printer *printer,
const google::protobuf::ServiceDescriptor *service,
std::map<std::string, std::string> *vars) {
(*vars)["Service"] = service->name();
printer->Print(
*vars,
@ -391,7 +394,7 @@ void PrintSourceService(google::protobuf::io::Printer* printer,
"}\n");
printer->Print("service_ = new ::grpc::RpcService();\n");
for (int i = 0; i < service->method_count(); ++i) {
const google::protobuf::MethodDescriptor* method = service->method(i);
const google::protobuf::MethodDescriptor *method = service->method(i);
(*vars)["Method"] = method->name();
(*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true);
@ -455,11 +458,11 @@ void PrintSourceService(google::protobuf::io::Printer* printer,
printer->Print("}\n\n");
}
string GetSourceServices(const google::protobuf::FileDescriptor* file) {
string output;
std::string GetSourceServices(const google::protobuf::FileDescriptor *file) {
std::string output;
google::protobuf::io::StringOutputStream output_stream(&output);
google::protobuf::io::Printer printer(&output_stream, '$');
map<string, string> vars;
std::map<std::string, std::string> vars;
// Package string is empty or ends with a dot. It is used to fully qualify
// method names.
vars["Package"] = file->package();

@ -42,21 +42,19 @@ class FileDescriptor;
} // namespace protobuf
} // namespace google
using namespace std;
namespace grpc_cpp_generator {
// Return the includes needed for generated header file.
string GetHeaderIncludes(const google::protobuf::FileDescriptor* file);
std::string GetHeaderIncludes(const google::protobuf::FileDescriptor *file);
// Return the includes needed for generated source file.
string GetSourceIncludes();
std::string GetSourceIncludes();
// Return the services for generated header file.
string GetHeaderServices(const google::protobuf::FileDescriptor* file);
std::string GetHeaderServices(const google::protobuf::FileDescriptor *file);
// Return the services for generated source file.
string GetSourceServices(const google::protobuf::FileDescriptor* file);
std::string GetSourceServices(const google::protobuf::FileDescriptor *file);
} // namespace grpc_cpp_generator

@ -39,14 +39,12 @@
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
using namespace std;
namespace grpc_cpp_generator {
inline bool StripSuffix(string* filename, const string& suffix) {
inline bool StripSuffix(std::string *filename, const std::string &suffix) {
if (filename->length() >= suffix.length()) {
size_t suffix_pos = filename->length() - suffix.length();
if (filename->compare(suffix_pos, string::npos, suffix) == 0) {
if (filename->compare(suffix_pos, std::string::npos, suffix) == 0) {
filename->resize(filename->size() - suffix.size());
return true;
}
@ -55,19 +53,20 @@ inline bool StripSuffix(string* filename, const string& suffix) {
return false;
}
inline string StripProto(string filename) {
inline std::string StripProto(std::string filename) {
if (!StripSuffix(&filename, ".protodevel")) {
StripSuffix(&filename, ".proto");
}
return filename;
}
inline string StringReplace(string str, const string& from, const string& to) {
inline std::string StringReplace(std::string str, const std::string &from,
const std::string &to) {
size_t pos = 0;
for (;;) {
pos = str.find(from, pos);
if (pos == string::npos) {
if (pos == std::string::npos) {
break;
}
str.replace(pos, from.length(), to);
@ -77,23 +76,23 @@ inline string StringReplace(string str, const string& from, const string& to) {
return str;
}
inline string DotsToColons(const string& name) {
inline std::string DotsToColons(const std::string &name) {
return StringReplace(name, ".", "::");
}
inline string DotsToUnderscores(const string& name) {
inline std::string DotsToUnderscores(const std::string &name) {
return StringReplace(name, ".", "_");
}
inline string ClassName(const google::protobuf::Descriptor* descriptor,
bool qualified) {
inline std::string ClassName(const google::protobuf::Descriptor *descriptor,
bool qualified) {
// Find "outer", the descriptor of the top-level message in which
// "descriptor" is embedded.
const google::protobuf::Descriptor* outer = descriptor;
const google::protobuf::Descriptor *outer = descriptor;
while (outer->containing_type() != NULL) outer = outer->containing_type();
const string& outer_name = outer->full_name();
string inner_name = descriptor->full_name().substr(outer_name.size());
const std::string &outer_name = outer->full_name();
std::string inner_name = descriptor->full_name().substr(outer_name.size());
if (qualified) {
return "::" + DotsToColons(outer_name) + DotsToUnderscores(inner_name);

@ -35,6 +35,8 @@
//
#include <memory>
#include <string>
#include "src/compiler/cpp_generator.h"
#include "src/compiler/cpp_generator_helpers.h"
#include <google/protobuf/descriptor.h>
@ -49,10 +51,10 @@ class CppGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
CppGrpcGenerator() {}
virtual ~CppGrpcGenerator() {}
virtual bool Generate(const google::protobuf::FileDescriptor* file,
const string& parameter,
google::protobuf::compiler::GeneratorContext* context,
string* error) const {
virtual bool Generate(const google::protobuf::FileDescriptor *file,
const std::string &parameter,
google::protobuf::compiler::GeneratorContext *context,
std::string *error) const {
if (file->options().cc_generic_services()) {
*error =
"cpp grpc proto compiler plugin does not work with generic "
@ -61,7 +63,7 @@ class CppGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
return false;
}
string file_name = grpc_cpp_generator::StripProto(file->name());
std::string file_name = grpc_cpp_generator::StripProto(file->name());
// Generate .pb.h
Insert(context, file_name + ".pb.h", "includes",
@ -79,9 +81,9 @@ class CppGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
private:
// Insert the given code into the given file at the given insertion point.
void Insert(google::protobuf::compiler::GeneratorContext* context,
const string& filename, const string& insertion_point,
const string& code) const {
void Insert(google::protobuf::compiler::GeneratorContext *context,
const std::string &filename, const std::string &insertion_point,
const std::string &code) const {
std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
context->OpenForInsert(filename, insertion_point));
google::protobuf::io::CodedOutputStream coded_out(output.get());
@ -89,7 +91,7 @@ class CppGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
}
};
int main(int argc, char* argv[]) {
int main(int argc, char *argv[]) {
CppGrpcGenerator generator;
return google::protobuf::compiler::PluginMain(argc, argv, &generator);
}

@ -32,6 +32,7 @@
*/
#include <cctype>
#include <string>
#include <map>
#include <vector>
@ -56,17 +57,17 @@ namespace grpc_ruby_generator {
namespace {
// Prints out the method using the ruby gRPC DSL.
void PrintMethod(const MethodDescriptor* method, const string& package,
Printer* out) {
string input_type = RubyTypeOf(method->input_type()->name(), package);
void PrintMethod(const MethodDescriptor *method, const std::string &package,
Printer *out) {
std::string input_type = RubyTypeOf(method->input_type()->name(), package);
if (method->client_streaming()) {
input_type = "stream(" + input_type + ")";
}
string output_type = RubyTypeOf(method->output_type()->name(), package);
std::string output_type = RubyTypeOf(method->output_type()->name(), package);
if (method->server_streaming()) {
output_type = "stream(" + output_type + ")";
}
map<string, string> method_vars = ListToDict({
std::map<std::string, std::string> method_vars = ListToDict({
"mth.name", method->name(), "input.type", input_type, "output.type",
output_type,
});
@ -74,22 +75,22 @@ void PrintMethod(const MethodDescriptor* method, const string& package,
}
// Prints out the service using the ruby gRPC DSL.
void PrintService(const ServiceDescriptor* service, const string& package,
Printer* out) {
void PrintService(const ServiceDescriptor *service, const std::string &package,
Printer *out) {
if (service->method_count() == 0) {
return;
}
// Begin the service module
map<string, string> module_vars = ListToDict({
std::map<std::string, std::string> module_vars = ListToDict({
"module.name", CapitalizeFirst(service->name()),
});
out->Print(module_vars, "module $module.name$\n");
out->Indent();
// TODO(temiola): add documentation
string doc = "TODO: add proto service documentation here";
map<string, string> template_vars = ListToDict({
std::string doc = "TODO: add proto service documentation here";
std::map<std::string, std::string> template_vars = ListToDict({
"Documentation", doc,
});
out->Print("\n");
@ -103,7 +104,7 @@ void PrintService(const ServiceDescriptor* service, const string& package,
out->Print("\n");
out->Print("self.marshal_class_method = :encode\n");
out->Print("self.unmarshal_class_method = :decode\n");
map<string, string> pkg_vars = ListToDict({
std::map<std::string, std::string> pkg_vars = ListToDict({
"service.name", service->name(), "pkg.name", package,
});
out->Print(pkg_vars, "self.service_name = '$pkg.name$.$service.name$'\n");
@ -124,8 +125,8 @@ void PrintService(const ServiceDescriptor* service, const string& package,
} // namespace
string GetServices(const FileDescriptor* file) {
string output;
std::string GetServices(const FileDescriptor *file) {
std::string output;
StringOutputStream output_stream(&output);
Printer out(&output_stream, '$');
@ -136,7 +137,7 @@ string GetServices(const FileDescriptor* file) {
}
// Write out a file header.
map<string, string> header_comment_vars = ListToDict({
std::map<std::string, std::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");
@ -148,16 +149,16 @@ 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.
map<string, string> dep_vars = ListToDict({
std::map<std::string, std::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");
vector<string> modules = Split(file->package(), '.');
std::vector<std::string> modules = Split(file->package(), '.');
for (size_t i = 0; i < modules.size(); ++i) {
map<string, string> module_vars = ListToDict({
std::map<std::string, std::string> module_vars = ListToDict({
"module.name", CapitalizeFirst(modules[i]),
});
out.Print(module_vars, "module $module.name$\n");

@ -36,8 +36,6 @@
#include <string>
using namespace std;
namespace google {
namespace protobuf {
class FileDescriptor;
@ -46,7 +44,7 @@ class FileDescriptor;
namespace grpc_ruby_generator {
string GetServices(const google::protobuf::FileDescriptor* file);
std::string GetServices(const google::protobuf::FileDescriptor *file);
} // namespace grpc_ruby_generator

@ -41,8 +41,8 @@
namespace grpc_ruby_generator {
inline bool ServicesFilename(const google::protobuf::FileDescriptor* file,
string* file_name_or_error) {
inline bool ServicesFilename(const google::protobuf::FileDescriptor *file,
std::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 +57,8 @@ inline bool ServicesFilename(const google::protobuf::FileDescriptor* file,
}
}
inline string MessagesRequireName(
const google::protobuf::FileDescriptor* file) {
inline std::string MessagesRequireName(
const google::protobuf::FileDescriptor *file) {
return Replace(file->name(), ".proto", "");
}

@ -48,17 +48,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 map<string, string> ListToDict(const initializer_list<string>& values) {
inline std::map<std::string, std::string> ListToDict(
const initializer_list<std::string> &values) {
if (values.size() % 2 != 0) {
// MOE: insert std::cerr << "Not every 'key' has a value in `values`."
// << std::endl;
}
map<string, string> value_map;
std::map<std::string, std::string> value_map;
auto value_iter = values.begin();
for (unsigned i = 0; i < values.size() / 2; ++i) {
string key = *value_iter;
std::string key = *value_iter;
++value_iter;
string value = *value_iter;
std::string value = *value_iter;
value_map[key] = value;
++value_iter;
}

@ -45,10 +45,10 @@ using std::transform;
namespace grpc_ruby_generator {
// Split splits a string using char into elems.
inline vector<string>& Split(const string& s, char delim,
vector<string>* elems) {
stringstream ss(s);
string item;
inline std::vector<std::string> &Split(const std::string &s, char delim,
std::vector<std::string> *elems) {
std::stringstream ss(s);
std::string item;
while (getline(ss, item, delim)) {
elems->push_back(item);
}
@ -56,16 +56,17 @@ inline vector<string>& Split(const string& s, char delim,
}
// Split splits a string using char, returning the result in a vector.
inline vector<string> Split(const string& s, char delim) {
vector<string> elems;
inline std::vector<std::string> Split(const std::string &s, char delim) {
std::vector<std::string> elems;
Split(s, delim, &elems);
return elems;
}
// Replace replaces from with to in s.
inline string Replace(string s, const string& from, const string& to) {
inline std::string Replace(std::string s, const std::string &from,
const std::string &to) {
size_t start_pos = s.find(from);
if (start_pos == string::npos) {
if (start_pos == std::string::npos) {
return s;
}
s.replace(start_pos, from.length(), to);
@ -73,10 +74,10 @@ inline string Replace(string s, const string& from, const string& to) {
}
// ReplaceAll replaces all instances of search with replace in s.
inline string ReplaceAll(string s, const string& search,
const string& replace) {
inline std::string ReplaceAll(std::string s, const std::string &search,
const std::string &replace) {
size_t pos = 0;
while ((pos = s.find(search, pos)) != string::npos) {
while ((pos = s.find(search, pos)) != std::string::npos) {
s.replace(pos, search.length(), replace);
pos += replace.length();
}
@ -84,9 +85,10 @@ inline string ReplaceAll(string s, const string& search,
}
// ReplacePrefix replaces from with to in s if search is a prefix of s.
inline bool ReplacePrefix(string* s, const string& from, const string& to) {
inline bool ReplacePrefix(std::string *s, const std::string &from,
const std::string &to) {
size_t start_pos = s->find(from);
if (start_pos == string::npos || start_pos != 0) {
if (start_pos == std::string::npos || start_pos != 0) {
return false;
}
s->replace(start_pos, from.length(), to);
@ -94,7 +96,7 @@ inline bool ReplacePrefix(string* s, const string& from, const string& to) {
}
// CapitalizeFirst capitalizes the first char in a string.
inline string CapitalizeFirst(string s) {
inline std::string CapitalizeFirst(std::string s) {
if (s.empty()) {
return s;
}
@ -103,14 +105,15 @@ inline string CapitalizeFirst(string s) {
}
// RubyTypeOf updates a proto type to the required ruby equivalent.
inline string RubyTypeOf(const string& a_type, const string& package) {
string res(a_type);
inline std::string RubyTypeOf(const std::string &a_type,
const std::string &package) {
std::string res(a_type);
ReplacePrefix(&res, package, ""); // remove the leading package if present
ReplacePrefix(&res, ".", ""); // remove the leading . (no package)
if (res.find('.') == string::npos) {
if (res.find('.') == std::string::npos) {
return res;
} else {
vector<string> prefixes_and_type = Split(res, '.');
std::vector<std::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

@ -37,6 +37,7 @@
// and net/proto2/compiler/public/plugin.h for more information on plugins.
#include <memory>
#include <string>
#include "src/compiler/ruby_generator.h"
#include "src/compiler/ruby_generator_helpers-inl.h"
@ -51,17 +52,17 @@ class RubyGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
RubyGrpcGenerator() {}
~RubyGrpcGenerator() override {}
bool Generate(const google::protobuf::FileDescriptor* file,
const string& parameter,
google::protobuf::compiler::GeneratorContext* context,
string* error) const override {
string code = grpc_ruby_generator::GetServices(file);
bool Generate(const google::protobuf::FileDescriptor *file,
const std::string &parameter,
google::protobuf::compiler::GeneratorContext *context,
std::string *error) const override {
std::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.
string file_name;
std::string file_name;
if (!grpc_ruby_generator::ServicesFilename(file, &file_name)) {
return false;
}
@ -73,7 +74,7 @@ class RubyGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
}
};
int main(int argc, char* argv[]) {
int main(int argc, char *argv[]) {
RubyGrpcGenerator generator;
return google::protobuf::compiler::PluginMain(argc, argv, &generator);
}

@ -178,19 +178,19 @@ static void destroy_channel_elem(grpc_channel_element* elem) {
}
const grpc_channel_filter grpc_client_census_filter = {
client_call_op, channel_op,
client_call_op, channel_op,
sizeof(call_data), client_init_call_elem, client_destroy_call_elem,
sizeof(call_data), client_init_call_elem, client_destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,
"census-client"};
const grpc_channel_filter grpc_server_census_filter = {
server_call_op, channel_op,
server_call_op, channel_op,
sizeof(call_data), server_init_call_elem, server_destroy_call_elem,
sizeof(call_data), server_init_call_elem, server_destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,
"census-server"};

@ -54,7 +54,7 @@
/* Given a size, round up to the next multiple of sizeof(void*) */
#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \
(((x) + GPR_MAX_ALIGNMENT - 1) & ~(GPR_MAX_ALIGNMENT - 1))
(((x)+GPR_MAX_ALIGNMENT - 1) & ~(GPR_MAX_ALIGNMENT - 1))
size_t grpc_channel_stack_size(const grpc_channel_filter **filters,
size_t filter_count) {
@ -190,13 +190,14 @@ void grpc_channel_next_op(grpc_channel_element *elem, grpc_channel_op *op) {
grpc_channel_stack *grpc_channel_stack_from_top_element(
grpc_channel_element *elem) {
return (grpc_channel_stack *)((char *)(elem)-ROUND_UP_TO_ALIGNMENT_SIZE(
sizeof(grpc_channel_stack)));
return (grpc_channel_stack *)((char *)(elem) -
ROUND_UP_TO_ALIGNMENT_SIZE(
sizeof(grpc_channel_stack)));
}
grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem) {
return (grpc_call_stack *)((char *)(elem)-ROUND_UP_TO_ALIGNMENT_SIZE(
sizeof(grpc_call_stack)));
return (grpc_call_stack *)((char *)(elem) - ROUND_UP_TO_ALIGNMENT_SIZE(
sizeof(grpc_call_stack)));
}
static void do_nothing(void *user_data, grpc_op_error error) {}

@ -165,9 +165,9 @@ static void lb_destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_child_channel_top_filter = {
lb_call_op, lb_channel_op,
lb_call_op, lb_channel_op,
sizeof(lb_call_data), lb_init_call_elem, lb_destroy_call_elem,
sizeof(lb_call_data), lb_init_call_elem, lb_destroy_call_elem,
sizeof(lb_channel_data), lb_init_channel_elem, lb_destroy_channel_elem,

@ -39,7 +39,7 @@
/* helper for filters that need to host child channel stacks... handles
lifetime and upwards propagation cleanly */
const grpc_channel_filter grpc_child_channel_top_filter;
extern const grpc_channel_filter grpc_child_channel_top_filter;
typedef grpc_channel_stack grpc_child_channel;
typedef grpc_call_stack grpc_child_call;

@ -450,9 +450,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_client_channel_filter = {
call_op, channel_op,
call_op, channel_op,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,

@ -69,7 +69,7 @@ typedef struct {
/* We perform a small hack to locate transport data alongside the connected
channel data in call allocations, to allow everything to be pulled in minimal
cache line requests */
#define TRANSPORT_STREAM_FROM_CALL_DATA(calld) ((grpc_stream *)((calld) + 1))
#define TRANSPORT_STREAM_FROM_CALL_DATA(calld) ((grpc_stream *)((calld)+1))
#define CALL_DATA_FROM_TRANSPORT_STREAM(transport_stream) \
(((call_data *)(transport_stream)) - 1)
@ -257,9 +257,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_connected_channel_filter = {
call_op, channel_op,
call_op, channel_op,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,

@ -178,9 +178,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_http_client_filter = {
call_op, channel_op,
call_op, channel_op,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,

@ -132,9 +132,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_http_filter = {
call_op, channel_op,
call_op, channel_op,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,

@ -244,9 +244,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_http_server_filter = {
call_op, channel_op,
call_op, channel_op,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,

@ -61,7 +61,7 @@ struct grpc_metadata_buffer_impl {
size_t elem_cap;
};
#define ELEMS(buffer) ((qelem *)((buffer) + 1))
#define ELEMS(buffer) ((qelem *)((buffer)+1))
void grpc_metadata_buffer_init(grpc_metadata_buffer *buffer) {
/* start buffer as NULL, indicating no elements */

@ -131,9 +131,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_no_op_filter = {
call_op, channel_op,
call_op, channel_op,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,

@ -100,7 +100,7 @@ void grpc_alarm_list_init(gpr_timespec now) {
}
}
void grpc_alarm_list_shutdown() {
void grpc_alarm_list_shutdown(void) {
int i;
while (run_some_expired_alarms(NULL, gpr_inf_future, NULL, 0))
;
@ -360,7 +360,7 @@ int grpc_alarm_check(gpr_mu *drop_mu, gpr_timespec now, gpr_timespec *next) {
return run_some_expired_alarms(drop_mu, now, next, 1);
}
gpr_timespec grpc_alarm_list_next_timeout() {
gpr_timespec grpc_alarm_list_next_timeout(void) {
gpr_timespec out;
gpr_mu_lock(&g_mu);
out = g_shard_queue[0]->min_deadline;

@ -42,12 +42,12 @@
int grpc_alarm_check(gpr_mu *drop_mu, gpr_timespec now, gpr_timespec *next);
void grpc_alarm_list_init(gpr_timespec now);
void grpc_alarm_list_shutdown();
void grpc_alarm_list_shutdown(void);
gpr_timespec grpc_alarm_list_next_timeout();
gpr_timespec grpc_alarm_list_next_timeout(void);
/* the following must be implemented by each iomgr implementation */
void grpc_kick_poller();
void grpc_kick_poller(void);
#endif /* __GRPC_INTERNAL_IOMGR_ALARM_INTERNAL_H_ */

@ -80,9 +80,9 @@ static void background_callback_executor(void *ignored) {
gpr_event_set(&g_background_callback_executor_done, (void *)1);
}
void grpc_kick_poller() { gpr_cv_broadcast(&g_cv); }
void grpc_kick_poller(void) { gpr_cv_broadcast(&g_cv); }
void grpc_iomgr_init() {
void grpc_iomgr_init(void) {
gpr_thd_id id;
gpr_mu_init(&g_mu);
gpr_cv_init(&g_cv);
@ -93,7 +93,7 @@ void grpc_iomgr_init() {
gpr_thd_new(&id, background_callback_executor, NULL, NULL);
}
void grpc_iomgr_shutdown() {
void grpc_iomgr_shutdown(void) {
delayed_callback *cb;
gpr_timespec shutdown_deadline =
gpr_time_add(gpr_now(), gpr_time_from_seconds(10));
@ -134,13 +134,13 @@ void grpc_iomgr_shutdown() {
gpr_cv_destroy(&g_cv);
}
void grpc_iomgr_ref() {
void grpc_iomgr_ref(void) {
gpr_mu_lock(&g_mu);
++g_refs;
gpr_mu_unlock(&g_mu);
}
void grpc_iomgr_unref() {
void grpc_iomgr_unref(void) {
gpr_mu_lock(&g_mu);
if (0 == --g_refs) {
gpr_cv_signal(&g_cv);

@ -37,8 +37,8 @@
/* gRPC Callback definition */
typedef void (*grpc_iomgr_cb_func)(void *arg, int success);
void grpc_iomgr_init();
void grpc_iomgr_shutdown();
void grpc_iomgr_init(void);
void grpc_iomgr_shutdown(void);
/* This function is called from within a callback or from anywhere else
and causes the invocation of a callback at some point in the future */

@ -42,10 +42,10 @@ int grpc_maybe_call_delayed_callbacks(gpr_mu *drop_mu, int success);
void grpc_iomgr_add_delayed_callback(grpc_iomgr_cb_func cb, void *cb_arg,
int success);
void grpc_iomgr_ref();
void grpc_iomgr_unref();
void grpc_iomgr_ref(void);
void grpc_iomgr_unref(void);
void grpc_iomgr_platform_init();
void grpc_iomgr_platform_shutdown();
void grpc_iomgr_platform_init(void);
void grpc_iomgr_platform_shutdown(void);
#endif /* __GRPC_INTERNAL_IOMGR_IOMGR_INTERNAL_H_ */

@ -33,6 +33,6 @@
#include "src/core/iomgr/iomgr_posix.h"
void grpc_iomgr_platform_init() { grpc_pollset_global_init(); }
void grpc_iomgr_platform_init(void) { grpc_pollset_global_init(); }
void grpc_iomgr_platform_shutdown() { grpc_pollset_global_shutdown(); }
void grpc_iomgr_platform_shutdown(void) { grpc_pollset_global_shutdown(); }

@ -36,7 +36,7 @@
#include "src/core/iomgr/iomgr_internal.h"
void grpc_pollset_global_init();
void grpc_pollset_global_shutdown();
void grpc_pollset_global_init(void);
void grpc_pollset_global_shutdown(void);
#endif /* __GRPC_INTERNAL_IOMGR_IOMGR_POSIX_H_ */

@ -0,0 +1,68 @@
/*
*
* 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_IOMGR_POLLSET_KICK_H_
#define __GRPC_INTERNAL_IOMGR_POLLSET_KICK_H_
#include <grpc/support/port_platform.h>
/* This is an abstraction around the typical pipe mechanism for waking up a
thread sitting in a poll() style call. */
#ifdef GPR_POSIX_SOCKET
#include "src/core/iomgr/pollset_kick_posix.h"
#else
#error "No pollset kick support on platform"
#endif
void grpc_pollset_kick_global_init(void);
void grpc_pollset_kick_global_destroy(void);
void grpc_pollset_kick_init(grpc_pollset_kick_state *kick_state);
void grpc_pollset_kick_destroy(grpc_pollset_kick_state *kick_state);
/* Must be called before entering poll(). If return value is -1, this consumed
an existing kick. Otherwise the return value is an FD to add to the poll set.
*/
int grpc_pollset_kick_pre_poll(grpc_pollset_kick_state *kick_state);
/* Consume an existing kick. Must be called after poll returns that the fd was
readable, and before calling kick_post_poll. */
void grpc_pollset_kick_consume(grpc_pollset_kick_state *kick_state);
/* Must be called after pre_poll, and after consume if applicable */
void grpc_pollset_kick_post_poll(grpc_pollset_kick_state *kick_state);
void grpc_pollset_kick_kick(grpc_pollset_kick_state *kick_state);
#endif /* __GRPC_INTERNAL_IOMGR_POLLSET_KICK_H_ */

@ -0,0 +1,177 @@
/*
*
* 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/iomgr/pollset_kick_posix.h"
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "src/core/iomgr/socket_utils_posix.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
/* This implementation is based on a freelist of pipes. */
#define GRPC_MAX_CACHED_PIPES 50
#define GRPC_PIPE_LOW_WATERMARK 25
typedef struct grpc_kick_pipe_info {
int pipe_read_fd;
int pipe_write_fd;
struct grpc_kick_pipe_info *next;
} grpc_kick_pipe_info;
static grpc_kick_pipe_info *pipe_freelist = NULL;
static int pipe_freelist_count = 0;
static gpr_mu pipe_freelist_mu;
static grpc_kick_pipe_info *allocate_pipe(void) {
grpc_kick_pipe_info *info;
gpr_mu_lock(&pipe_freelist_mu);
if (pipe_freelist != NULL) {
info = pipe_freelist;
pipe_freelist = pipe_freelist->next;
--pipe_freelist_count;
} else {
int pipefd[2];
/* TODO(klempner): Make this nonfatal */
GPR_ASSERT(0 == pipe(pipefd));
GPR_ASSERT(grpc_set_socket_nonblocking(pipefd[0], 1));
GPR_ASSERT(grpc_set_socket_nonblocking(pipefd[1], 1));
info = gpr_malloc(sizeof(*info));
info->pipe_read_fd = pipefd[0];
info->pipe_write_fd = pipefd[1];
info->next = NULL;
}
gpr_mu_unlock(&pipe_freelist_mu);
return info;
}
static void destroy_pipe(void) {
/* assumes pipe_freelist_mu is held */
grpc_kick_pipe_info *current = pipe_freelist;
pipe_freelist = pipe_freelist->next;
pipe_freelist_count--;
close(current->pipe_read_fd);
close(current->pipe_write_fd);
gpr_free(current);
}
static void free_pipe(grpc_kick_pipe_info *pipe_info) {
gpr_mu_lock(&pipe_freelist_mu);
pipe_info->next = pipe_freelist;
pipe_freelist = pipe_info;
pipe_freelist_count++;
if (pipe_freelist_count > GRPC_MAX_CACHED_PIPES) {
while (pipe_freelist_count > GRPC_PIPE_LOW_WATERMARK) {
destroy_pipe();
}
}
gpr_mu_unlock(&pipe_freelist_mu);
}
void grpc_pollset_kick_global_init() {
pipe_freelist = NULL;
gpr_mu_init(&pipe_freelist_mu);
}
void grpc_pollset_kick_global_destroy() {
while (pipe_freelist != NULL) {
destroy_pipe();
}
gpr_mu_destroy(&pipe_freelist_mu);
}
void grpc_pollset_kick_init(grpc_pollset_kick_state *kick_state) {
gpr_mu_init(&kick_state->mu);
kick_state->kicked = 0;
kick_state->pipe_info = NULL;
}
void grpc_pollset_kick_destroy(grpc_pollset_kick_state *kick_state) {
gpr_mu_destroy(&kick_state->mu);
GPR_ASSERT(kick_state->pipe_info == NULL);
}
int grpc_pollset_kick_pre_poll(grpc_pollset_kick_state *kick_state) {
gpr_mu_lock(&kick_state->mu);
if (kick_state->kicked) {
kick_state->kicked = 0;
gpr_mu_unlock(&kick_state->mu);
return -1;
}
kick_state->pipe_info = allocate_pipe();
gpr_mu_unlock(&kick_state->mu);
return kick_state->pipe_info->pipe_read_fd;
}
void grpc_pollset_kick_consume(grpc_pollset_kick_state *kick_state) {
char buf[128];
int r;
for (;;) {
r = read(kick_state->pipe_info->pipe_read_fd, buf, sizeof(buf));
if (r > 0) continue;
if (r == 0) return;
switch (errno) {
case EAGAIN:
return;
case EINTR:
continue;
default:
gpr_log(GPR_ERROR, "error reading pipe: %s", strerror(errno));
return;
}
}
}
void grpc_pollset_kick_post_poll(grpc_pollset_kick_state *kick_state) {
gpr_mu_lock(&kick_state->mu);
free_pipe(kick_state->pipe_info);
kick_state->pipe_info = NULL;
gpr_mu_unlock(&kick_state->mu);
}
void grpc_pollset_kick_kick(grpc_pollset_kick_state *kick_state) {
gpr_mu_lock(&kick_state->mu);
if (kick_state->pipe_info != NULL) {
char c = 0;
while (write(kick_state->pipe_info->pipe_write_fd, &c, 1) != 1 &&
errno == EINTR)
;
} else {
kick_state->kicked = 1;
}
gpr_mu_unlock(&kick_state->mu);
}

@ -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.
*
*/
#ifndef __GRPC_INTERNAL_IOMGR_POLLSET_KICK_POSIX_H_
#define __GRPC_INTERNAL_IOMGR_POLLSET_KICK_POSIX_H_
#include <grpc/support/sync.h>
struct grpc_kick_pipe_info;
typedef struct grpc_pollset_kick_state {
gpr_mu mu;
int kicked;
struct grpc_kick_pipe_info *pipe_info;
} grpc_pollset_kick_state;
#endif /* __GRPC_INTERNAL_IOMGR_POLLSET_KICK_POSIX_H_ */

@ -131,7 +131,11 @@ static int multipoll_with_poll_pollset_maybe_work(
}
nf = 0;
np = 1;
h->pfds[0].fd = grpc_kick_read_fd(pollset);
h->pfds[0].fd = grpc_pollset_kick_pre_poll(&pollset->kick_state);
if (h->pfds[0].fd < 0) {
/* Already kicked */
return 1;
}
h->pfds[0].events = POLLIN;
h->pfds[0].revents = POLLOUT;
for (i = 0; i < h->fd_count; i++) {
@ -173,7 +177,7 @@ static int multipoll_with_poll_pollset_maybe_work(
/* do nothing */
} else {
if (h->pfds[0].revents & POLLIN) {
grpc_kick_drain(pollset);
grpc_pollset_kick_consume(&pollset->kick_state);
}
for (i = 1; i < np; i++) {
if (h->pfds[i].revents & POLLIN) {
@ -184,6 +188,7 @@ static int multipoll_with_poll_pollset_maybe_work(
}
}
}
grpc_pollset_kick_post_poll(&pollset->kick_state);
end_polling(pollset);
gpr_mu_lock(&pollset->mu);

@ -48,18 +48,6 @@
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
/* kick pipes: we keep a sharded set of pipes to allow breaking from poll.
Ideally this would be 1:1 with pollsets, but we'd like to avoid associating
full kernel objects with each pollset to keep them lightweight, so instead
keep a sharded set and allow associating a pollset with one of the shards.
TODO(ctiller): move this out from this file, and allow an eventfd
implementation on linux */
#define LOG2_KICK_SHARDS 6
#define KICK_SHARDS (1 << LOG2_KICK_SHARDS)
static int g_kick_pipes[KICK_SHARDS][2];
static grpc_pollset g_backup_pollset;
static int g_shutdown_backup_poller;
static gpr_event g_backup_poller_done;
@ -82,65 +70,22 @@ static void backup_poller(void *p) {
gpr_event_set(&g_backup_poller_done, (void *)1);
}
static size_t kick_shard(const grpc_pollset *info) {
size_t x = (size_t)info;
return ((x >> 4) ^ (x >> 9) ^ (x >> 14)) & (KICK_SHARDS - 1);
}
int grpc_kick_read_fd(grpc_pollset *p) {
return g_kick_pipes[kick_shard(p)][0];
}
static int grpc_kick_write_fd(grpc_pollset *p) {
return g_kick_pipes[kick_shard(p)][1];
}
void grpc_pollset_force_kick(grpc_pollset *p) {
char c = 0;
while (write(grpc_kick_write_fd(p), &c, 1) != 1 && errno == EINTR)
;
}
void grpc_pollset_kick(grpc_pollset *p) {
if (!p->counter) return;
grpc_pollset_force_kick(p);
grpc_pollset_kick_kick(&p->kick_state);
}
void grpc_kick_drain(grpc_pollset *p) {
int fd = grpc_kick_read_fd(p);
char buf[128];
int r;
for (;;) {
r = read(fd, buf, sizeof(buf));
if (r > 0) continue;
if (r == 0) return;
switch (errno) {
case EAGAIN:
return;
case EINTR:
continue;
default:
gpr_log(GPR_ERROR, "error reading pipe: %s", strerror(errno));
return;
}
}
}
void grpc_pollset_force_kick(grpc_pollset *p) { grpc_pollset_kick(p); }
/* global state management */
grpc_pollset *grpc_backup_pollset() { return &g_backup_pollset; }
grpc_pollset *grpc_backup_pollset(void) { return &g_backup_pollset; }
void grpc_pollset_global_init() {
int i;
void grpc_pollset_global_init(void) {
gpr_thd_id id;
/* initialize the kick shards */
for (i = 0; i < KICK_SHARDS; i++) {
GPR_ASSERT(0 == pipe(g_kick_pipes[i]));
GPR_ASSERT(grpc_set_socket_nonblocking(g_kick_pipes[i][0], 1));
GPR_ASSERT(grpc_set_socket_nonblocking(g_kick_pipes[i][1], 1));
}
/* Initialize kick fd state */
grpc_pollset_kick_global_init();
/* initialize the backup pollset */
grpc_pollset_init(&g_backup_pollset);
@ -151,9 +96,7 @@ void grpc_pollset_global_init() {
gpr_thd_new(&id, backup_poller, NULL, NULL);
}
void grpc_pollset_global_shutdown() {
int i;
void grpc_pollset_global_shutdown(void) {
/* terminate the backup poller thread */
gpr_mu_lock(&g_backup_pollset.mu);
g_shutdown_backup_poller = 1;
@ -163,11 +106,8 @@ void grpc_pollset_global_shutdown() {
/* destroy the backup pollset */
grpc_pollset_destroy(&g_backup_pollset);
/* destroy the kick shards */
for (i = 0; i < KICK_SHARDS; i++) {
close(g_kick_pipes[i][0]);
close(g_kick_pipes[i][1]);
}
/* destroy the kick pipes */
grpc_pollset_kick_global_destroy();
}
/* main interface */
@ -178,6 +118,7 @@ static void become_unary_pollset(grpc_pollset *pollset, grpc_fd *fd);
void grpc_pollset_init(grpc_pollset *pollset) {
gpr_mu_init(&pollset->mu);
gpr_cv_init(&pollset->cv);
grpc_pollset_kick_init(&pollset->kick_state);
become_empty_pollset(pollset);
}
@ -213,6 +154,7 @@ int grpc_pollset_work(grpc_pollset *pollset, gpr_timespec deadline) {
void grpc_pollset_destroy(grpc_pollset *pollset) {
pollset->vtable->destroy(pollset);
grpc_pollset_kick_destroy(&pollset->kick_state);
gpr_mu_destroy(&pollset->mu);
gpr_cv_destroy(&pollset->cv);
}
@ -290,7 +232,11 @@ static int unary_poll_pollset_maybe_work(grpc_pollset *pollset,
return 1;
}
}
pfd[0].fd = grpc_kick_read_fd(pollset);
pfd[0].fd = grpc_pollset_kick_pre_poll(&pollset->kick_state);
if (pfd[0].fd < 0) {
/* Already kicked */
return 1;
}
pfd[0].events = POLLIN;
pfd[0].revents = 0;
pfd[1].fd = fd->fd;
@ -308,7 +254,7 @@ static int unary_poll_pollset_maybe_work(grpc_pollset *pollset,
/* do nothing */
} else {
if (pfd[0].revents & POLLIN) {
grpc_kick_drain(pollset);
grpc_pollset_kick_consume(&pollset->kick_state);
}
if (pfd[1].revents & POLLIN) {
grpc_fd_become_readable(fd, allow_synchronous_callback);
@ -318,6 +264,8 @@ static int unary_poll_pollset_maybe_work(grpc_pollset *pollset,
}
}
grpc_pollset_kick_post_poll(&pollset->kick_state);
gpr_mu_lock(&pollset->mu);
grpc_fd_end_poll(fd, pollset);
pollset->counter = 0;

@ -36,6 +36,8 @@
#include <grpc/support/sync.h>
#include "src/core/iomgr/pollset_kick.h"
typedef struct grpc_pollset_vtable grpc_pollset_vtable;
/* forward declare only in this file to avoid leaking impl details via
@ -51,6 +53,7 @@ typedef struct grpc_pollset {
const grpc_pollset_vtable *vtable;
gpr_mu mu;
gpr_cv cv;
grpc_pollset_kick_state kick_state;
int counter;
union {
int fd;
@ -86,7 +89,7 @@ void grpc_kick_drain(grpc_pollset *p);
regardless of applications listening to events. Relying on this is slow
however (the backup pollset only listens every 100ms or so) - so it's not
to be relied on. */
grpc_pollset *grpc_backup_pollset();
grpc_pollset *grpc_backup_pollset(void);
/* turn a pollset into a multipoller: platform specific */
void grpc_platform_become_multipoller(grpc_pollset *pollset,

@ -99,7 +99,7 @@ int grpc_set_socket_reuse_addr(int fd, int reuse) {
socklen_t intlen = sizeof(newval);
return 0 == setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) &&
0 == getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &newval, &intlen) &&
newval == val;
(newval != 0) == val;
}
/* disable nagle */
@ -109,13 +109,13 @@ int grpc_set_socket_low_latency(int fd, int low_latency) {
socklen_t intlen = sizeof(newval);
return 0 == setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) &&
0 == getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &newval, &intlen) &&
newval == val;
(newval != 0) == val;
}
static gpr_once g_probe_ipv6_once = GPR_ONCE_INIT;
static int g_ipv6_loopback_available;
static void probe_ipv6_once() {
static void probe_ipv6_once(void) {
int fd = socket(AF_INET6, SOCK_STREAM, 0);
g_ipv6_loopback_available = 0;
if (fd < 0) {
@ -135,7 +135,7 @@ static void probe_ipv6_once() {
}
}
int grpc_ipv6_loopback_available() {
int grpc_ipv6_loopback_available(void) {
gpr_once_init(&g_probe_ipv6_once, probe_ipv6_once);
return g_ipv6_loopback_available;
}

@ -50,12 +50,22 @@ int grpc_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
fd = accept(sockfd, addr, addrlen);
if (fd >= 0) {
flags = fcntl(fd, F_GETFL, 0);
flags |= nonblock ? O_NONBLOCK : 0;
flags |= cloexec ? FD_CLOEXEC : 0;
GPR_ASSERT(fcntl(fd, F_SETFL, flags) == 0);
if (nonblock) {
flags = fcntl(fd, F_GETFL, 0);
if (flags < 0) goto close_and_error;
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) goto close_and_error;
}
if (cloexec) {
flags = fcntl(fd, F_GETFD, 0);
if (flags < 0) goto close_and_error;
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != 0) goto close_and_error;
}
}
return fd;
close_and_error:
close(fd);
return -1;
}
#endif /* GPR_POSIX_SOCKETUTILS */

@ -61,7 +61,7 @@ int grpc_set_socket_low_latency(int fd, int low_latency);
and bind IPv6 sockets, but cannot connect to a getsockname() of [::]:port
without a valid loopback interface. Rather than expose this half-broken
state to library users, we turn off IPv6 sockets. */
int grpc_ipv6_loopback_available();
int grpc_ipv6_loopback_available(void);
/* An enum to keep track of IPv4/IPv6 socket modes.

@ -46,7 +46,7 @@ typedef struct grpc_tcp_server grpc_tcp_server;
typedef void (*grpc_tcp_server_cb)(void *arg, grpc_endpoint *ep);
/* Create a server, initially not bound to any ports */
grpc_tcp_server *grpc_tcp_server_create();
grpc_tcp_server *grpc_tcp_server_create(void);
/* Start listening to bound ports */
void grpc_tcp_server_start(grpc_tcp_server *server, grpc_pollset *pollset,

@ -84,7 +84,7 @@ struct grpc_tcp_server {
size_t port_capacity;
};
grpc_tcp_server *grpc_tcp_server_create() {
grpc_tcp_server *grpc_tcp_server_create(void) {
grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
gpr_mu_init(&s->mu);
gpr_cv_init(&s->cv);
@ -120,7 +120,7 @@ void grpc_tcp_server_destroy(grpc_tcp_server *s) {
}
/* get max listen queue size on linux */
static void init_max_accept_queue_size() {
static void init_max_accept_queue_size(void) {
int n = SOMAXCONN;
char buf[64];
FILE *fp = fopen("/proc/sys/net/core/somaxconn", "r");
@ -147,7 +147,7 @@ static void init_max_accept_queue_size() {
}
}
static int get_max_accept_queue_size() {
static int get_max_accept_queue_size(void) {
gpr_once_init(&s_init_max_accept_queue_size, init_max_accept_queue_size);
return s_max_accept_queue_size;
}
@ -252,7 +252,7 @@ static int add_socket_to_server(grpc_tcp_server *s, int fd,
if (s->nports == s->port_capacity) {
s->port_capacity *= 2;
s->ports =
gpr_realloc(s->ports, sizeof(server_port *) * s->port_capacity);
gpr_realloc(s->ports, sizeof(server_port) * s->port_capacity);
}
sp = &s->ports[s->nports++];
sp->server = s;

@ -157,5 +157,6 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_client_auth_filter = {
call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem, "auth"};
call_op, channel_op, sizeof(call_data),
init_call_elem, destroy_call_elem, sizeof(channel_data),
init_channel_elem, destroy_channel_elem, "auth"};

@ -139,7 +139,7 @@ typedef struct {
typedef struct {
grpc_server_credentials base;
grpc_ssl_config config;
grpc_ssl_server_config config;
} grpc_ssl_server_credentials;
static void ssl_destroy(grpc_credentials *creds) {
@ -152,9 +152,24 @@ static void ssl_destroy(grpc_credentials *creds) {
static void ssl_server_destroy(grpc_server_credentials *creds) {
grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
size_t i;
for (i = 0; i < c->config.num_key_cert_pairs; i++) {
if (c->config.pem_private_keys[i] != NULL) {
gpr_free(c->config.pem_private_keys[i]);
}
if (c->config.pem_cert_chains[i]!= NULL) {
gpr_free(c->config.pem_cert_chains[i]);
}
}
if (c->config.pem_private_keys != NULL) gpr_free(c->config.pem_private_keys);
if (c->config.pem_private_keys_sizes != NULL) {
gpr_free(c->config.pem_private_keys_sizes);
}
if (c->config.pem_cert_chains != NULL) gpr_free(c->config.pem_cert_chains);
if (c->config.pem_cert_chains_sizes != NULL) {
gpr_free(c->config.pem_cert_chains_sizes);
}
if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
if (c->config.pem_private_key != NULL) gpr_free(c->config.pem_private_key);
if (c->config.pem_cert_chain != NULL) gpr_free(c->config.pem_cert_chain);
gpr_free(creds);
}
@ -179,7 +194,7 @@ const grpc_ssl_config *grpc_ssl_credentials_get_config(
}
}
const grpc_ssl_config *grpc_ssl_server_credentials_get_config(
const grpc_ssl_server_config *grpc_ssl_server_credentials_get_config(
const grpc_server_credentials *creds) {
if (creds == NULL || strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
return NULL;
@ -189,57 +204,89 @@ const grpc_ssl_config *grpc_ssl_server_credentials_get_config(
}
}
static void ssl_build_config(const unsigned char *pem_root_certs,
size_t pem_root_certs_size,
const unsigned char *pem_private_key,
size_t pem_private_key_size,
const unsigned char *pem_cert_chain,
size_t pem_cert_chain_size,
static void ssl_copy_key_material(const char *input, unsigned char **output,
size_t *output_size) {
*output_size = strlen(input);
*output = gpr_malloc(*output_size);
memcpy(*output, input, *output_size);
}
static void ssl_build_config(const char *pem_root_certs,
grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
grpc_ssl_config *config) {
if (pem_root_certs == NULL) {
/* TODO(jboeuf): Get them from the environment. */
gpr_log(GPR_ERROR, "Default SSL roots not yet implemented.");
} else {
ssl_copy_key_material(pem_root_certs, &config->pem_root_certs,
&config->pem_root_certs_size);
}
if (pem_key_cert_pair != NULL) {
GPR_ASSERT(pem_key_cert_pair->private_key != NULL);
GPR_ASSERT(pem_key_cert_pair->cert_chain != NULL);
ssl_copy_key_material(pem_key_cert_pair->private_key,
&config->pem_private_key,
&config->pem_private_key_size);
ssl_copy_key_material(pem_key_cert_pair->cert_chain,
&config->pem_cert_chain,
&config->pem_cert_chain_size);
}
}
static void ssl_build_server_config(
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs, grpc_ssl_server_config *config) {
size_t i;
if (pem_root_certs != NULL) {
config->pem_root_certs = gpr_malloc(pem_root_certs_size);
memcpy(config->pem_root_certs, pem_root_certs, pem_root_certs_size);
config->pem_root_certs_size = pem_root_certs_size;
ssl_copy_key_material(pem_root_certs, &config->pem_root_certs,
&config->pem_root_certs_size);
}
if (pem_private_key != NULL) {
config->pem_private_key = gpr_malloc(pem_private_key_size);
memcpy(config->pem_private_key, pem_private_key, pem_private_key_size);
config->pem_private_key_size = pem_private_key_size;
if (num_key_cert_pairs > 0) {
GPR_ASSERT(pem_key_cert_pairs != NULL);
config->pem_private_keys =
gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *));
config->pem_cert_chains =
gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *));
config->pem_private_keys_sizes =
gpr_malloc(num_key_cert_pairs * sizeof(size_t));
config->pem_cert_chains_sizes =
gpr_malloc(num_key_cert_pairs * sizeof(size_t));
}
if (pem_cert_chain != NULL) {
config->pem_cert_chain = gpr_malloc(pem_cert_chain_size);
memcpy(config->pem_cert_chain, pem_cert_chain, pem_cert_chain_size);
config->pem_cert_chain_size = pem_cert_chain_size;
config->num_key_cert_pairs = num_key_cert_pairs;
for (i = 0; i < num_key_cert_pairs; i++) {
GPR_ASSERT(pem_key_cert_pairs[i].private_key != NULL);
GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != NULL);
ssl_copy_key_material(pem_key_cert_pairs[i].private_key,
&config->pem_private_keys[i],
&config->pem_private_keys_sizes[i]);
ssl_copy_key_material(pem_key_cert_pairs[i].cert_chain,
&config->pem_cert_chains[i],
&config->pem_cert_chains_sizes[i]);
}
}
grpc_credentials *grpc_ssl_credentials_create(
const unsigned char *pem_root_certs, size_t pem_root_certs_size,
const unsigned char *pem_private_key, size_t pem_private_key_size,
const unsigned char *pem_cert_chain, size_t pem_cert_chain_size) {
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair) {
grpc_ssl_credentials *c = gpr_malloc(sizeof(grpc_ssl_credentials));
memset(c, 0, sizeof(grpc_ssl_credentials));
c->base.type = GRPC_CREDENTIALS_TYPE_SSL;
c->base.vtable = &ssl_vtable;
gpr_ref_init(&c->base.refcount, 1);
ssl_build_config(pem_root_certs, pem_root_certs_size, pem_private_key,
pem_private_key_size, pem_cert_chain, pem_cert_chain_size,
&c->config);
ssl_build_config(pem_root_certs, pem_key_cert_pair, &c->config);
return &c->base;
}
grpc_server_credentials *grpc_ssl_server_credentials_create(
const unsigned char *pem_root_certs, size_t pem_root_certs_size,
const unsigned char *pem_private_key, size_t pem_private_key_size,
const unsigned char *pem_cert_chain, size_t pem_cert_chain_size) {
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs) {
grpc_ssl_server_credentials *c =
gpr_malloc(sizeof(grpc_ssl_server_credentials));
memset(c, 0, sizeof(grpc_ssl_server_credentials));
c->base.type = GRPC_CREDENTIALS_TYPE_SSL;
c->base.vtable = &ssl_server_vtable;
ssl_build_config(pem_root_certs, pem_root_certs_size, pem_private_key,
pem_private_key_size, pem_cert_chain, pem_cert_chain_size,
&c->config);
ssl_build_server_config(pem_root_certs, pem_key_cert_pairs,
num_key_cert_pairs, &c->config);
return &c->base;
}
@ -637,8 +684,8 @@ grpc_credentials *grpc_fake_transport_security_credentials_create(void) {
return c;
}
grpc_server_credentials *
grpc_fake_transport_security_server_credentials_create() {
grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
void) {
grpc_server_credentials *c = gpr_malloc(sizeof(grpc_server_credentials));
memset(c, 0, sizeof(grpc_server_credentials));
c->type = GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;

@ -137,10 +137,17 @@ struct grpc_server_credentials {
const char *type;
};
/* TODO(jboeuf): Have an ssl_server_config that can contain multiple key/cert
pairs. */
typedef struct {
unsigned char **pem_private_keys;
size_t *pem_private_keys_sizes;
unsigned char **pem_cert_chains;
size_t *pem_cert_chains_sizes;
size_t num_key_cert_pairs;
unsigned char *pem_root_certs;
size_t pem_root_certs_size;
} grpc_ssl_server_config;
const grpc_ssl_config *grpc_ssl_server_credentials_get_config(
const grpc_ssl_server_config *grpc_ssl_server_credentials_get_config(
const grpc_server_credentials *ssl_creds);
#endif /* __GRPC_INTERNAL_SECURITY_CREDENTIALS_H__ */

@ -126,8 +126,8 @@ static void on_read(void *user_data, gpr_slice *slices, size_t nslices,
size_t message_size = GPR_SLICE_LENGTH(encrypted);
while (message_size > 0 || keep_looping) {
gpr_uint32 unprotected_buffer_size_written = end - cur;
gpr_uint32 processed_message_size = message_size;
size_t unprotected_buffer_size_written = end - cur;
size_t processed_message_size = message_size;
gpr_mu_lock(&ep->protector_mu);
result = tsi_frame_protector_unprotect(ep->protector, message_bytes,
&processed_message_size, cur,
@ -245,8 +245,8 @@ static grpc_endpoint_write_status endpoint_write(grpc_endpoint *secure_ep,
gpr_uint8 *message_bytes = GPR_SLICE_START_PTR(plain);
size_t message_size = GPR_SLICE_LENGTH(plain);
while (message_size > 0) {
gpr_uint32 protected_buffer_size_to_send = end - cur;
gpr_uint32 processed_message_size = message_size;
size_t protected_buffer_size_to_send = end - cur;
size_t processed_message_size = message_size;
gpr_mu_lock(&ep->protector_mu);
result = tsi_frame_protector_protect(ep->protector, message_bytes,
&processed_message_size, cur,
@ -268,9 +268,9 @@ static grpc_endpoint_write_status endpoint_write(grpc_endpoint *secure_ep,
if (result != TSI_OK) break;
}
if (result == TSI_OK) {
gpr_uint32 still_pending_size;
size_t still_pending_size;
do {
gpr_uint32 protected_buffer_size_to_send = end - cur;
size_t protected_buffer_size_to_send = end - cur;
gpr_mu_lock(&ep->protector_mu);
result = tsi_frame_protector_protect_flush(ep->protector, cur,
&protected_buffer_size_to_send,

@ -131,7 +131,7 @@ static void send_handshake_bytes_to_peer(grpc_secure_transport_setup *s) {
grpc_endpoint_write_status write_status;
do {
uint32_t to_send_size = s->handshake_buffer_size - offset;
size_t to_send_size = s->handshake_buffer_size - offset;
result = tsi_handshaker_get_bytes_to_send_to_peer(
s->handshaker, s->handshake_buffer + offset, &to_send_size);
offset += to_send_size;
@ -174,7 +174,7 @@ static void on_handshake_data_received_from_peer(
void *setup, gpr_slice *slices, size_t nslices,
grpc_endpoint_cb_status error) {
grpc_secure_transport_setup *s = setup;
uint32_t consumed_slice_size = 0;
size_t consumed_slice_size = 0;
tsi_result result = TSI_OK;
size_t i;
size_t num_left_overs;

@ -382,7 +382,7 @@ error:
}
grpc_security_status grpc_ssl_server_security_context_create(
const grpc_ssl_config *config, grpc_security_context **ctx) {
const grpc_ssl_server_config *config, grpc_security_context **ctx) {
size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
const unsigned char **alpn_protocol_strings =
gpr_malloc(sizeof(const char *) * num_alpn_protocols);
@ -399,8 +399,7 @@ grpc_security_status grpc_ssl_server_security_context_create(
strlen(grpc_chttp2_get_alpn_version_index(i));
}
if (config == NULL || config->pem_private_key == NULL ||
config->pem_cert_chain == NULL) {
if (config == NULL || config->num_key_cert_pairs == 0) {
gpr_log(GPR_ERROR, "An SSL server needs a key and a cert.");
goto error;
}
@ -410,10 +409,10 @@ grpc_security_status grpc_ssl_server_security_context_create(
gpr_ref_init(&c->base.refcount, 1);
c->base.vtable = &ssl_server_vtable;
result = tsi_create_ssl_server_handshaker_factory(
(const unsigned char **)&config->pem_private_key,
(const gpr_uint32 *)&config->pem_private_key_size,
(const unsigned char **)&config->pem_cert_chain,
(const gpr_uint32 *)&config->pem_cert_chain_size, 1,
(const unsigned char **)config->pem_private_keys,
config->pem_private_keys_sizes,
(const unsigned char **)config->pem_cert_chains,
config->pem_cert_chains_sizes, config->num_key_cert_pairs,
config->pem_root_certs, config->pem_root_certs_size,
GRPC_SSL_CIPHER_SUITES, alpn_protocol_strings,
alpn_protocol_string_lengths, num_alpn_protocols, &c->handshaker_factory);

@ -157,7 +157,7 @@ grpc_security_status grpc_ssl_channel_security_context_create(
specific error code otherwise.
*/
grpc_security_status grpc_ssl_server_security_context_create(
const grpc_ssl_config *config, grpc_security_context **ctx);
const grpc_ssl_server_config *config, grpc_security_context **ctx);
/* --- Creation of high level objects. --- */

@ -93,6 +93,8 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) {
grpc_tcp_server *tcp = NULL;
size_t i;
int count = 0;
int port_num = -1;
int port_temp;
resolved = grpc_blocking_resolve_address(addr, "https");
if (!resolved) {
@ -105,9 +107,15 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) {
}
for (i = 0; i < resolved->naddrs; i++) {
if (grpc_tcp_server_add_port(tcp,
(struct sockaddr *)&resolved->addrs[i].addr,
resolved->addrs[i].len)) {
port_temp = grpc_tcp_server_add_port(
tcp, (struct sockaddr *)&resolved->addrs[i].addr,
resolved->addrs[i].len);
if (port_temp >= 0) {
if (port_num == -1) {
port_num = port_temp;
} else {
GPR_ASSERT(port_num == port_temp);
}
count++;
}
}
@ -125,7 +133,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) {
/* Register with the server only upon success */
grpc_server_add_listener(server, tcp, start, destroy);
return 1;
return port_num;
/* Error path: cleanup and return */
error:

@ -37,13 +37,13 @@
#include "src/core/statistics/census_rpc_stats.h"
#include "src/core/statistics/census_tracing.h"
void census_init() {
void census_init(void) {
gpr_log(GPR_INFO, "Initialize census library.");
census_tracing_init();
census_stats_store_init();
}
void census_shutdown() {
void census_shutdown(void) {
gpr_log(GPR_INFO, "Shutdown census library.");
census_stats_store_shutdown();
census_tracing_shutdown();

@ -49,10 +49,10 @@ typedef struct census_op_id {
typedef struct census_rpc_stats census_rpc_stats;
/* Initializes Census library. No-op if Census is already initialized. */
void census_init();
void census_init(void);
/* Shutdown Census Library. */
void census_shutdown();
void census_shutdown(void);
/* Annotates grpc method name on a census_op_id. The method name has the format
of <full quantified rpc service name>/<rpc function name>. Returns 0 iff
@ -68,7 +68,7 @@ int census_add_method_tag(census_op_id op_id, const char* method_name);
void census_tracing_print(census_op_id op_id, const char* annotation);
/* Starts tracing for an RPC. Returns a locally unique census_op_id */
census_op_id census_tracing_start_op();
census_op_id census_tracing_start_op(void);
/* Ends tracing. Calling this function will invalidate the input op_id. */
void census_tracing_end_op(census_op_id op_id);

@ -368,7 +368,7 @@ static void cl_block_end_read(cl_block* block) {
/* Allocates a new free block (or recycles an available dirty block if log is
configured to discard old records). Returns NULL if out-of-space. */
static cl_block* cl_allocate_block() {
static cl_block* cl_allocate_block(void) {
cl_block* block = cl_block_list_head(&g_log.free_block_list);
if (block != NULL) {
cl_block_list_remove(&g_log.free_block_list, block);
@ -496,7 +496,7 @@ void census_log_initialize(size_t size_in_mb, int discard_old_records) {
g_log.initialized = 1;
}
void census_log_shutdown() {
void census_log_shutdown(void) {
GPR_ASSERT(g_log.initialized);
gpr_mu_destroy(&g_log.lock);
gpr_free_aligned(g_log.core_local_blocks);
@ -551,7 +551,7 @@ void census_log_end_write(void* record, size_t bytes_written) {
cl_block_end_write(cl_get_block(record), bytes_written);
}
void census_log_init_reader() {
void census_log_init_reader(void) {
GPR_ASSERT(g_log.initialized);
gpr_mu_lock(&g_log.lock);
/* If a block is locked for reading unlock it. */
@ -584,7 +584,7 @@ const void* census_log_read_next(size_t* bytes_available) {
return NULL;
}
size_t census_log_remaining_space() {
size_t census_log_remaining_space(void) {
size_t space;
GPR_ASSERT(g_log.initialized);
gpr_mu_lock(&g_log.lock);
@ -598,7 +598,7 @@ size_t census_log_remaining_space() {
return space;
}
int census_log_out_of_space_count() {
int census_log_out_of_space_count(void) {
GPR_ASSERT(g_log.initialized);
return gpr_atm_acq_load(&g_log.out_of_space_count);
}

@ -53,7 +53,7 @@ void census_log_initialize(size_t size_in_mb, int discard_old_records);
- no in progress or future call to any census_log functions
- no incomplete records
*/
void census_log_shutdown();
void census_log_shutdown(void);
/* Allocates and returns a 'size' bytes record and marks it in use. A
subsequent census_log_end_write() marks the record complete. The
@ -74,7 +74,7 @@ void census_log_end_write(void* record, size_t bytes_written);
is read. census_log_init_reader() starts the iteration or aborts the
current iteration.
*/
void census_log_init_reader();
void census_log_init_reader(void);
const void* census_log_read_next(size_t* bytes_available);
/* Returns estimated remaining space across all blocks, in bytes. If log is
@ -82,10 +82,10 @@ const void* census_log_read_next(size_t* bytes_available);
returns space available in empty blocks (partially filled blocks are
treated as full).
*/
size_t census_log_remaining_space();
size_t census_log_remaining_space(void);
/* Returns the number of times gprc_stats_log_start_write() failed due to
out-of-space. */
int census_log_out_of_space_count();
int census_log_out_of_space_count(void);
#endif /* __GRPC_INTERNAL_STATISTICS_LOG_H__ */

@ -59,9 +59,9 @@ static gpr_mu g_mu;
static census_ht* g_client_stats_store = NULL;
static census_ht* g_server_stats_store = NULL;
static void init_mutex() { gpr_mu_init(&g_mu); }
static void init_mutex(void) { gpr_mu_init(&g_mu); }
static void init_mutex_once() {
static void init_mutex_once(void) {
gpr_once_init(&g_stats_store_mu_init, init_mutex);
}
@ -85,8 +85,9 @@ static void delete_key(void* key) { gpr_free(key); }
static const census_ht_option ht_opt = {
CENSUS_HT_POINTER /* key type */, 1999 /* n_of_buckets */,
simple_hash /* hash function */, cmp_str_keys /* key comparator */,
delete_stats /* data deleter */, delete_key /* key deleter */};
simple_hash /* hash function */, cmp_str_keys /* key comparator */,
delete_stats /* data deleter */, delete_key /* key deleter */
};
static void init_rpc_stats(void* stats) {
memset(stats, 0, sizeof(census_rpc_stats));
@ -115,7 +116,7 @@ static gpr_timespec min_hour_total_intervals[3] = {
static const census_window_stats_stat_info window_stats_settings = {
sizeof(census_rpc_stats), init_rpc_stats, stat_add, stat_add_proportion};
census_rpc_stats* census_rpc_stats_create_empty() {
census_rpc_stats* census_rpc_stats_create_empty(void) {
census_rpc_stats* ret =
(census_rpc_stats*)gpr_malloc(sizeof(census_rpc_stats));
memset(ret, 0, sizeof(census_rpc_stats));
@ -220,7 +221,7 @@ void census_get_server_stats(census_aggregated_rpc_stats* data) {
get_stats(g_server_stats_store, data);
}
void census_stats_store_init() {
void census_stats_store_init(void) {
gpr_log(GPR_INFO, "Initialize census stats store.");
init_mutex_once();
gpr_mu_lock(&g_mu);
@ -233,7 +234,7 @@ void census_stats_store_init() {
gpr_mu_unlock(&g_mu);
}
void census_stats_store_shutdown() {
void census_stats_store_shutdown(void) {
gpr_log(GPR_INFO, "Shutdown census stats store.");
init_mutex_once();
gpr_mu_lock(&g_mu);

@ -53,7 +53,7 @@ struct census_rpc_stats {
};
/* Creates an empty rpc stats object on heap. */
census_rpc_stats* census_rpc_stats_create_empty();
census_rpc_stats* census_rpc_stats_create_empty(void);
typedef struct census_per_method_rpc_stats {
const char* method;
@ -91,8 +91,8 @@ void census_get_server_stats(census_aggregated_rpc_stats* data_map);
DO NOT CALL from outside of grpc code. */
void census_get_client_stats(census_aggregated_rpc_stats* data_map);
void census_stats_store_init();
void census_stats_store_shutdown();
void census_stats_store_init(void);
void census_stats_store_shutdown(void);
#ifdef __cplusplus
}

@ -76,7 +76,8 @@ static void delete_trace_obj(void* obj) { trace_obj_destroy((trace_obj*)obj); }
static const census_ht_option ht_opt = {
CENSUS_HT_UINT64 /* key type*/, 571 /* n_of_buckets */, NULL /* hash */,
NULL /* compare_keys */, delete_trace_obj /* delete data */,
NULL /* delete key */};
NULL /* delete key */
};
static gpr_once g_init_mutex_once = GPR_ONCE_INIT;
static gpr_mu g_mu; /* Guards following two static variables. */
@ -93,11 +94,13 @@ static gpr_uint64 op_id_2_uint64(census_op_id* id) {
return ret;
}
static void init_mutex() { gpr_mu_init(&g_mu); }
static void init_mutex(void) { gpr_mu_init(&g_mu); }
static void init_mutex_once() { gpr_once_init(&g_init_mutex_once, init_mutex); }
static void init_mutex_once(void) {
gpr_once_init(&g_init_mutex_once, init_mutex);
}
census_op_id census_tracing_start_op() {
census_op_id census_tracing_start_op(void) {
gpr_mu_lock(&g_mu);
{
trace_obj* ret = (trace_obj*)gpr_malloc(sizeof(trace_obj));
@ -164,7 +167,7 @@ void census_tracing_end_op(census_op_id op_id) {
gpr_mu_unlock(&g_mu);
}
void census_tracing_init() {
void census_tracing_init(void) {
gpr_log(GPR_INFO, "Initialize census trace store.");
init_mutex_once();
gpr_mu_lock(&g_mu);
@ -177,7 +180,7 @@ void census_tracing_init() {
gpr_mu_unlock(&g_mu);
}
void census_tracing_shutdown() {
void census_tracing_shutdown(void) {
gpr_log(GPR_INFO, "Shutdown census trace store.");
gpr_mu_lock(&g_mu);
if (g_trace_store != NULL) {
@ -189,9 +192,9 @@ void census_tracing_shutdown() {
gpr_mu_unlock(&g_mu);
}
void census_internal_lock_trace_store() { gpr_mu_lock(&g_mu); }
void census_internal_lock_trace_store(void) { gpr_mu_lock(&g_mu); }
void census_internal_unlock_trace_store() { gpr_mu_unlock(&g_mu); }
void census_internal_unlock_trace_store(void) { gpr_mu_unlock(&g_mu); }
trace_obj* census_get_trace_obj_locked(census_op_id op_id) {
if (g_trace_store == NULL) {

@ -38,10 +38,10 @@
typedef struct trace_obj trace_obj;
/* Initializes trace store. This function is thread safe. */
void census_tracing_init();
void census_tracing_init(void);
/* Shutsdown trace store. This function is thread safe. */
void census_tracing_shutdown();
void census_tracing_shutdown(void);
/* Gets trace obj corresponding to the input op_id. Returns NULL if trace store
is not initialized or trace obj is not found. Requires trace store being
@ -50,8 +50,8 @@ trace_obj* census_get_trace_obj_locked(census_op_id op_id);
/* The following two functions acquire and release the trace store global lock.
They are for census internal use only. */
void census_internal_lock_trace_store();
void census_internal_unlock_trace_store();
void census_internal_lock_trace_store(void);
void census_internal_unlock_trace_store(void);
/* Gets method tag name associated with the input trace object. */
const char* census_get_trace_method_name(const trace_obj* trace);

@ -38,12 +38,12 @@
/* Return the number of CPU cores on the current system. Will return 0 if
if information is not available. */
int gpr_cpu_num_cores();
int gpr_cpu_num_cores(void);
/* Return the CPU on which the current thread is executing; N.B. This should
be considered advisory only - it is possible that the thread is switched
to a different CPU at any time. Returns a value in range
[0, gpr_cpu_num_cores() - 1] */
int gpr_cpu_current_cpu();
int gpr_cpu_current_cpu(void);
#endif /* __GRPC_INTERNAL_SUPPORT_CPU_H__ */

@ -75,7 +75,7 @@
#include <grpc/support/log.h>
int gpr_cpu_num_cores() {
int gpr_cpu_num_cores(void) {
static int ncpus = 0;
if (ncpus == 0) {
ncpus = sysconf(_SC_NPROCESSORS_ONLN);
@ -87,7 +87,7 @@ int gpr_cpu_num_cores() {
return ncpus;
}
int gpr_cpu_current_cpu() {
int gpr_cpu_current_cpu(void) {
int cpu = sched_getcpu();
if (cpu < 0) {
gpr_log(GPR_ERROR, "Error determining current CPU: %s\n", strerror(errno));

@ -45,7 +45,7 @@
static __thread char magic_thread_local;
int gpr_cpu_num_cores() {
int gpr_cpu_num_cores(void) {
static int ncpus = 0;
if (ncpus == 0) {
ncpus = sysconf(_SC_NPROCESSORS_ONLN);
@ -63,7 +63,7 @@ static size_t shard_ptr(const void *info) {
return ((x >> 4) ^ (x >> 9) ^ (x >> 14)) % gpr_cpu_num_cores();
}
int gpr_cpu_current_cpu() {
int gpr_cpu_current_cpu(void) {
/* NOTE: there's no way I know to return the actual cpu index portably...
most code that's using this is using it to shard across work queues though,
so here we use thread identity instead to achieve a similar though not

@ -47,7 +47,7 @@
#include <sys/syscall.h>
#include <unistd.h>
static long gettid() { return syscall(__NR_gettid); }
static long gettid(void) { return syscall(__NR_gettid); }
void gpr_log(const char *file, int line, gpr_log_severity severity,
const char *format, ...) {

@ -50,7 +50,7 @@
#include <time.h>
#include <pthread.h>
static gpr_intptr gettid() { return (gpr_intptr)pthread_self(); }
static gpr_intptr gettid(void) { return (gpr_intptr)pthread_self(); }
void gpr_log(const char *file, int line, gpr_log_severity severity,
const char *format, ...) {

@ -46,8 +46,8 @@
handle aligned reads, do the conversion here */
#define GETBLOCK32(p, i) (p)[(i)]
gpr_uint32 gpr_murmur_hash3(const void* key, size_t len, gpr_uint32 seed) {
const gpr_uint8* data = (const gpr_uint8*)key;
gpr_uint32 gpr_murmur_hash3(const void *key, size_t len, gpr_uint32 seed) {
const gpr_uint8 *data = (const gpr_uint8 *)key;
const int nblocks = len / 4;
int i;
@ -57,8 +57,8 @@ gpr_uint32 gpr_murmur_hash3(const void* key, size_t len, gpr_uint32 seed) {
const gpr_uint32 c1 = 0xcc9e2d51;
const gpr_uint32 c2 = 0x1b873593;
const gpr_uint32* blocks = (const uint32_t*)(data + nblocks * 4);
const uint8_t* tail = (const uint8_t*)(data + nblocks * 4);
const gpr_uint32 *blocks = (const uint32_t *)(data + nblocks * 4);
const uint8_t *tail = (const uint8_t *)(data + nblocks * 4);
/* body */
for (i = -nblocks; i; i++) {

@ -37,7 +37,7 @@
#include <string.h>
gpr_slice gpr_empty_slice() {
gpr_slice gpr_empty_slice(void) {
gpr_slice out;
out.refcount = 0;
out.data.inlined.length = 0;

@ -63,7 +63,7 @@ typedef struct {
char *data;
} hexout;
static hexout hexout_create() {
static hexout hexout_create(void) {
hexout r = {0, 0, NULL};
return r;
}

@ -61,7 +61,7 @@ gpr_timespec gpr_now(void) {
struct timeval now_tv;
gettimeofday(&now_tv, NULL);
now.tv_sec = now_tv.tv_sec;
now.tv_nsec = now_tv.tv_usec / 1000;
now.tv_nsec = now_tv.tv_usec * 1000;
return now;
}
#endif

@ -198,7 +198,7 @@ struct grpc_call {
gpr_refcount internal_refcount;
};
#define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call) + 1))
#define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call)+1))
#define CALL_FROM_CALL_STACK(call_stack) (((grpc_call *)(call_stack)) - 1)
#define CALL_ELEM_FROM_CALL(call, idx) \
grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx)
@ -535,17 +535,6 @@ grpc_call_error grpc_call_server_end_initial_metadata(grpc_call *call,
return GRPC_CALL_OK;
}
grpc_call_error grpc_call_accept(grpc_call *call, grpc_completion_queue *cq,
void *finished_tag, gpr_uint32 flags) {
grpc_call_error err;
err = grpc_call_server_accept(call, cq, finished_tag);
if (err != GRPC_CALL_OK) return err;
err = grpc_call_server_end_initial_metadata(call, flags);
if (err != GRPC_CALL_OK) return err;
return GRPC_CALL_OK;
}
static void done_writes_done(void *user_data, grpc_op_error error) {
grpc_call *call = user_data;
void *tag = call->write_tag;
@ -812,7 +801,7 @@ static gpr_uint32 decode_status(grpc_mdelem *md) {
gpr_uint32 status;
void *user_data = grpc_mdelem_get_user_data(md, destroy_status);
if (user_data) {
status = ((gpr_uint32)(gpr_intptr)user_data) - STATUS_OFFSET;
status = ((gpr_uint32)(gpr_intptr) user_data) - STATUS_OFFSET;
} else {
if (!gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value),
GPR_SLICE_LENGTH(md->value->slice),
@ -908,7 +897,12 @@ grpc_metadata_buffer *grpc_call_get_metadata_buffer(grpc_call *call) {
static void call_alarm(void *arg, int success) {
grpc_call *call = arg;
if (success) {
grpc_call_cancel(call);
if (call->is_client) {
grpc_call_cancel_with_status(call, GRPC_STATUS_DEADLINE_EXCEEDED,
"Deadline Exceeded");
} else {
grpc_call_cancel(call);
}
}
grpc_call_internal_unref(call);
}

@ -51,7 +51,7 @@ struct grpc_channel {
grpc_mdstr *authority_string;
};
#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c) + 1))
#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c)+1))
grpc_channel *grpc_channel_create_from_filters(
const grpc_channel_filter **filters, size_t num_filters,

@ -109,9 +109,9 @@ static void init_channel_elem(grpc_channel_element *elem,
static void destroy_channel_elem(grpc_channel_element *elem) {}
const grpc_channel_filter grpc_client_surface_filter = {
call_op, channel_op,
call_op, channel_op,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,

@ -85,7 +85,7 @@ struct grpc_completion_queue {
/* Default do-nothing on_finish function */
static void null_on_finish(void *user_data, grpc_op_error error) {}
grpc_completion_queue *grpc_completion_queue_create() {
grpc_completion_queue *grpc_completion_queue_create(void) {
grpc_completion_queue *cc = gpr_malloc(sizeof(grpc_completion_queue));
memset(cc, 0, sizeof(*cc));
/* Initial ref is dropped by grpc_completion_queue_shutdown */
@ -155,6 +155,13 @@ static void end_op_locked(grpc_completion_queue *cc,
}
}
void grpc_cq_end_server_shutdown(grpc_completion_queue *cc, void *tag) {
gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
add_locked(cc, GRPC_SERVER_SHUTDOWN, tag, NULL, NULL, NULL);
end_op_locked(cc, GRPC_SERVER_SHUTDOWN);
gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
}
void grpc_cq_end_read(grpc_completion_queue *cc, void *tag, grpc_call *call,
grpc_event_finish_func on_finish, void *user_data,
grpc_byte_buffer *read) {
@ -251,7 +258,7 @@ void grpc_cq_end_new_rpc(grpc_completion_queue *cc, void *tag, grpc_call *call,
}
/* Create a GRPC_QUEUE_SHUTDOWN event without queuing it anywhere */
static event *create_shutdown_event() {
static event *create_shutdown_event(void) {
event *ev = gpr_malloc(sizeof(event));
ev->base.type = GRPC_QUEUE_SHUTDOWN;
ev->base.call = NULL;

@ -97,6 +97,8 @@ void grpc_cq_end_new_rpc(grpc_completion_queue *cc, void *tag, grpc_call *call,
gpr_timespec deadline, size_t metadata_count,
grpc_metadata *metadata_elements);
void grpc_cq_end_server_shutdown(grpc_completion_queue *cc, void *tag);
/* disable polling for some tests */
void grpc_completion_queue_dont_poll_test_only(grpc_completion_queue *cc);

@ -63,6 +63,9 @@ char *grpc_event_string(grpc_event *ev) {
if (ev == NULL) return gpr_strdup("null");
switch (ev->type) {
case GRPC_SERVER_SHUTDOWN:
p += sprintf(p, "SERVER_SHUTDOWN");
break;
case GRPC_QUEUE_SHUTDOWN:
p += sprintf(p, "QUEUE_SHUTDOWN");
break;

@ -35,12 +35,12 @@
#include "src/core/statistics/census_interface.h"
#include "src/core/iomgr/iomgr.h"
void grpc_init() {
void grpc_init(void) {
grpc_iomgr_init();
census_init();
}
void grpc_shutdown() {
void grpc_shutdown(void) {
grpc_iomgr_shutdown();
census_shutdown();
}

@ -111,9 +111,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
static const grpc_channel_filter lame_filter = {
call_op, channel_op,
call_op, channel_op,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,

@ -81,6 +81,8 @@ struct grpc_server {
size_t tag_cap;
gpr_uint8 shutdown;
gpr_uint8 have_shutdown_tag;
void *shutdown_tag;
call_data *lists[CALL_LIST_COUNT];
channel_data root_channel_data;
@ -375,6 +377,10 @@ static void destroy_call_elem(grpc_call_element *elem) {
for (i = 0; i < CALL_LIST_COUNT; i++) {
call_list_remove(chand->server, elem->call_data, i);
}
if (chand->server->shutdown && chand->server->have_shutdown_tag &&
chand->server->lists[ALL_CALLS] == NULL) {
grpc_cq_end_server_shutdown(chand->server->cq, chand->server->shutdown_tag);
}
gpr_mu_unlock(&chand->server->mu);
server_unref(chand->server);
@ -405,9 +411,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
static const grpc_channel_filter server_surface_filter = {
call_op, channel_op,
call_op, channel_op,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(call_data), init_call_elem, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,
@ -513,7 +519,8 @@ grpc_transport_setup_result grpc_server_setup_transport(
grpc_channel_get_channel_stack(channel), transport);
}
void grpc_server_shutdown(grpc_server *server) {
void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag,
void *shutdown_tag) {
listener *l;
void **tags;
size_t ntags;
@ -551,6 +558,14 @@ void grpc_server_shutdown(grpc_server *server) {
server->ntags = 0;
server->shutdown = 1;
server->have_shutdown_tag = have_shutdown_tag;
server->shutdown_tag = shutdown_tag;
if (have_shutdown_tag) {
grpc_cq_begin_op(server->cq, NULL, GRPC_SERVER_SHUTDOWN);
if (server->lists[ALL_CALLS] == NULL) {
grpc_cq_end_server_shutdown(server->cq, shutdown_tag);
}
}
gpr_mu_unlock(&server->mu);
for (i = 0; i < nchannels; i++) {
@ -583,6 +598,14 @@ void grpc_server_shutdown(grpc_server *server) {
}
}
void grpc_server_shutdown(grpc_server *server) {
shutdown_internal(server, 0, NULL);
}
void grpc_server_shutdown_and_notify(grpc_server *server, void *tag) {
shutdown_internal(server, 1, tag);
}
void grpc_server_destroy(grpc_server *server) {
channel_data *c;
gpr_mu_lock(&server->mu);

@ -46,7 +46,7 @@ int grpc_chttp2_is_alpn_version_supported(const char *version, size_t size) {
return 0;
}
size_t grpc_chttp2_num_alpn_versions() {
size_t grpc_chttp2_num_alpn_versions(void) {
return GPR_ARRAY_SIZE(supported_versions);
}

@ -40,7 +40,7 @@
int grpc_chttp2_is_alpn_version_supported(const char *version, size_t size);
/* Returns the number of protocol versions to advertise */
size_t grpc_chttp2_num_alpn_versions();
size_t grpc_chttp2_num_alpn_versions(void);
/* Returns the protocol version at index i (0 <= i <
* grpc_chttp2_num_alpn_versions()) */

@ -102,7 +102,7 @@ gpr_slice grpc_chttp2_settings_create(gpr_uint32 *old, const gpr_uint32 *new,
return output;
}
gpr_slice grpc_chttp2_settings_ack_create() {
gpr_slice grpc_chttp2_settings_ack_create(void) {
gpr_slice output = gpr_slice_malloc(9);
fill_header(GPR_SLICE_START_PTR(output), 0, GRPC_CHTTP2_FLAG_ACK);
return output;

@ -88,7 +88,7 @@ extern const grpc_chttp2_setting_parameters
gpr_slice grpc_chttp2_settings_create(gpr_uint32 *old, const gpr_uint32 *new,
gpr_uint32 force_mask, size_t count);
/* Create an ack settings frame */
gpr_slice grpc_chttp2_settings_ack_create();
gpr_slice grpc_chttp2_settings_ack_create(void);
grpc_chttp2_parse_error grpc_chttp2_settings_parser_begin_frame(
grpc_chttp2_settings_parser *parser, gpr_uint32 length, gpr_uint8 flags,

@ -86,7 +86,7 @@ static unsigned char suffix_mask(unsigned char prefix_len) {
return ~prefix_mask(prefix_len);
}
static void generate_first_byte_lut() {
static void generate_first_byte_lut(void) {
int i, j, n;
const spec *chrspec;
unsigned char suffix;
@ -136,21 +136,21 @@ typedef struct { char included[GRPC_CHTTP2_NUM_HUFFSYMS]; } symset;
typedef struct { int values[16]; } nibblelut;
/* returns a symset that includes all possible symbols */
static symset symset_all() {
static symset symset_all(void) {
symset x;
memset(x.included, 1, sizeof(x.included));
return x;
}
/* returns a symset that includes no symbols */
static symset symset_none() {
static symset symset_none(void) {
symset x;
memset(x.included, 0, sizeof(x.included));
return x;
}
/* returns an empty nibblelut */
static nibblelut nibblelut_empty() {
static nibblelut nibblelut_empty(void) {
nibblelut x;
int i;
for (i = 0; i < 16; i++) {
@ -296,7 +296,7 @@ static void dump_ctbl(const char *name) {
printf("};\n");
}
static void generate_huff_tables() {
static void generate_huff_tables(void) {
int i;
build_dec_tbl(state_index(0, symset_all(), &i), 0, 0, 0, -1, symset_all());
@ -317,7 +317,7 @@ static void generate_huff_tables() {
dump_ctbl("emit_sub_tbl");
}
static void generate_base64_huff_encoder_table() {
static void generate_base64_huff_encoder_table(void) {
static const char alphabet[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int i;
@ -332,7 +332,7 @@ static void generate_base64_huff_encoder_table() {
printf("};\n");
}
static void generate_base64_inverse_table() {
static void generate_base64_inverse_table(void) {
static const char alphabet[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
unsigned char inverse[256];

@ -43,68 +43,68 @@ static struct {
const char *key;
const char *value;
} static_table[] = {
/* 0: */ {NULL, NULL},
/* 1: */ {":authority", ""},
/* 2: */ {":method", "GET"},
/* 3: */ {":method", "POST"},
/* 4: */ {":path", "/"},
/* 5: */ {":path", "/index.html"},
/* 6: */ {":scheme", "http"},
/* 7: */ {":scheme", "https"},
/* 8: */ {":status", "200"},
/* 9: */ {":status", "204"},
/* 10: */ {":status", "206"},
/* 11: */ {":status", "304"},
/* 12: */ {":status", "400"},
/* 13: */ {":status", "404"},
/* 14: */ {":status", "500"},
/* 15: */ {"accept-charset", ""},
/* 16: */ {"accept-encoding", "gzip, deflate"},
/* 17: */ {"accept-language", ""},
/* 18: */ {"accept-ranges", ""},
/* 19: */ {"accept", ""},
/* 20: */ {"access-control-allow-origin", ""},
/* 21: */ {"age", ""},
/* 22: */ {"allow", ""},
/* 23: */ {"authorization", ""},
/* 24: */ {"cache-control", ""},
/* 25: */ {"content-disposition", ""},
/* 26: */ {"content-encoding", ""},
/* 27: */ {"content-language", ""},
/* 28: */ {"content-length", ""},
/* 29: */ {"content-location", ""},
/* 30: */ {"content-range", ""},
/* 31: */ {"content-type", ""},
/* 32: */ {"cookie", ""},
/* 33: */ {"date", ""},
/* 34: */ {"etag", ""},
/* 35: */ {"expect", ""},
/* 36: */ {"expires", ""},
/* 37: */ {"from", ""},
/* 38: */ {"host", ""},
/* 39: */ {"if-match", ""},
/* 40: */ {"if-modified-since", ""},
/* 41: */ {"if-none-match", ""},
/* 42: */ {"if-range", ""},
/* 43: */ {"if-unmodified-since", ""},
/* 44: */ {"last-modified", ""},
/* 45: */ {"link", ""},
/* 46: */ {"location", ""},
/* 47: */ {"max-forwards", ""},
/* 48: */ {"proxy-authenticate", ""},
/* 49: */ {"proxy-authorization", ""},
/* 50: */ {"range", ""},
/* 51: */ {"referer", ""},
/* 52: */ {"refresh", ""},
/* 53: */ {"retry-after", ""},
/* 54: */ {"server", ""},
/* 55: */ {"set-cookie", ""},
/* 56: */ {"strict-transport-security", ""},
/* 57: */ {"transfer-encoding", ""},
/* 58: */ {"user-agent", ""},
/* 59: */ {"vary", ""},
/* 60: */ {"via", ""},
/* 61: */ {"www-authenticate", ""},
/* 0: */ {NULL, NULL},
/* 1: */ {":authority", ""},
/* 2: */ {":method", "GET"},
/* 3: */ {":method", "POST"},
/* 4: */ {":path", "/"},
/* 5: */ {":path", "/index.html"},
/* 6: */ {":scheme", "http"},
/* 7: */ {":scheme", "https"},
/* 8: */ {":status", "200"},
/* 9: */ {":status", "204"},
/* 10: */ {":status", "206"},
/* 11: */ {":status", "304"},
/* 12: */ {":status", "400"},
/* 13: */ {":status", "404"},
/* 14: */ {":status", "500"},
/* 15: */ {"accept-charset", ""},
/* 16: */ {"accept-encoding", "gzip, deflate"},
/* 17: */ {"accept-language", ""},
/* 18: */ {"accept-ranges", ""},
/* 19: */ {"accept", ""},
/* 20: */ {"access-control-allow-origin", ""},
/* 21: */ {"age", ""},
/* 22: */ {"allow", ""},
/* 23: */ {"authorization", ""},
/* 24: */ {"cache-control", ""},
/* 25: */ {"content-disposition", ""},
/* 26: */ {"content-encoding", ""},
/* 27: */ {"content-language", ""},
/* 28: */ {"content-length", ""},
/* 29: */ {"content-location", ""},
/* 30: */ {"content-range", ""},
/* 31: */ {"content-type", ""},
/* 32: */ {"cookie", ""},
/* 33: */ {"date", ""},
/* 34: */ {"etag", ""},
/* 35: */ {"expect", ""},
/* 36: */ {"expires", ""},
/* 37: */ {"from", ""},
/* 38: */ {"host", ""},
/* 39: */ {"if-match", ""},
/* 40: */ {"if-modified-since", ""},
/* 41: */ {"if-none-match", ""},
/* 42: */ {"if-range", ""},
/* 43: */ {"if-unmodified-since", ""},
/* 44: */ {"last-modified", ""},
/* 45: */ {"link", ""},
/* 46: */ {"location", ""},
/* 47: */ {"max-forwards", ""},
/* 48: */ {"proxy-authenticate", ""},
/* 49: */ {"proxy-authorization", ""},
/* 50: */ {"range", ""},
/* 51: */ {"referer", ""},
/* 52: */ {"refresh", ""},
/* 53: */ {"retry-after", ""},
/* 54: */ {"server", ""},
/* 55: */ {"set-cookie", ""},
/* 56: */ {"strict-transport-security", ""},
/* 57: */ {"transfer-encoding", ""},
/* 58: */ {"user-agent", ""},
/* 59: */ {"vary", ""},
/* 60: */ {"via", ""},
/* 61: */ {"www-authenticate", ""},
};
void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl, grpc_mdctx *mdctx) {

@ -58,16 +58,16 @@ void grpc_chttp2_hpack_write_varint_tail(gpr_uint32 tail_value,
: grpc_chttp2_hpack_varint_length( \
(n)-GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits)))
#define GRPC_CHTTP2_WRITE_VARINT(n, prefix_bits, prefix_or, target, length) \
do { \
gpr_uint8* tgt = target; \
if ((length) == 1) { \
(tgt)[0] = (prefix_or) | (n); \
} else { \
(tgt)[0] = (prefix_or) | GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits); \
grpc_chttp2_hpack_write_varint_tail( \
(n)-GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits), (tgt) + 1, (length)-1); \
} \
#define GRPC_CHTTP2_WRITE_VARINT(n, prefix_bits, prefix_or, target, length) \
do { \
gpr_uint8* tgt = target; \
if ((length) == 1) { \
(tgt)[0] = (prefix_or) | (n); \
} else { \
(tgt)[0] = (prefix_or) | GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits); \
grpc_chttp2_hpack_write_varint_tail( \
(n)-GRPC_CHTTP2_MAX_IN_PREFIX(prefix_bits), (tgt)+1, (length)-1); \
} \
} while (0)
#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_VARINT_H__ */

@ -525,7 +525,7 @@ static int init_stream(grpc_transport *gt, grpc_stream *gs,
lock(t);
s->id = 0;
} else {
s->id = (gpr_uint32)(gpr_uintptr)server_data;
s->id = (gpr_uint32)(gpr_uintptr) server_data;
t->incoming_stream = s;
grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
}
@ -1238,7 +1238,7 @@ static int init_header_frame_parser(transport *t, int is_continuation) {
t->incoming_stream = NULL;
/* if stream is accepted, we set incoming_stream in init_stream */
t->cb->accept_stream(t->cb_user_data, &t->base,
(void *)(gpr_uintptr)t->incoming_stream_id);
(void *)(gpr_uintptr) t->incoming_stream_id);
s = t->incoming_stream;
if (!s) {
gpr_log(GPR_ERROR, "stream not accepted");
@ -1503,8 +1503,9 @@ static int process_read(transport *t, gpr_slice slice) {
"Connect string mismatch: expected '%c' (%d) got '%c' (%d) "
"at byte %d",
CLIENT_CONNECT_STRING[t->deframe_state],
(int)(gpr_uint8)CLIENT_CONNECT_STRING[t->deframe_state], *cur,
(int)*cur, t->deframe_state);
(int)(gpr_uint8) CLIENT_CONNECT_STRING[t->deframe_state],
*cur, (int)*cur, t->deframe_state);
drop_connection(t);
return 0;
}
++cur;
@ -1737,9 +1738,9 @@ static void add_to_pollset(grpc_transport *gt, grpc_pollset *pollset) {
*/
static const grpc_transport_vtable vtable = {
sizeof(stream), init_stream, send_batch, set_allow_window_updates,
add_to_pollset, destroy_stream, abort_stream, goaway, close_transport,
send_ping, destroy_transport};
sizeof(stream), init_stream, send_batch, set_allow_window_updates,
add_to_pollset, destroy_stream, abort_stream, goaway,
close_transport, send_ping, destroy_transport};
void grpc_create_chttp2_transport(grpc_transport_setup_callback setup,
void *arg,

@ -154,7 +154,7 @@ grpc_mdctx *grpc_mdctx_create_with_seed(gpr_uint32 seed) {
return ctx;
}
grpc_mdctx *grpc_mdctx_create() {
grpc_mdctx *grpc_mdctx_create(void) {
/* This seed is used to prevent remote connections from controlling hash table
* collisions. It needs to be somewhat unpredictable to a remote connection.
*/

@ -82,7 +82,7 @@ struct grpc_mdelem {
};
/* Create/orphan a metadata context */
grpc_mdctx *grpc_mdctx_create();
grpc_mdctx *grpc_mdctx_create(void);
grpc_mdctx *grpc_mdctx_create_with_seed(gpr_uint32 seed);
void grpc_mdctx_orphan(grpc_mdctx *mdctx);

@ -37,6 +37,7 @@
#include <string.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include "src/core/tsi/transport_security.h"
/* --- Constants. ---*/
@ -52,9 +53,9 @@
the data encoded in little endian on 4 bytes. */
typedef struct {
unsigned char* data;
uint32_t size;
uint32_t allocated_size;
uint32_t offset;
size_t size;
size_t allocated_size;
size_t offset;
int needs_draining;
} tsi_fake_frame;
@ -80,7 +81,7 @@ typedef struct {
tsi_frame_protector base;
tsi_fake_frame protect_frame;
tsi_fake_frame unprotect_frame;
uint32_t max_frame_size;
size_t max_frame_size;
} tsi_fake_frame_protector;
/* --- Utils. ---*/
@ -110,16 +111,16 @@ static tsi_result tsi_fake_handshake_message_from_string(
return TSI_DATA_CORRUPTED;
}
static uint32_t load32_little_endian(const unsigned char* buf) {
return ((uint32_t)(buf[0]) | (uint32_t)(buf[1] << 8) |
(uint32_t)(buf[2] << 16) | (uint32_t)(buf[3] << 24));
static gpr_uint32 load32_little_endian(const unsigned char* buf) {
return ((gpr_uint32)(buf[0]) | (gpr_uint32)(buf[1] << 8) |
(gpr_uint32)(buf[2] << 16) | (gpr_uint32)(buf[3] << 24));
}
static void store32_little_endian(uint32_t value, unsigned char* buf) {
static void store32_little_endian(gpr_uint32 value, unsigned char* buf) {
buf[3] = (unsigned char)(value >> 24) & 0xFF;
buf[2] = (unsigned char)(value >> 16) & 0xFF;
buf[1] = (unsigned char)(value >> 8) & 0xFF;
buf[0] = (unsigned char)(value)&0xFF;
buf[0] = (unsigned char)(value) & 0xFF;
}
static void tsi_fake_frame_reset(tsi_fake_frame* frame, int needs_draining) {
@ -149,10 +150,10 @@ static int tsi_fake_frame_ensure_size(tsi_fake_frame* frame) {
/* This method should not be called if frame->needs_framing is not 0. */
static tsi_result fill_frame_from_bytes(const unsigned char* incoming_bytes,
uint32_t* incoming_bytes_size,
size_t* incoming_bytes_size,
tsi_fake_frame* frame) {
uint32_t available_size = *incoming_bytes_size;
uint32_t to_read_size = 0;
size_t available_size = *incoming_bytes_size;
size_t to_read_size = 0;
const unsigned char* bytes_cursor = incoming_bytes;
if (frame->needs_draining) return TSI_INTERNAL_ERROR;
@ -197,9 +198,9 @@ static tsi_result fill_frame_from_bytes(const unsigned char* incoming_bytes,
/* This method should not be called if frame->needs_framing is 0. */
static tsi_result drain_frame_to_bytes(unsigned char* outgoing_bytes,
uint32_t* outgoing_bytes_size,
size_t* outgoing_bytes_size,
tsi_fake_frame* frame) {
uint32_t to_write_size = frame->size - frame->offset;
size_t to_write_size = frame->size - frame->offset;
if (!frame->needs_draining) return TSI_INTERNAL_ERROR;
if (*outgoing_bytes_size < to_write_size) {
memcpy(outgoing_bytes, frame->data + frame->offset, *outgoing_bytes_size);
@ -212,7 +213,7 @@ static tsi_result drain_frame_to_bytes(unsigned char* outgoing_bytes,
return TSI_OK;
}
static tsi_result bytes_to_frame(unsigned char* bytes, uint32_t bytes_size,
static tsi_result bytes_to_frame(unsigned char* bytes, size_t bytes_size,
tsi_fake_frame* frame) {
frame->offset = 0;
frame->size = bytes_size + TSI_FAKE_FRAME_HEADER_SIZE;
@ -229,17 +230,18 @@ static void tsi_fake_frame_destruct(tsi_fake_frame* frame) {
/* --- tsi_frame_protector methods implementation. ---*/
static tsi_result fake_protector_protect(
tsi_frame_protector* self, const unsigned char* unprotected_bytes,
uint32_t* unprotected_bytes_size, unsigned char* protected_output_frames,
uint32_t* protected_output_frames_size) {
static tsi_result fake_protector_protect(tsi_frame_protector* self,
const unsigned char* unprotected_bytes,
size_t* unprotected_bytes_size,
unsigned char* protected_output_frames,
size_t* protected_output_frames_size) {
tsi_result result = TSI_OK;
tsi_fake_frame_protector* impl = (tsi_fake_frame_protector*)self;
unsigned char frame_header[TSI_FAKE_FRAME_HEADER_SIZE];
tsi_fake_frame* frame = &impl->protect_frame;
uint32_t saved_output_size = *protected_output_frames_size;
uint32_t drained_size = 0;
uint32_t* num_bytes_written = protected_output_frames_size;
size_t saved_output_size = *protected_output_frames_size;
size_t drained_size = 0;
size_t* num_bytes_written = protected_output_frames_size;
*num_bytes_written = 0;
/* Try to drain first. */
@ -262,7 +264,7 @@ static tsi_result fake_protector_protect(
if (frame->needs_draining) return TSI_INTERNAL_ERROR;
if (frame->size == 0) {
/* New frame, create a header. */
uint32_t written_in_frame_size = 0;
size_t written_in_frame_size = 0;
store32_little_endian(impl->max_frame_size, frame_header);
written_in_frame_size = TSI_FAKE_FRAME_HEADER_SIZE;
result = fill_frame_from_bytes(frame_header, &written_in_frame_size, frame);
@ -291,7 +293,7 @@ static tsi_result fake_protector_protect(
static tsi_result fake_protector_protect_flush(
tsi_frame_protector* self, unsigned char* protected_output_frames,
uint32_t* protected_output_frames_size, uint32_t* still_pending_size) {
size_t* protected_output_frames_size, size_t* still_pending_size) {
tsi_result result = TSI_OK;
tsi_fake_frame_protector* impl = (tsi_fake_frame_protector*)self;
tsi_fake_frame* frame = &impl->protect_frame;
@ -311,14 +313,14 @@ static tsi_result fake_protector_protect_flush(
static tsi_result fake_protector_unprotect(
tsi_frame_protector* self, const unsigned char* protected_frames_bytes,
uint32_t* protected_frames_bytes_size, unsigned char* unprotected_bytes,
uint32_t* unprotected_bytes_size) {
size_t* protected_frames_bytes_size, unsigned char* unprotected_bytes,
size_t* unprotected_bytes_size) {
tsi_result result = TSI_OK;
tsi_fake_frame_protector* impl = (tsi_fake_frame_protector*)self;
tsi_fake_frame* frame = &impl->unprotect_frame;
uint32_t saved_output_size = *unprotected_bytes_size;
uint32_t drained_size = 0;
uint32_t* num_bytes_written = unprotected_bytes_size;
size_t saved_output_size = *unprotected_bytes_size;
size_t drained_size = 0;
size_t* num_bytes_written = unprotected_bytes_size;
*num_bytes_written = 0;
/* Try to drain first. */
@ -373,7 +375,7 @@ static const tsi_frame_protector_vtable frame_protector_vtable = {
/* --- tsi_handshaker methods implementation. ---*/
static tsi_result fake_handshaker_get_bytes_to_send_to_peer(
tsi_handshaker* self, unsigned char* bytes, uint32_t* bytes_size) {
tsi_handshaker* self, unsigned char* bytes, size_t* bytes_size) {
tsi_fake_handshaker* impl = (tsi_fake_handshaker*)self;
tsi_result result = TSI_OK;
if (impl->needs_incoming_message || impl->result == TSI_OK) {
@ -408,7 +410,7 @@ static tsi_result fake_handshaker_get_bytes_to_send_to_peer(
}
static tsi_result fake_handshaker_process_bytes_from_peer(
tsi_handshaker* self, const unsigned char* bytes, uint32_t* bytes_size) {
tsi_handshaker* self, const unsigned char* bytes, size_t* bytes_size) {
tsi_result result = TSI_OK;
tsi_fake_handshaker* impl = (tsi_fake_handshaker*)self;
int expected_msg = impl->next_message_to_send - 1;
@ -463,7 +465,7 @@ static tsi_result fake_handshaker_extract_peer(tsi_handshaker* self,
}
static tsi_result fake_handshaker_create_frame_protector(
tsi_handshaker* self, uint32_t* max_protected_frame_size,
tsi_handshaker* self, size_t* max_protected_frame_size,
tsi_frame_protector** protector) {
*protector = tsi_create_fake_protector(max_protected_frame_size);
if (*protector == NULL) return TSI_OUT_OF_RESOURCES;
@ -479,8 +481,10 @@ static void fake_handshaker_destroy(tsi_handshaker* self) {
static const tsi_handshaker_vtable handshaker_vtable = {
fake_handshaker_get_bytes_to_send_to_peer,
fake_handshaker_process_bytes_from_peer, fake_handshaker_get_result,
fake_handshaker_extract_peer, fake_handshaker_create_frame_protector,
fake_handshaker_process_bytes_from_peer,
fake_handshaker_get_result,
fake_handshaker_extract_peer,
fake_handshaker_create_frame_protector,
fake_handshaker_destroy,
};
@ -500,7 +504,7 @@ tsi_handshaker* tsi_create_fake_handshaker(int is_client) {
}
tsi_frame_protector* tsi_create_fake_protector(
uint32_t* max_protected_frame_size) {
size_t* max_protected_frame_size) {
tsi_fake_frame_protector* impl = calloc(1, sizeof(tsi_fake_frame_protector));
if (impl == NULL) return NULL;
impl->max_frame_size = (max_protected_frame_size == NULL)

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

Loading…
Cancel
Save