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

pull/145/head
murgatroid99 10 years ago
commit e1613dcd31
  1. 12
      .clang-format
  2. 14
      .gitignore
  3. 2920
      Makefile
  4. 1026
      build.json
  5. 5
      include/grpc/grpc.h
  6. 58
      src/compiler/cpp_generator.cc
  7. 6
      src/compiler/cpp_generator.h
  8. 16
      src/compiler/cpp_generator_helpers.h
  9. 16
      src/compiler/cpp_plugin.cc
  10. 10
      src/compiler/ruby_generator.cc
  11. 2
      src/compiler/ruby_generator.h
  12. 6
      src/compiler/ruby_generator_helpers-inl.h
  13. 2
      src/compiler/ruby_generator_map-inl.h
  14. 22
      src/compiler/ruby_generator_string-inl.h
  15. 10
      src/compiler/ruby_plugin.cc
  16. 12
      src/core/channel/census_filter.c
  17. 11
      src/core/channel/channel_stack.c
  18. 4
      src/core/channel/child_channel.c
  19. 2
      src/core/channel/child_channel.h
  20. 4
      src/core/channel/client_channel.c
  21. 6
      src/core/channel/connected_channel.c
  22. 4
      src/core/channel/http_client_filter.c
  23. 4
      src/core/channel/http_filter.c
  24. 4
      src/core/channel/http_server_filter.c
  25. 2
      src/core/channel/metadata_buffer.c
  26. 4
      src/core/channel/noop_filter.c
  27. 68
      src/core/iomgr/pollset_kick.h
  28. 161
      src/core/iomgr/pollset_kick_posix.c
  29. 47
      src/core/iomgr/pollset_kick_posix.h
  30. 9
      src/core/iomgr/pollset_multipoller_with_poll_posix.c
  31. 84
      src/core/iomgr/pollset_posix.c
  32. 3
      src/core/iomgr/pollset_posix.h
  33. 5
      src/core/security/auth.c
  34. 8
      src/core/security/security_context.c
  35. 5
      src/core/statistics/census_rpc_stats.c
  36. 3
      src/core/statistics/census_tracing.c
  37. 8
      src/core/support/murmur_hash.c
  38. 4
      src/core/surface/call.c
  39. 2
      src/core/surface/channel.c
  40. 4
      src/core/surface/client.c
  41. 7
      src/core/surface/completion_queue.c
  42. 2
      src/core/surface/completion_queue.h
  43. 3
      src/core/surface/event_string.c
  44. 4
      src/core/surface/lame_client.c
  45. 29
      src/core/surface/server.c
  46. 124
      src/core/transport/chttp2/hpack_table.c
  47. 20
      src/core/transport/chttp2/varint.h
  48. 15
      src/core/transport/chttp2_transport.c
  49. 17
      src/core/tsi/fake_transport_security.c
  50. 23
      src/core/tsi/ssl_transport_security.c
  51. 3
      src/core/tsi/ssl_transport_security.h
  52. 56
      src/cpp/client/channel.cc
  53. 22
      src/cpp/client/channel.h
  54. 18
      src/cpp/client/channel_arguments.cc
  55. 8
      src/cpp/client/client_context.cc
  56. 8
      src/cpp/client/create_channel.cc
  57. 40
      src/cpp/client/credentials.cc
  58. 12
      src/cpp/proto/proto_utils.cc
  59. 6
      src/cpp/proto/proto_utils.h
  60. 4
      src/cpp/server/async_server.cc
  61. 16
      src/cpp/server/async_server_context.cc
  62. 8
      src/cpp/server/completion_queue.cc
  63. 16
      src/cpp/server/server.cc
  64. 12
      src/cpp/server/server_builder.cc
  65. 20
      src/cpp/server/server_credentials.cc
  66. 14
      src/cpp/server/server_rpc_handler.cc
  67. 8
      src/cpp/server/server_rpc_handler.h
  68. 4
      src/cpp/server/thread_pool.cc
  69. 2
      src/cpp/server/thread_pool.h
  70. 34
      src/cpp/stream/stream_context.cc
  71. 50
      src/cpp/stream/stream_context.h
  72. 4
      src/cpp/util/status.cc
  73. 4
      src/cpp/util/time.cc
  74. 4
      src/cpp/util/time.h
  75. 3
      src/php/.gitignore
  76. 16
      src/php/bin/run_tests.sh
  77. 19
      src/php/ext/grpc/call.c
  78. 2
      src/php/ext/grpc/channel.c
  79. 16
      src/php/ext/grpc/completion_queue.c
  80. 17
      src/php/ext/grpc/config.m4
  81. 13
      src/php/ext/grpc/credentials.c
  82. 3
      src/php/ext/grpc/php_grpc.c
  83. 8
      src/php/ext/grpc/server.c
  84. 4
      src/php/ext/grpc/server_credentials.c
  85. 24
      src/php/ext/grpc/timeval.c
  86. 10
      src/ruby/.rubocop.yml
  87. 52
      src/ruby/.rubocop_todo.yml
  88. 32
      src/ruby/Rakefile
  89. 57
      src/ruby/bin/interop/interop_client.rb
  90. 35
      src/ruby/bin/interop/interop_server.rb
  91. 25
      src/ruby/bin/math_client.rb
  92. 44
      src/ruby/bin/math_server.rb
  93. 12
      src/ruby/bin/noproto_client.rb
  94. 16
      src/ruby/bin/noproto_server.rb
  95. 26
      src/ruby/ext/grpc/extconf.rb
  96. 27
      src/ruby/grpc.gemspec
  97. 19
      src/ruby/lib/grpc/beefcake.rb
  98. 7
      src/ruby/lib/grpc/core/event.rb
  99. 18
      src/ruby/lib/grpc/core/time_consts.rb
  100. 9
      src/ruby/lib/grpc/errors.rb
  101. Some files were not shown because too many files have changed in this diff Show More

@ -2,27 +2,22 @@
Language: Cpp Language: Cpp
# BasedOnStyle: Google # BasedOnStyle: Google
AccessModifierOffset: -1 AccessModifierOffset: -1
AlignAfterOpenBracket: true ConstructorInitializerIndentWidth: 4
AlignEscapedNewlinesLeft: true AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignTrailingComments: true AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: true AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true AllowShortLoopsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All AllowShortFunctionsOnASingleLine: All
AlwaysBreakAfterDefinitionReturnType: false
AlwaysBreakTemplateDeclarations: true AlwaysBreakTemplateDeclarations: true
AlwaysBreakBeforeMultilineStrings: true AlwaysBreakBeforeMultilineStrings: true
BreakBeforeBinaryOperators: None BreakBeforeBinaryOperators: false
BreakBeforeTernaryOperators: true BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false BreakConstructorInitializersBeforeComma: false
BinPackParameters: true BinPackParameters: true
BinPackArguments: true
ColumnLimit: 80 ColumnLimit: 80
ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
DerivePointerAlignment: true DerivePointerAlignment: true
ExperimentalAutoDetectBinPacking: false ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: true IndentCaseLabels: true
@ -31,7 +26,6 @@ IndentFunctionDeclarationAfterType: false
MaxEmptyLinesToKeep: 1 MaxEmptyLinesToKeep: 1
KeepEmptyLinesAtTheStartOfBlocks: false KeepEmptyLinesAtTheStartOfBlocks: false
NamespaceIndentation: None NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false ObjCSpaceBeforeProtocolList: false
PenaltyBreakBeforeFirstCallParameter: 1 PenaltyBreakBeforeFirstCallParameter: 1
@ -49,11 +43,9 @@ TabWidth: 8
UseTab: Never UseTab: Never
BreakBeforeBraces: Attach BreakBeforeBraces: Attach
SpacesInParentheses: false SpacesInParentheses: false
SpacesInSquareBrackets: false
SpacesInAngles: false SpacesInAngles: false
SpaceInEmptyParentheses: false SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false SpacesInCStyleCastParentheses: false
SpaceAfterCStyleCast: false
SpacesInContainerLiterals: true SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4 ContinuationIndentWidth: 4

14
.gitignore vendored

@ -1,11 +1,19 @@
# C/C++ build outputs
bins bins
coverage
deps
*.gcno
gens gens
libs libs
objs objs
# gcov coverage data
coverage
*.gcno
# profiler output
*.prof
# python compiled objects
*.pyc *.pyc
# cache for run_tests.py # cache for run_tests.py
.run_tests_cache .run_tests_cache

2920
Makefile

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -194,6 +194,7 @@ typedef enum grpc_completion_type {
GRPC_FINISHED, /* An RPC has finished. The event contains status. GRPC_FINISHED, /* An RPC has finished. The event contains status.
On the server this will be OK or Cancelled. */ On the server this will be OK or Cancelled. */
GRPC_SERVER_RPC_NEW, /* A new RPC has arrived at the server */ 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 GRPC_COMPLETION_DO_NOT_USE /* must be last, forces users to include
a default: case */ a default: case */
} grpc_completion_type; } grpc_completion_type;
@ -439,6 +440,10 @@ void grpc_server_start(grpc_server *server);
Existing calls will be allowed to complete. */ Existing calls will be allowed to complete. */
void grpc_server_shutdown(grpc_server *server); 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. /* Destroy a server.
Forcefully cancels all existing calls. */ Forcefully cancels all existing calls. */
void grpc_server_destroy(grpc_server *server); void grpc_server_destroy(grpc_server *server);

@ -45,23 +45,23 @@
namespace grpc_cpp_generator { namespace grpc_cpp_generator {
namespace { namespace {
bool NoStreaming(const google::protobuf::MethodDescriptor* method) { bool NoStreaming(const google::protobuf::MethodDescriptor *method) {
return !method->client_streaming() && !method->server_streaming(); 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(); 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(); 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(); 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 i = 0; i < file->service_count(); i++) {
for (int j = 0; j < file->service(i)->method_count(); j++) { for (int j = 0; j < file->service(i)->method_count(); j++) {
if (ClientOnlyStreaming(file->service(i)->method(j))) { if (ClientOnlyStreaming(file->service(i)->method(j))) {
@ -72,7 +72,7 @@ bool HasClientOnlyStreaming(const google::protobuf::FileDescriptor* file) {
return false; 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 i = 0; i < file->service_count(); i++) {
for (int j = 0; j < file->service(i)->method_count(); j++) { for (int j = 0; j < file->service(i)->method_count(); j++) {
if (ServerOnlyStreaming(file->service(i)->method(j))) { if (ServerOnlyStreaming(file->service(i)->method(j))) {
@ -83,7 +83,7 @@ bool HasServerOnlyStreaming(const google::protobuf::FileDescriptor* file) {
return false; 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 i = 0; i < file->service_count(); i++) {
for (int j = 0; j < file->service(i)->method_count(); j++) { for (int j = 0; j < file->service(i)->method_count(); j++) {
if (BidiStreaming(file->service(i)->method(j))) { if (BidiStreaming(file->service(i)->method(j))) {
@ -95,7 +95,7 @@ bool HasBidiStreaming(const google::protobuf::FileDescriptor* file) {
} }
} // namespace } // namespace
std::string GetHeaderIncludes(const google::protobuf::FileDescriptor* file) { std::string GetHeaderIncludes(const google::protobuf::FileDescriptor *file) {
std::string temp = std::string temp =
"#include \"grpc++/impl/internal_stub.h\"\n" "#include \"grpc++/impl/internal_stub.h\"\n"
"#include \"grpc++/status.h\"\n" "#include \"grpc++/status.h\"\n"
@ -131,9 +131,9 @@ std::string GetSourceIncludes() {
"#include \"grpc++/stream.h\"\n"; "#include \"grpc++/stream.h\"\n";
} }
void PrintHeaderClientMethod(google::protobuf::io::Printer* printer, void PrintHeaderClientMethod(google::protobuf::io::Printer *printer,
const google::protobuf::MethodDescriptor* method, const google::protobuf::MethodDescriptor *method,
std::map<std::string, std::string>* vars) { std::map<std::string, std::string> *vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = (*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true); grpc_cpp_generator::ClassName(method->input_type(), true);
@ -160,9 +160,9 @@ void PrintHeaderClientMethod(google::protobuf::io::Printer* printer,
} }
} }
void PrintHeaderServerMethod(google::protobuf::io::Printer* printer, void PrintHeaderServerMethod(google::protobuf::io::Printer *printer,
const google::protobuf::MethodDescriptor* method, const google::protobuf::MethodDescriptor *method,
std::map<std::string, std::string>* vars) { std::map<std::string, std::string> *vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = (*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true); grpc_cpp_generator::ClassName(method->input_type(), true);
@ -194,9 +194,9 @@ void PrintHeaderServerMethod(google::protobuf::io::Printer* printer,
} }
} }
void PrintHeaderService(google::protobuf::io::Printer* printer, void PrintHeaderService(google::protobuf::io::Printer *printer,
const google::protobuf::ServiceDescriptor* service, const google::protobuf::ServiceDescriptor *service,
std::map<std::string, std::string>* vars) { std::map<std::string, std::string> *vars) {
(*vars)["Service"] = service->name(); (*vars)["Service"] = service->name();
printer->Print(*vars, printer->Print(*vars,
@ -241,7 +241,7 @@ void PrintHeaderService(google::protobuf::io::Printer* printer,
printer->Print("};\n"); printer->Print("};\n");
} }
std::string GetHeaderServices(const google::protobuf::FileDescriptor* file) { std::string GetHeaderServices(const google::protobuf::FileDescriptor *file) {
std::string output; std::string output;
google::protobuf::io::StringOutputStream output_stream(&output); google::protobuf::io::StringOutputStream output_stream(&output);
google::protobuf::io::Printer printer(&output_stream, '$'); google::protobuf::io::Printer printer(&output_stream, '$');
@ -254,9 +254,9 @@ std::string GetHeaderServices(const google::protobuf::FileDescriptor* file) {
return output; return output;
} }
void PrintSourceClientMethod(google::protobuf::io::Printer* printer, void PrintSourceClientMethod(google::protobuf::io::Printer *printer,
const google::protobuf::MethodDescriptor* method, const google::protobuf::MethodDescriptor *method,
std::map<std::string, std::string>* vars) { std::map<std::string, std::string> *vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = (*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true); grpc_cpp_generator::ClassName(method->input_type(), true);
@ -312,9 +312,9 @@ void PrintSourceClientMethod(google::protobuf::io::Printer* printer,
} }
} }
void PrintSourceServerMethod(google::protobuf::io::Printer* printer, void PrintSourceServerMethod(google::protobuf::io::Printer *printer,
const google::protobuf::MethodDescriptor* method, const google::protobuf::MethodDescriptor *method,
std::map<std::string, std::string>* vars) { std::map<std::string, std::string> *vars) {
(*vars)["Method"] = method->name(); (*vars)["Method"] = method->name();
(*vars)["Request"] = (*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true); grpc_cpp_generator::ClassName(method->input_type(), true);
@ -362,9 +362,9 @@ void PrintSourceServerMethod(google::protobuf::io::Printer* printer,
} }
} }
void PrintSourceService(google::protobuf::io::Printer* printer, void PrintSourceService(google::protobuf::io::Printer *printer,
const google::protobuf::ServiceDescriptor* service, const google::protobuf::ServiceDescriptor *service,
std::map<std::string, std::string>* vars) { std::map<std::string, std::string> *vars) {
(*vars)["Service"] = service->name(); (*vars)["Service"] = service->name();
printer->Print( printer->Print(
*vars, *vars,
@ -394,7 +394,7 @@ void PrintSourceService(google::protobuf::io::Printer* printer,
"}\n"); "}\n");
printer->Print("service_ = new ::grpc::RpcService();\n"); printer->Print("service_ = new ::grpc::RpcService();\n");
for (int i = 0; i < service->method_count(); ++i) { 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)["Method"] = method->name();
(*vars)["Request"] = (*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true); grpc_cpp_generator::ClassName(method->input_type(), true);
@ -458,7 +458,7 @@ void PrintSourceService(google::protobuf::io::Printer* printer,
printer->Print("}\n\n"); printer->Print("}\n\n");
} }
std::string GetSourceServices(const google::protobuf::FileDescriptor* file) { std::string GetSourceServices(const google::protobuf::FileDescriptor *file) {
std::string output; std::string output;
google::protobuf::io::StringOutputStream output_stream(&output); google::protobuf::io::StringOutputStream output_stream(&output);
google::protobuf::io::Printer printer(&output_stream, '$'); google::protobuf::io::Printer printer(&output_stream, '$');

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

@ -41,7 +41,7 @@
namespace grpc_cpp_generator { namespace grpc_cpp_generator {
inline bool StripSuffix(std::string* filename, const std::string& suffix) { inline bool StripSuffix(std::string *filename, const std::string &suffix) {
if (filename->length() >= suffix.length()) { if (filename->length() >= suffix.length()) {
size_t suffix_pos = filename->length() - suffix.length(); size_t suffix_pos = filename->length() - suffix.length();
if (filename->compare(suffix_pos, std::string::npos, suffix) == 0) { if (filename->compare(suffix_pos, std::string::npos, suffix) == 0) {
@ -60,8 +60,8 @@ inline std::string StripProto(std::string filename) {
return filename; return filename;
} }
inline std::string StringReplace(std::string str, const std::string& from, inline std::string StringReplace(std::string str, const std::string &from,
const std::string& to) { const std::string &to) {
size_t pos = 0; size_t pos = 0;
for (;;) { for (;;) {
@ -76,22 +76,22 @@ inline std::string StringReplace(std::string str, const std::string& from,
return str; return str;
} }
inline std::string DotsToColons(const std::string& name) { inline std::string DotsToColons(const std::string &name) {
return StringReplace(name, ".", "::"); return StringReplace(name, ".", "::");
} }
inline std::string DotsToUnderscores(const std::string& name) { inline std::string DotsToUnderscores(const std::string &name) {
return StringReplace(name, ".", "_"); return StringReplace(name, ".", "_");
} }
inline std::string ClassName(const google::protobuf::Descriptor* descriptor, inline std::string ClassName(const google::protobuf::Descriptor *descriptor,
bool qualified) { bool qualified) {
// Find "outer", the descriptor of the top-level message in which // Find "outer", the descriptor of the top-level message in which
// "descriptor" is embedded. // "descriptor" is embedded.
const google::protobuf::Descriptor* outer = descriptor; const google::protobuf::Descriptor *outer = descriptor;
while (outer->containing_type() != NULL) outer = outer->containing_type(); while (outer->containing_type() != NULL) outer = outer->containing_type();
const std::string& outer_name = outer->full_name(); const std::string &outer_name = outer->full_name();
std::string inner_name = descriptor->full_name().substr(outer_name.size()); std::string inner_name = descriptor->full_name().substr(outer_name.size());
if (qualified) { if (qualified) {

@ -51,10 +51,10 @@ class CppGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
CppGrpcGenerator() {} CppGrpcGenerator() {}
virtual ~CppGrpcGenerator() {} virtual ~CppGrpcGenerator() {}
virtual bool Generate(const google::protobuf::FileDescriptor* file, virtual bool Generate(const google::protobuf::FileDescriptor *file,
const std::string& parameter, const std::string &parameter,
google::protobuf::compiler::GeneratorContext* context, google::protobuf::compiler::GeneratorContext *context,
std::string* error) const { std::string *error) const {
if (file->options().cc_generic_services()) { if (file->options().cc_generic_services()) {
*error = *error =
"cpp grpc proto compiler plugin does not work with generic " "cpp grpc proto compiler plugin does not work with generic "
@ -81,9 +81,9 @@ class CppGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
private: private:
// Insert the given code into the given file at the given insertion point. // Insert the given code into the given file at the given insertion point.
void Insert(google::protobuf::compiler::GeneratorContext* context, void Insert(google::protobuf::compiler::GeneratorContext *context,
const std::string& filename, const std::string& insertion_point, const std::string &filename, const std::string &insertion_point,
const std::string& code) const { const std::string &code) const {
std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output( std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
context->OpenForInsert(filename, insertion_point)); context->OpenForInsert(filename, insertion_point));
google::protobuf::io::CodedOutputStream coded_out(output.get()); google::protobuf::io::CodedOutputStream coded_out(output.get());
@ -91,7 +91,7 @@ class CppGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
} }
}; };
int main(int argc, char* argv[]) { int main(int argc, char *argv[]) {
CppGrpcGenerator generator; CppGrpcGenerator generator;
return google::protobuf::compiler::PluginMain(argc, argv, &generator); return google::protobuf::compiler::PluginMain(argc, argv, &generator);
} }

@ -57,8 +57,8 @@ namespace grpc_ruby_generator {
namespace { namespace {
// Prints out the method using the ruby gRPC DSL. // Prints out the method using the ruby gRPC DSL.
void PrintMethod(const MethodDescriptor* method, const std::string& package, void PrintMethod(const MethodDescriptor *method, const std::string &package,
Printer* out) { Printer *out) {
std::string input_type = RubyTypeOf(method->input_type()->name(), package); std::string input_type = RubyTypeOf(method->input_type()->name(), package);
if (method->client_streaming()) { if (method->client_streaming()) {
input_type = "stream(" + input_type + ")"; input_type = "stream(" + input_type + ")";
@ -75,8 +75,8 @@ void PrintMethod(const MethodDescriptor* method, const std::string& package,
} }
// Prints out the service using the ruby gRPC DSL. // Prints out the service using the ruby gRPC DSL.
void PrintService(const ServiceDescriptor* service, const std::string& package, void PrintService(const ServiceDescriptor *service, const std::string &package,
Printer* out) { Printer *out) {
if (service->method_count() == 0) { if (service->method_count() == 0) {
return; return;
} }
@ -125,7 +125,7 @@ void PrintService(const ServiceDescriptor* service, const std::string& package,
} // namespace } // namespace
std::string GetServices(const FileDescriptor* file) { std::string GetServices(const FileDescriptor *file) {
std::string output; std::string output;
StringOutputStream output_stream(&output); StringOutputStream output_stream(&output);
Printer out(&output_stream, '$'); Printer out(&output_stream, '$');

@ -44,7 +44,7 @@ class FileDescriptor;
namespace grpc_ruby_generator { namespace grpc_ruby_generator {
std::string GetServices(const google::protobuf::FileDescriptor* file); std::string GetServices(const google::protobuf::FileDescriptor *file);
} // namespace grpc_ruby_generator } // namespace grpc_ruby_generator

@ -41,8 +41,8 @@
namespace grpc_ruby_generator { namespace grpc_ruby_generator {
inline bool ServicesFilename(const google::protobuf::FileDescriptor* file, inline bool ServicesFilename(const google::protobuf::FileDescriptor *file,
std::string* file_name_or_error) { std::string *file_name_or_error) {
// Get output file name. // Get output file name.
static const unsigned proto_suffix_length = 6; // length of ".proto" static const unsigned proto_suffix_length = 6; // length of ".proto"
if (file->name().size() > proto_suffix_length && if (file->name().size() > proto_suffix_length &&
@ -58,7 +58,7 @@ inline bool ServicesFilename(const google::protobuf::FileDescriptor* file,
} }
inline std::string MessagesRequireName( inline std::string MessagesRequireName(
const google::protobuf::FileDescriptor* file) { const google::protobuf::FileDescriptor *file) {
return Replace(file->name(), ".proto", ""); return Replace(file->name(), ".proto", "");
} }

@ -49,7 +49,7 @@ namespace grpc_ruby_generator {
// Converts an initializer list of the form { key0, value0, key1, value1, ... } // 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. // into a map of key* to value*. Is merely a readability helper for later code.
inline std::map<std::string, std::string> ListToDict( inline std::map<std::string, std::string> ListToDict(
const initializer_list<std::string>& values) { const initializer_list<std::string> &values) {
if (values.size() % 2 != 0) { if (values.size() % 2 != 0) {
// MOE: insert std::cerr << "Not every 'key' has a value in `values`." // MOE: insert std::cerr << "Not every 'key' has a value in `values`."
// << std::endl; // << std::endl;

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

@ -52,10 +52,10 @@ class RubyGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
RubyGrpcGenerator() {} RubyGrpcGenerator() {}
~RubyGrpcGenerator() override {} ~RubyGrpcGenerator() override {}
bool Generate(const google::protobuf::FileDescriptor* file, bool Generate(const google::protobuf::FileDescriptor *file,
const std::string& parameter, const std::string &parameter,
google::protobuf::compiler::GeneratorContext* context, google::protobuf::compiler::GeneratorContext *context,
std::string* error) const override { std::string *error) const override {
std::string code = grpc_ruby_generator::GetServices(file); std::string code = grpc_ruby_generator::GetServices(file);
if (code.size() == 0) { if (code.size() == 0) {
return true; // don't generate a file if there are no services return true; // don't generate a file if there are no services
@ -74,7 +74,7 @@ class RubyGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
} }
}; };
int main(int argc, char* argv[]) { int main(int argc, char *argv[]) {
RubyGrpcGenerator generator; RubyGrpcGenerator generator;
return google::protobuf::compiler::PluginMain(argc, argv, &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 = { 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"}; "census-client"};
const grpc_channel_filter grpc_server_census_filter = { 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"}; "census-server"};

@ -54,7 +54,7 @@
/* Given a size, round up to the next multiple of sizeof(void*) */ /* Given a size, round up to the next multiple of sizeof(void*) */
#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \ #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 grpc_channel_stack_size(const grpc_channel_filter **filters,
size_t filter_count) { 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_stack *grpc_channel_stack_from_top_element(
grpc_channel_element *elem) { grpc_channel_element *elem) {
return (grpc_channel_stack *)((char *)(elem)-ROUND_UP_TO_ALIGNMENT_SIZE( return (grpc_channel_stack *)((char *)(elem) -
sizeof(grpc_channel_stack))); ROUND_UP_TO_ALIGNMENT_SIZE(
sizeof(grpc_channel_stack)));
} }
grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem) { grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem) {
return (grpc_call_stack *)((char *)(elem)-ROUND_UP_TO_ALIGNMENT_SIZE( return (grpc_call_stack *)((char *)(elem) - ROUND_UP_TO_ALIGNMENT_SIZE(
sizeof(grpc_call_stack))); sizeof(grpc_call_stack)));
} }
static void do_nothing(void *user_data, grpc_op_error error) {} 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 = { 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, 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 /* helper for filters that need to host child channel stacks... handles
lifetime and upwards propagation cleanly */ 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_channel_stack grpc_child_channel;
typedef grpc_call_stack grpc_child_call; 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 = { 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, 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 /* 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 channel data in call allocations, to allow everything to be pulled in minimal
cache line requests */ 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) \ #define CALL_DATA_FROM_TRANSPORT_STREAM(transport_stream) \
(((call_data *)(transport_stream)) - 1) (((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 = { 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, 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 = { 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, 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 = { 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, 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 = { 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, sizeof(channel_data), init_channel_elem, destroy_channel_elem,

@ -61,7 +61,7 @@ struct grpc_metadata_buffer_impl {
size_t elem_cap; 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) { void grpc_metadata_buffer_init(grpc_metadata_buffer *buffer) {
/* start buffer as NULL, indicating no elements */ /* 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 = { 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, sizeof(channel_data), init_channel_elem, destroy_channel_elem,

@ -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,161 @@
/*
*
* 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. */
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 gpr_mu pipe_freelist_mu;
static grpc_kick_pipe_info *allocate_pipe() {
grpc_kick_pipe_info *info;
gpr_mu_lock(&pipe_freelist_mu);
if (pipe_freelist != NULL) {
info = pipe_freelist;
pipe_freelist = pipe_freelist->next;
} 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 free_pipe(grpc_kick_pipe_info *pipe_info) {
/* TODO(klempner): Start closing pipes if the free list gets too large */
gpr_mu_lock(&pipe_freelist_mu);
pipe_info->next = pipe_freelist;
pipe_freelist = pipe_info;
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) {
grpc_kick_pipe_info *current = pipe_freelist;
pipe_freelist = pipe_freelist->next;
close(current->pipe_read_fd);
close(current->pipe_write_fd);
gpr_free(current);
}
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; nf = 0;
np = 1; 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].events = POLLIN;
h->pfds[0].revents = POLLOUT; h->pfds[0].revents = POLLOUT;
for (i = 0; i < h->fd_count; i++) { for (i = 0; i < h->fd_count; i++) {
@ -173,7 +177,7 @@ static int multipoll_with_poll_pollset_maybe_work(
/* do nothing */ /* do nothing */
} else { } else {
if (h->pfds[0].revents & POLLIN) { if (h->pfds[0].revents & POLLIN) {
grpc_kick_drain(pollset); grpc_pollset_kick_consume(&pollset->kick_state);
} }
for (i = 1; i < np; i++) { for (i = 1; i < np; i++) {
if (h->pfds[i].revents & POLLIN) { 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); end_polling(pollset);
gpr_mu_lock(&pollset->mu); gpr_mu_lock(&pollset->mu);

@ -48,18 +48,6 @@
#include <grpc/support/thd.h> #include <grpc/support/thd.h>
#include <grpc/support/useful.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 grpc_pollset g_backup_pollset;
static int g_shutdown_backup_poller; static int g_shutdown_backup_poller;
static gpr_event g_backup_poller_done; 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); 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) { void grpc_pollset_kick(grpc_pollset *p) {
if (!p->counter) return; if (!p->counter) return;
grpc_pollset_force_kick(p); grpc_pollset_kick_kick(&p->kick_state);
} }
void grpc_kick_drain(grpc_pollset *p) { void grpc_pollset_force_kick(grpc_pollset *p) { grpc_pollset_kick(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;
}
}
}
/* global state management */ /* global state management */
grpc_pollset *grpc_backup_pollset(void) { return &g_backup_pollset; } grpc_pollset *grpc_backup_pollset(void) { return &g_backup_pollset; }
void grpc_pollset_global_init(void) { void grpc_pollset_global_init(void) {
int i;
gpr_thd_id id; gpr_thd_id id;
/* initialize the kick shards */ /* Initialize kick fd state */
for (i = 0; i < KICK_SHARDS; i++) { grpc_pollset_kick_global_init();
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 the backup pollset */ /* initialize the backup pollset */
grpc_pollset_init(&g_backup_pollset); grpc_pollset_init(&g_backup_pollset);
@ -152,8 +97,6 @@ void grpc_pollset_global_init(void) {
} }
void grpc_pollset_global_shutdown(void) { void grpc_pollset_global_shutdown(void) {
int i;
/* terminate the backup poller thread */ /* terminate the backup poller thread */
gpr_mu_lock(&g_backup_pollset.mu); gpr_mu_lock(&g_backup_pollset.mu);
g_shutdown_backup_poller = 1; g_shutdown_backup_poller = 1;
@ -163,11 +106,8 @@ void grpc_pollset_global_shutdown(void) {
/* destroy the backup pollset */ /* destroy the backup pollset */
grpc_pollset_destroy(&g_backup_pollset); grpc_pollset_destroy(&g_backup_pollset);
/* destroy the kick shards */ /* destroy the kick pipes */
for (i = 0; i < KICK_SHARDS; i++) { grpc_pollset_kick_global_destroy();
close(g_kick_pipes[i][0]);
close(g_kick_pipes[i][1]);
}
} }
/* main interface */ /* main interface */
@ -178,6 +118,7 @@ static void become_unary_pollset(grpc_pollset *pollset, grpc_fd *fd);
void grpc_pollset_init(grpc_pollset *pollset) { void grpc_pollset_init(grpc_pollset *pollset) {
gpr_mu_init(&pollset->mu); gpr_mu_init(&pollset->mu);
gpr_cv_init(&pollset->cv); gpr_cv_init(&pollset->cv);
grpc_pollset_kick_init(&pollset->kick_state);
become_empty_pollset(pollset); 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) { void grpc_pollset_destroy(grpc_pollset *pollset) {
pollset->vtable->destroy(pollset); pollset->vtable->destroy(pollset);
grpc_pollset_kick_destroy(&pollset->kick_state);
gpr_mu_destroy(&pollset->mu); gpr_mu_destroy(&pollset->mu);
gpr_cv_destroy(&pollset->cv); gpr_cv_destroy(&pollset->cv);
} }
@ -290,7 +232,11 @@ static int unary_poll_pollset_maybe_work(grpc_pollset *pollset,
return 1; 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].events = POLLIN;
pfd[0].revents = 0; pfd[0].revents = 0;
pfd[1].fd = fd->fd; pfd[1].fd = fd->fd;
@ -308,7 +254,7 @@ static int unary_poll_pollset_maybe_work(grpc_pollset *pollset,
/* do nothing */ /* do nothing */
} else { } else {
if (pfd[0].revents & POLLIN) { if (pfd[0].revents & POLLIN) {
grpc_kick_drain(pollset); grpc_pollset_kick_consume(&pollset->kick_state);
} }
if (pfd[1].revents & POLLIN) { if (pfd[1].revents & POLLIN) {
grpc_fd_become_readable(fd, allow_synchronous_callback); 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); gpr_mu_lock(&pollset->mu);
grpc_fd_end_poll(fd, pollset); grpc_fd_end_poll(fd, pollset);
pollset->counter = 0; pollset->counter = 0;

@ -36,6 +36,8 @@
#include <grpc/support/sync.h> #include <grpc/support/sync.h>
#include "src/core/iomgr/pollset_kick.h"
typedef struct grpc_pollset_vtable grpc_pollset_vtable; typedef struct grpc_pollset_vtable grpc_pollset_vtable;
/* forward declare only in this file to avoid leaking impl details via /* 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; const grpc_pollset_vtable *vtable;
gpr_mu mu; gpr_mu mu;
gpr_cv cv; gpr_cv cv;
grpc_pollset_kick_state kick_state;
int counter; int counter;
union { union {
int fd; int fd;

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

@ -413,10 +413,10 @@ grpc_security_status grpc_ssl_server_security_context_create(
(const unsigned char **)&config->pem_private_key, (const unsigned char **)&config->pem_private_key,
&config->pem_private_key_size, &config->pem_private_key_size,
(const unsigned char **)&config->pem_cert_chain, (const unsigned char **)&config->pem_cert_chain,
&config->pem_cert_chain_size, 1, &config->pem_cert_chain_size, 1, config->pem_root_certs,
config->pem_root_certs, config->pem_root_certs_size, config->pem_root_certs_size, GRPC_SSL_CIPHER_SUITES,
GRPC_SSL_CIPHER_SUITES, alpn_protocol_strings, alpn_protocol_strings, alpn_protocol_string_lengths, num_alpn_protocols,
alpn_protocol_string_lengths, num_alpn_protocols, &c->handshaker_factory); &c->handshaker_factory);
if (result != TSI_OK) { if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result)); tsi_result_to_string(result));

@ -85,8 +85,9 @@ static void delete_key(void* key) { gpr_free(key); }
static const census_ht_option ht_opt = { static const census_ht_option ht_opt = {
CENSUS_HT_POINTER /* key type */, 1999 /* n_of_buckets */, CENSUS_HT_POINTER /* key type */, 1999 /* n_of_buckets */,
simple_hash /* hash function */, cmp_str_keys /* key comparator */, simple_hash /* hash function */, cmp_str_keys /* key comparator */,
delete_stats /* data deleter */, delete_key /* key deleter */}; delete_stats /* data deleter */, delete_key /* key deleter */
};
static void init_rpc_stats(void* stats) { static void init_rpc_stats(void* stats) {
memset(stats, 0, sizeof(census_rpc_stats)); memset(stats, 0, sizeof(census_rpc_stats));

@ -76,7 +76,8 @@ static void delete_trace_obj(void* obj) { trace_obj_destroy((trace_obj*)obj); }
static const census_ht_option ht_opt = { static const census_ht_option ht_opt = {
CENSUS_HT_UINT64 /* key type*/, 571 /* n_of_buckets */, NULL /* hash */, CENSUS_HT_UINT64 /* key type*/, 571 /* n_of_buckets */, NULL /* hash */,
NULL /* compare_keys */, delete_trace_obj /* delete data */, 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_once g_init_mutex_once = GPR_ONCE_INIT;
static gpr_mu g_mu; /* Guards following two static variables. */ static gpr_mu g_mu; /* Guards following two static variables. */

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

@ -198,7 +198,7 @@ struct grpc_call {
gpr_refcount internal_refcount; 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_FROM_CALL_STACK(call_stack) (((grpc_call *)(call_stack)) - 1)
#define CALL_ELEM_FROM_CALL(call, idx) \ #define CALL_ELEM_FROM_CALL(call, idx) \
grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx) grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx)
@ -801,7 +801,7 @@ static gpr_uint32 decode_status(grpc_mdelem *md) {
gpr_uint32 status; gpr_uint32 status;
void *user_data = grpc_mdelem_get_user_data(md, destroy_status); void *user_data = grpc_mdelem_get_user_data(md, destroy_status);
if (user_data) { if (user_data) {
status = ((gpr_uint32)(gpr_intptr)user_data) - STATUS_OFFSET; status = ((gpr_uint32)(gpr_intptr) user_data) - STATUS_OFFSET;
} else { } else {
if (!gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value), if (!gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value),
GPR_SLICE_LENGTH(md->value->slice), GPR_SLICE_LENGTH(md->value->slice),

@ -51,7 +51,7 @@ struct grpc_channel {
grpc_mdstr *authority_string; 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( grpc_channel *grpc_channel_create_from_filters(
const grpc_channel_filter **filters, size_t num_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) {} static void destroy_channel_elem(grpc_channel_element *elem) {}
const grpc_channel_filter grpc_client_surface_filter = { 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, sizeof(channel_data), init_channel_elem, destroy_channel_elem,

@ -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, void grpc_cq_end_read(grpc_completion_queue *cc, void *tag, grpc_call *call,
grpc_event_finish_func on_finish, void *user_data, grpc_event_finish_func on_finish, void *user_data,
grpc_byte_buffer *read) { grpc_byte_buffer *read) {

@ -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, gpr_timespec deadline, size_t metadata_count,
grpc_metadata *metadata_elements); grpc_metadata *metadata_elements);
void grpc_cq_end_server_shutdown(grpc_completion_queue *cc, void *tag);
/* disable polling for some tests */ /* disable polling for some tests */
void grpc_completion_queue_dont_poll_test_only(grpc_completion_queue *cc); 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"); if (ev == NULL) return gpr_strdup("null");
switch (ev->type) { switch (ev->type) {
case GRPC_SERVER_SHUTDOWN:
p += sprintf(p, "SERVER_SHUTDOWN");
break;
case GRPC_QUEUE_SHUTDOWN: case GRPC_QUEUE_SHUTDOWN:
p += sprintf(p, "QUEUE_SHUTDOWN"); p += sprintf(p, "QUEUE_SHUTDOWN");
break; break;

@ -111,9 +111,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
} }
static const grpc_channel_filter lame_filter = { 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, sizeof(channel_data), init_channel_elem, destroy_channel_elem,

@ -81,6 +81,8 @@ struct grpc_server {
size_t tag_cap; size_t tag_cap;
gpr_uint8 shutdown; gpr_uint8 shutdown;
gpr_uint8 have_shutdown_tag;
void *shutdown_tag;
call_data *lists[CALL_LIST_COUNT]; call_data *lists[CALL_LIST_COUNT];
channel_data root_channel_data; 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++) { for (i = 0; i < CALL_LIST_COUNT; i++) {
call_list_remove(chand->server, elem->call_data, 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); gpr_mu_unlock(&chand->server->mu);
server_unref(chand->server); 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 = { 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, 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); 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; listener *l;
void **tags; void **tags;
size_t ntags; size_t ntags;
@ -551,6 +558,14 @@ void grpc_server_shutdown(grpc_server *server) {
server->ntags = 0; server->ntags = 0;
server->shutdown = 1; 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); gpr_mu_unlock(&server->mu);
for (i = 0; i < nchannels; i++) { 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) { void grpc_server_destroy(grpc_server *server) {
channel_data *c; channel_data *c;
gpr_mu_lock(&server->mu); gpr_mu_lock(&server->mu);

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

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

@ -120,7 +120,7 @@ static void store32_little_endian(gpr_uint32 value, unsigned char* buf) {
buf[3] = (unsigned char)(value >> 24) & 0xFF; buf[3] = (unsigned char)(value >> 24) & 0xFF;
buf[2] = (unsigned char)(value >> 16) & 0xFF; buf[2] = (unsigned char)(value >> 16) & 0xFF;
buf[1] = (unsigned char)(value >> 8) & 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) { static void tsi_fake_frame_reset(tsi_fake_frame* frame, int needs_draining) {
@ -230,10 +230,11 @@ static void tsi_fake_frame_destruct(tsi_fake_frame* frame) {
/* --- tsi_frame_protector methods implementation. ---*/ /* --- tsi_frame_protector methods implementation. ---*/
static tsi_result fake_protector_protect( static tsi_result fake_protector_protect(tsi_frame_protector* self,
tsi_frame_protector* self, const unsigned char* unprotected_bytes, const unsigned char* unprotected_bytes,
size_t* unprotected_bytes_size, unsigned char* protected_output_frames, size_t* unprotected_bytes_size,
size_t* protected_output_frames_size) { unsigned char* protected_output_frames,
size_t* protected_output_frames_size) {
tsi_result result = TSI_OK; tsi_result result = TSI_OK;
tsi_fake_frame_protector* impl = (tsi_fake_frame_protector*)self; tsi_fake_frame_protector* impl = (tsi_fake_frame_protector*)self;
unsigned char frame_header[TSI_FAKE_FRAME_HEADER_SIZE]; unsigned char frame_header[TSI_FAKE_FRAME_HEADER_SIZE];
@ -480,8 +481,10 @@ static void fake_handshaker_destroy(tsi_handshaker* self) {
static const tsi_handshaker_vtable handshaker_vtable = { static const tsi_handshaker_vtable handshaker_vtable = {
fake_handshaker_get_bytes_to_send_to_peer, fake_handshaker_get_bytes_to_send_to_peer,
fake_handshaker_process_bytes_from_peer, fake_handshaker_get_result, fake_handshaker_process_bytes_from_peer,
fake_handshaker_extract_peer, fake_handshaker_create_frame_protector, fake_handshaker_get_result,
fake_handshaker_extract_peer,
fake_handshaker_create_frame_protector,
fake_handshaker_destroy, fake_handshaker_destroy,
}; };

@ -573,10 +573,11 @@ static tsi_result build_alpn_protocol_name_list(
/* --- tsi_frame_protector methods implementation. ---*/ /* --- tsi_frame_protector methods implementation. ---*/
static tsi_result ssl_protector_protect( static tsi_result ssl_protector_protect(tsi_frame_protector* self,
tsi_frame_protector* self, const unsigned char* unprotected_bytes, const unsigned char* unprotected_bytes,
size_t* unprotected_bytes_size, unsigned char* protected_output_frames, size_t* unprotected_bytes_size,
size_t* protected_output_frames_size) { unsigned char* protected_output_frames,
size_t* protected_output_frames_size) {
tsi_ssl_frame_protector* impl = (tsi_ssl_frame_protector*)self; tsi_ssl_frame_protector* impl = (tsi_ssl_frame_protector*)self;
int read_from_ssl; int read_from_ssl;
size_t available; size_t available;
@ -707,8 +708,9 @@ static const tsi_frame_protector_vtable frame_protector_vtable = {
/* --- tsi_handshaker methods implementation. ---*/ /* --- tsi_handshaker methods implementation. ---*/
static tsi_result ssl_handshaker_get_bytes_to_send_to_peer( static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(tsi_handshaker* self,
tsi_handshaker* self, unsigned char* bytes, size_t* bytes_size) { unsigned char* bytes,
size_t* bytes_size) {
tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self; tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self;
int bytes_read_from_ssl = 0; int bytes_read_from_ssl = 0;
if (bytes == NULL || bytes_size == NULL || *bytes_size == 0 || if (bytes == NULL || bytes_size == NULL || *bytes_size == 0 ||
@ -871,8 +873,10 @@ static void ssl_handshaker_destroy(tsi_handshaker* self) {
static const tsi_handshaker_vtable handshaker_vtable = { static const tsi_handshaker_vtable handshaker_vtable = {
ssl_handshaker_get_bytes_to_send_to_peer, ssl_handshaker_get_bytes_to_send_to_peer,
ssl_handshaker_process_bytes_from_peer, ssl_handshaker_get_result, ssl_handshaker_process_bytes_from_peer,
ssl_handshaker_extract_peer, ssl_handshaker_create_frame_protector, ssl_handshaker_get_result,
ssl_handshaker_extract_peer,
ssl_handshaker_create_frame_protector,
ssl_handshaker_destroy, ssl_handshaker_destroy,
}; };
@ -1157,8 +1161,7 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
tsi_result tsi_create_ssl_server_handshaker_factory( tsi_result tsi_create_ssl_server_handshaker_factory(
const unsigned char** pem_private_keys, const unsigned char** pem_private_keys,
const size_t* pem_private_keys_sizes, const size_t* pem_private_keys_sizes, const unsigned char** pem_cert_chains,
const unsigned char** pem_cert_chains,
const size_t* pem_cert_chains_sizes, size_t key_cert_pair_count, const size_t* pem_cert_chains_sizes, size_t key_cert_pair_count,
const unsigned char* pem_client_root_certs, const unsigned char* pem_client_root_certs,
size_t pem_client_root_certs_size, const char* cipher_list, size_t pem_client_root_certs_size, const char* cipher_list,

@ -132,8 +132,7 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
where a parameter is invalid. */ where a parameter is invalid. */
tsi_result tsi_create_ssl_server_handshaker_factory( tsi_result tsi_create_ssl_server_handshaker_factory(
const unsigned char** pem_private_keys, const unsigned char** pem_private_keys,
const size_t* pem_private_keys_sizes, const size_t* pem_private_keys_sizes, const unsigned char** pem_cert_chains,
const unsigned char** pem_cert_chains,
const size_t* pem_cert_chains_sizes, size_t key_cert_pair_count, const size_t* pem_cert_chains_sizes, size_t key_cert_pair_count,
const unsigned char* pem_client_root_certs, const unsigned char* pem_client_root_certs,
size_t pem_client_root_certs_size, const char* cipher_suites, size_t pem_client_root_certs_size, const char* cipher_suites,

@ -53,7 +53,7 @@
namespace grpc { namespace grpc {
Channel::Channel(const grpc::string& target, const ChannelArguments& args) Channel::Channel(const grpc::string &target, const ChannelArguments &args)
: target_(target) { : target_(target) {
grpc_channel_args channel_args; grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args); args.SetChannelArgs(&channel_args);
@ -61,15 +61,15 @@ Channel::Channel(const grpc::string& target, const ChannelArguments& args)
target_.c_str(), channel_args.num_args > 0 ? &channel_args : nullptr); target_.c_str(), channel_args.num_args > 0 ? &channel_args : nullptr);
} }
Channel::Channel(const grpc::string& target, Channel::Channel(const grpc::string &target,
const std::unique_ptr<Credentials>& creds, const std::unique_ptr<Credentials> &creds,
const ChannelArguments& args) const ChannelArguments &args)
: target_(args.GetSslTargetNameOverride().empty() : target_(args.GetSslTargetNameOverride().empty()
? target ? target
: args.GetSslTargetNameOverride()) { : args.GetSslTargetNameOverride()) {
grpc_channel_args channel_args; grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args); args.SetChannelArgs(&channel_args);
grpc_credentials* c_creds = creds ? creds->GetRawCreds() : nullptr; grpc_credentials *c_creds = creds ? creds->GetRawCreds() : nullptr;
c_channel_ = grpc_secure_channel_create( c_channel_ = grpc_secure_channel_create(
c_creds, target.c_str(), c_creds, target.c_str(),
channel_args.num_args > 0 ? &channel_args : nullptr); channel_args.num_args > 0 ? &channel_args : nullptr);
@ -79,9 +79,9 @@ Channel::~Channel() { grpc_channel_destroy(c_channel_); }
namespace { namespace {
// Pluck the finished event and set to status when it is not nullptr. // Pluck the finished event and set to status when it is not nullptr.
void GetFinalStatus(grpc_completion_queue* cq, void* finished_tag, void GetFinalStatus(grpc_completion_queue *cq, void *finished_tag,
Status* status) { Status *status) {
grpc_event* ev = grpc_event *ev =
grpc_completion_queue_pluck(cq, finished_tag, gpr_inf_future); grpc_completion_queue_pluck(cq, finished_tag, gpr_inf_future);
if (status) { if (status) {
StatusCode error_code = static_cast<StatusCode>(ev->data.finished.status); StatusCode error_code = static_cast<StatusCode>(ev->data.finished.status);
@ -94,23 +94,23 @@ void GetFinalStatus(grpc_completion_queue* cq, void* finished_tag,
} // namespace } // namespace
// TODO(yangg) more error handling // TODO(yangg) more error handling
Status Channel::StartBlockingRpc(const RpcMethod& method, Status Channel::StartBlockingRpc(const RpcMethod &method,
ClientContext* context, ClientContext *context,
const google::protobuf::Message& request, const google::protobuf::Message &request,
google::protobuf::Message* result) { google::protobuf::Message *result) {
Status status; Status status;
grpc_call* call = grpc_channel_create_call( grpc_call *call = grpc_channel_create_call(
c_channel_, method.name(), target_.c_str(), context->RawDeadline()); c_channel_, method.name(), target_.c_str(), context->RawDeadline());
context->set_call(call); context->set_call(call);
grpc_event* ev; grpc_event *ev;
void* finished_tag = reinterpret_cast<char*>(call); void *finished_tag = reinterpret_cast<char *>(call);
void* invoke_tag = reinterpret_cast<char*>(call) + 1; void *invoke_tag = reinterpret_cast<char *>(call) + 1;
void* metadata_read_tag = reinterpret_cast<char*>(call) + 2; void *metadata_read_tag = reinterpret_cast<char *>(call) + 2;
void* write_tag = reinterpret_cast<char*>(call) + 3; void *write_tag = reinterpret_cast<char *>(call) + 3;
void* halfclose_tag = reinterpret_cast<char*>(call) + 4; void *halfclose_tag = reinterpret_cast<char *>(call) + 4;
void* read_tag = reinterpret_cast<char*>(call) + 5; void *read_tag = reinterpret_cast<char *>(call) + 5;
grpc_completion_queue* cq = grpc_completion_queue_create(); grpc_completion_queue *cq = grpc_completion_queue_create();
context->set_cq(cq); context->set_cq(cq);
// add_metadata from context // add_metadata from context
// //
@ -126,7 +126,7 @@ Status Channel::StartBlockingRpc(const RpcMethod& method,
return status; return status;
} }
// write request // write request
grpc_byte_buffer* write_buffer = nullptr; grpc_byte_buffer *write_buffer = nullptr;
success = SerializeProto(request, &write_buffer); success = SerializeProto(request, &write_buffer);
if (!success) { if (!success) {
grpc_call_cancel(call); grpc_call_cancel(call);
@ -172,14 +172,14 @@ Status Channel::StartBlockingRpc(const RpcMethod& method,
return status; return status;
} }
StreamContextInterface* Channel::CreateStream( StreamContextInterface *Channel::CreateStream(
const RpcMethod& method, ClientContext* context, const RpcMethod &method, ClientContext *context,
const google::protobuf::Message* request, const google::protobuf::Message *request,
google::protobuf::Message* result) { google::protobuf::Message *result) {
grpc_call* call = grpc_channel_create_call( grpc_call *call = grpc_channel_create_call(
c_channel_, method.name(), target_.c_str(), context->RawDeadline()); c_channel_, method.name(), target_.c_str(), context->RawDeadline());
context->set_call(call); context->set_call(call);
grpc_completion_queue* cq = grpc_completion_queue_create(); grpc_completion_queue *cq = grpc_completion_queue_create();
context->set_cq(cq); context->set_cq(cq);
return new StreamContext(method, context, request, result); return new StreamContext(method, context, request, result);
} }

@ -48,24 +48,24 @@ class StreamContextInterface;
class Channel : public ChannelInterface { class Channel : public ChannelInterface {
public: public:
Channel(const grpc::string& target, const ChannelArguments& args); Channel(const grpc::string &target, const ChannelArguments &args);
Channel(const grpc::string& target, const std::unique_ptr<Credentials>& creds, Channel(const grpc::string &target, const std::unique_ptr<Credentials> &creds,
const ChannelArguments& args); const ChannelArguments &args);
~Channel() override; ~Channel() override;
Status StartBlockingRpc(const RpcMethod& method, ClientContext* context, Status StartBlockingRpc(const RpcMethod &method, ClientContext *context,
const google::protobuf::Message& request, const google::protobuf::Message &request,
google::protobuf::Message* result) override; google::protobuf::Message *result) override;
StreamContextInterface* CreateStream( StreamContextInterface *CreateStream(
const RpcMethod& method, ClientContext* context, const RpcMethod &method, ClientContext *context,
const google::protobuf::Message* request, const google::protobuf::Message *request,
google::protobuf::Message* result) override; google::protobuf::Message *result) override;
private: private:
const grpc::string target_; const grpc::string target_;
grpc_channel* c_channel_; // owned grpc_channel *c_channel_; // owned
}; };
} // namespace grpc } // namespace grpc

@ -37,7 +37,7 @@
namespace grpc { namespace grpc {
void ChannelArguments::SetSslTargetNameOverride(const grpc::string& name) { void ChannelArguments::SetSslTargetNameOverride(const grpc::string &name) {
SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, name); SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, name);
} }
@ -50,32 +50,32 @@ grpc::string ChannelArguments::GetSslTargetNameOverride() const {
return ""; return "";
} }
void ChannelArguments::SetInt(const grpc::string& key, int value) { void ChannelArguments::SetInt(const grpc::string &key, int value) {
grpc_arg arg; grpc_arg arg;
arg.type = GRPC_ARG_INTEGER; arg.type = GRPC_ARG_INTEGER;
strings_.push_back(key); strings_.push_back(key);
arg.key = const_cast<char*>(strings_.back().c_str()); arg.key = const_cast<char *>(strings_.back().c_str());
arg.value.integer = value; arg.value.integer = value;
args_.push_back(arg); args_.push_back(arg);
} }
void ChannelArguments::SetString(const grpc::string& key, void ChannelArguments::SetString(const grpc::string &key,
const grpc::string& value) { const grpc::string &value) {
grpc_arg arg; grpc_arg arg;
arg.type = GRPC_ARG_STRING; arg.type = GRPC_ARG_STRING;
strings_.push_back(key); strings_.push_back(key);
arg.key = const_cast<char*>(strings_.back().c_str()); arg.key = const_cast<char *>(strings_.back().c_str());
strings_.push_back(value); strings_.push_back(value);
arg.value.string = const_cast<char*>(strings_.back().c_str()); arg.value.string = const_cast<char *>(strings_.back().c_str());
args_.push_back(arg); args_.push_back(arg);
} }
void ChannelArguments::SetChannelArgs(grpc_channel_args* channel_args) const { void ChannelArguments::SetChannelArgs(grpc_channel_args *channel_args) const {
channel_args->num_args = args_.size(); channel_args->num_args = args_.size();
if (channel_args->num_args > 0) { if (channel_args->num_args > 0) {
channel_args->args = const_cast<grpc_arg*>(&args_[0]); channel_args->args = const_cast<grpc_arg *>(&args_[0]);
} }
} }

@ -50,7 +50,7 @@ ClientContext::~ClientContext() {
if (cq_) { if (cq_) {
grpc_completion_queue_shutdown(cq_); grpc_completion_queue_shutdown(cq_);
// Drain cq_. // Drain cq_.
grpc_event* ev; grpc_event *ev;
grpc_completion_type t; grpc_completion_type t;
do { do {
ev = grpc_completion_queue_next(cq_, gpr_inf_future); ev = grpc_completion_queue_next(cq_, gpr_inf_future);
@ -62,7 +62,7 @@ ClientContext::~ClientContext() {
} }
void ClientContext::set_absolute_deadline( void ClientContext::set_absolute_deadline(
const system_clock::time_point& deadline) { const system_clock::time_point &deadline) {
Timepoint2Timespec(deadline, &absolute_deadline_); Timepoint2Timespec(deadline, &absolute_deadline_);
} }
@ -70,8 +70,8 @@ system_clock::time_point ClientContext::absolute_deadline() {
return Timespec2Timepoint(absolute_deadline_); return Timespec2Timepoint(absolute_deadline_);
} }
void ClientContext::AddMetadata(const grpc::string& meta_key, void ClientContext::AddMetadata(const grpc::string &meta_key,
const grpc::string& meta_value) { const grpc::string &meta_value) {
return; return;
} }

@ -40,14 +40,14 @@
namespace grpc { namespace grpc {
class ChannelArguments; class ChannelArguments;
std::shared_ptr<ChannelInterface> CreateChannel(const grpc::string& target, std::shared_ptr<ChannelInterface> CreateChannel(const grpc::string &target,
const ChannelArguments& args) { const ChannelArguments &args) {
return std::shared_ptr<ChannelInterface>(new Channel(target, args)); return std::shared_ptr<ChannelInterface>(new Channel(target, args));
} }
std::shared_ptr<ChannelInterface> CreateChannel( std::shared_ptr<ChannelInterface> CreateChannel(
const grpc::string& target, const std::unique_ptr<Credentials>& creds, const grpc::string &target, const std::unique_ptr<Credentials> &creds,
const ChannelArguments& args) { const ChannelArguments &args) {
return std::shared_ptr<ChannelInterface>(new Channel(target, creds, args)); return std::shared_ptr<ChannelInterface>(new Channel(target, creds, args));
} }
} // namespace grpc } // namespace grpc

@ -40,37 +40,37 @@
namespace grpc { namespace grpc {
Credentials::Credentials(grpc_credentials* c_creds) : creds_(c_creds) {} Credentials::Credentials(grpc_credentials *c_creds) : creds_(c_creds) {}
Credentials::~Credentials() { grpc_credentials_release(creds_); } Credentials::~Credentials() { grpc_credentials_release(creds_); }
grpc_credentials* Credentials::GetRawCreds() { return creds_; } grpc_credentials *Credentials::GetRawCreds() { return creds_; }
std::unique_ptr<Credentials> CredentialsFactory::DefaultCredentials() { std::unique_ptr<Credentials> CredentialsFactory::DefaultCredentials() {
grpc_credentials* c_creds = grpc_default_credentials_create(); grpc_credentials *c_creds = grpc_default_credentials_create();
std::unique_ptr<Credentials> cpp_creds(new Credentials(c_creds)); std::unique_ptr<Credentials> cpp_creds(new Credentials(c_creds));
return cpp_creds; return cpp_creds;
} }
// Builds SSL Credentials given SSL specific options // Builds SSL Credentials given SSL specific options
std::unique_ptr<Credentials> CredentialsFactory::SslCredentials( std::unique_ptr<Credentials> CredentialsFactory::SslCredentials(
const SslCredentialsOptions& options) { const SslCredentialsOptions &options) {
const unsigned char* pem_root_certs = const unsigned char *pem_root_certs =
options.pem_root_certs.empty() ? nullptr options.pem_root_certs.empty() ? nullptr
: reinterpret_cast<const unsigned char*>( : reinterpret_cast<const unsigned char *>(
options.pem_root_certs.c_str()); options.pem_root_certs.c_str());
if (pem_root_certs == nullptr) { if (pem_root_certs == nullptr) {
return std::unique_ptr<Credentials>(); return std::unique_ptr<Credentials>();
} }
const unsigned char* pem_private_key = const unsigned char *pem_private_key =
options.pem_private_key.empty() ? nullptr options.pem_private_key.empty() ? nullptr
: reinterpret_cast<const unsigned char*>( : reinterpret_cast<const unsigned char *>(
options.pem_private_key.c_str()); options.pem_private_key.c_str());
const unsigned char* pem_cert_chain = const unsigned char *pem_cert_chain =
options.pem_cert_chain.empty() ? nullptr options.pem_cert_chain.empty() ? nullptr
: reinterpret_cast<const unsigned char*>( : reinterpret_cast<const unsigned char *>(
options.pem_cert_chain.c_str()); options.pem_cert_chain.c_str());
grpc_credentials* c_creds = grpc_ssl_credentials_create( grpc_credentials *c_creds = grpc_ssl_credentials_create(
pem_root_certs, options.pem_root_certs.size(), pem_private_key, pem_root_certs, options.pem_root_certs.size(), pem_private_key,
options.pem_private_key.size(), pem_cert_chain, options.pem_private_key.size(), pem_cert_chain,
options.pem_cert_chain.size()); options.pem_cert_chain.size());
@ -81,7 +81,7 @@ std::unique_ptr<Credentials> CredentialsFactory::SslCredentials(
// Builds credentials for use when running in GCE // Builds credentials for use when running in GCE
std::unique_ptr<Credentials> CredentialsFactory::ComputeEngineCredentials() { std::unique_ptr<Credentials> CredentialsFactory::ComputeEngineCredentials() {
grpc_credentials* c_creds = grpc_compute_engine_credentials_create(); grpc_credentials *c_creds = grpc_compute_engine_credentials_create();
std::unique_ptr<Credentials> cpp_creds( std::unique_ptr<Credentials> cpp_creds(
c_creds == nullptr ? nullptr : new Credentials(c_creds)); c_creds == nullptr ? nullptr : new Credentials(c_creds));
return cpp_creds; return cpp_creds;
@ -89,11 +89,11 @@ std::unique_ptr<Credentials> CredentialsFactory::ComputeEngineCredentials() {
// Builds service account credentials. // Builds service account credentials.
std::unique_ptr<Credentials> CredentialsFactory::ServiceAccountCredentials( std::unique_ptr<Credentials> CredentialsFactory::ServiceAccountCredentials(
const grpc::string& json_key, const grpc::string& scope, const grpc::string &json_key, const grpc::string &scope,
std::chrono::seconds token_lifetime) { std::chrono::seconds token_lifetime) {
gpr_timespec lifetime = gpr_time_from_seconds( gpr_timespec lifetime = gpr_time_from_seconds(
token_lifetime.count() > 0 ? token_lifetime.count() : 0); token_lifetime.count() > 0 ? token_lifetime.count() : 0);
grpc_credentials* c_creds = grpc_service_account_credentials_create( grpc_credentials *c_creds = grpc_service_account_credentials_create(
json_key.c_str(), scope.c_str(), lifetime); json_key.c_str(), scope.c_str(), lifetime);
std::unique_ptr<Credentials> cpp_creds( std::unique_ptr<Credentials> cpp_creds(
c_creds == nullptr ? nullptr : new Credentials(c_creds)); c_creds == nullptr ? nullptr : new Credentials(c_creds));
@ -102,9 +102,9 @@ std::unique_ptr<Credentials> CredentialsFactory::ServiceAccountCredentials(
// Builds IAM credentials. // Builds IAM credentials.
std::unique_ptr<Credentials> CredentialsFactory::IAMCredentials( std::unique_ptr<Credentials> CredentialsFactory::IAMCredentials(
const grpc::string& authorization_token, const grpc::string &authorization_token,
const grpc::string& authority_selector) { const grpc::string &authority_selector) {
grpc_credentials* c_creds = grpc_iam_credentials_create( grpc_credentials *c_creds = grpc_iam_credentials_create(
authorization_token.c_str(), authority_selector.c_str()); authorization_token.c_str(), authority_selector.c_str());
std::unique_ptr<Credentials> cpp_creds( std::unique_ptr<Credentials> cpp_creds(
c_creds == nullptr ? nullptr : new Credentials(c_creds)); c_creds == nullptr ? nullptr : new Credentials(c_creds));
@ -113,13 +113,13 @@ std::unique_ptr<Credentials> CredentialsFactory::IAMCredentials(
// Combines two credentials objects into a composite credentials. // Combines two credentials objects into a composite credentials.
std::unique_ptr<Credentials> CredentialsFactory::ComposeCredentials( std::unique_ptr<Credentials> CredentialsFactory::ComposeCredentials(
const std::unique_ptr<Credentials>& creds1, const std::unique_ptr<Credentials> &creds1,
const std::unique_ptr<Credentials>& creds2) { const std::unique_ptr<Credentials> &creds2) {
// Note that we are not saving unique_ptrs to the two credentials // Note that we are not saving unique_ptrs to the two credentials
// passed in here. This is OK because the underlying C objects (i.e., // passed in here. This is OK because the underlying C objects (i.e.,
// creds1 and creds2) into grpc_composite_credentials_create will see their // creds1 and creds2) into grpc_composite_credentials_create will see their
// refcounts incremented. // refcounts incremented.
grpc_credentials* c_creds = grpc_composite_credentials_create( grpc_credentials *c_creds = grpc_composite_credentials_create(
creds1->GetRawCreds(), creds2->GetRawCreds()); creds1->GetRawCreds(), creds2->GetRawCreds());
std::unique_ptr<Credentials> cpp_creds( std::unique_ptr<Credentials> cpp_creds(
c_creds == nullptr ? nullptr : new Credentials(c_creds)); c_creds == nullptr ? nullptr : new Credentials(c_creds));

@ -40,8 +40,8 @@
namespace grpc { namespace grpc {
bool SerializeProto(const google::protobuf::Message& msg, bool SerializeProto(const google::protobuf::Message &msg,
grpc_byte_buffer** bp) { grpc_byte_buffer **bp) {
grpc::string msg_str; grpc::string msg_str;
bool success = msg.SerializeToString(&msg_str); bool success = msg.SerializeToString(&msg_str);
if (success) { if (success) {
@ -53,13 +53,13 @@ bool SerializeProto(const google::protobuf::Message& msg,
return success; return success;
} }
bool DeserializeProto(grpc_byte_buffer* buffer, bool DeserializeProto(grpc_byte_buffer *buffer,
google::protobuf::Message* msg) { google::protobuf::Message *msg) {
grpc::string msg_string; grpc::string msg_string;
grpc_byte_buffer_reader* reader = grpc_byte_buffer_reader_create(buffer); grpc_byte_buffer_reader *reader = grpc_byte_buffer_reader_create(buffer);
gpr_slice slice; gpr_slice slice;
while (grpc_byte_buffer_reader_next(reader, &slice)) { while (grpc_byte_buffer_reader_next(reader, &slice)) {
const char* data = reinterpret_cast<const char*>( const char *data = reinterpret_cast<const char *>(
slice.refcount ? slice.data.refcounted.bytes slice.refcount ? slice.data.refcounted.bytes
: slice.data.inlined.bytes); : slice.data.inlined.bytes);
msg_string.append(data, slice.refcount ? slice.data.refcounted.length msg_string.append(data, slice.refcount ? slice.data.refcounted.length

@ -46,11 +46,11 @@ namespace grpc {
// Serialize the msg into a buffer created inside the function. The caller // Serialize the msg into a buffer created inside the function. The caller
// should destroy the returned buffer when done with it. If serialization fails, // should destroy the returned buffer when done with it. If serialization fails,
// false is returned and buffer is left unchanged. // false is returned and buffer is left unchanged.
bool SerializeProto(const google::protobuf::Message& msg, bool SerializeProto(const google::protobuf::Message &msg,
grpc_byte_buffer** buffer); grpc_byte_buffer **buffer);
// The caller keeps ownership of buffer and msg. // The caller keeps ownership of buffer and msg.
bool DeserializeProto(grpc_byte_buffer* buffer, google::protobuf::Message* msg); bool DeserializeProto(grpc_byte_buffer *buffer, google::protobuf::Message *msg);
} // namespace grpc } // namespace grpc

@ -39,7 +39,7 @@
namespace grpc { namespace grpc {
AsyncServer::AsyncServer(CompletionQueue* cc) AsyncServer::AsyncServer(CompletionQueue *cc)
: started_(false), shutdown_(false) { : started_(false), shutdown_(false) {
server_ = grpc_server_create(cc->cq(), nullptr); server_ = grpc_server_create(cc->cq(), nullptr);
} }
@ -53,7 +53,7 @@ AsyncServer::~AsyncServer() {
grpc_server_destroy(server_); grpc_server_destroy(server_);
} }
void AsyncServer::AddPort(const grpc::string& addr) { void AsyncServer::AddPort(const grpc::string &addr) {
GPR_ASSERT(!started_); GPR_ASSERT(!started_);
int success = grpc_server_add_http2_port(server_, addr.c_str()); int success = grpc_server_add_http2_port(server_, addr.c_str());
GPR_ASSERT(success); GPR_ASSERT(success);

@ -42,7 +42,7 @@
namespace grpc { namespace grpc {
AsyncServerContext::AsyncServerContext( AsyncServerContext::AsyncServerContext(
grpc_call* call, const grpc::string& method, const grpc::string& host, grpc_call *call, const grpc::string &method, const grpc::string &host,
system_clock::time_point absolute_deadline) system_clock::time_point absolute_deadline)
: method_(method), : method_(method),
host_(host), host_(host),
@ -52,21 +52,21 @@ AsyncServerContext::AsyncServerContext(
AsyncServerContext::~AsyncServerContext() { grpc_call_destroy(call_); } AsyncServerContext::~AsyncServerContext() { grpc_call_destroy(call_); }
void AsyncServerContext::Accept(grpc_completion_queue* cq) { void AsyncServerContext::Accept(grpc_completion_queue *cq) {
GPR_ASSERT(grpc_call_server_accept(call_, cq, this) == GRPC_CALL_OK); GPR_ASSERT(grpc_call_server_accept(call_, cq, this) == GRPC_CALL_OK);
GPR_ASSERT(grpc_call_server_end_initial_metadata(call_, 0) == GRPC_CALL_OK); GPR_ASSERT(grpc_call_server_end_initial_metadata(call_, 0) == GRPC_CALL_OK);
} }
bool AsyncServerContext::StartRead(google::protobuf::Message* request) { bool AsyncServerContext::StartRead(google::protobuf::Message *request) {
GPR_ASSERT(request); GPR_ASSERT(request);
request_ = request; request_ = request;
grpc_call_error err = grpc_call_start_read(call_, this); grpc_call_error err = grpc_call_start_read(call_, this);
return err == GRPC_CALL_OK; return err == GRPC_CALL_OK;
} }
bool AsyncServerContext::StartWrite(const google::protobuf::Message& response, bool AsyncServerContext::StartWrite(const google::protobuf::Message &response,
int flags) { int flags) {
grpc_byte_buffer* buffer = nullptr; grpc_byte_buffer *buffer = nullptr;
if (!SerializeProto(response, &buffer)) { if (!SerializeProto(response, &buffer)) {
return false; return false;
} }
@ -75,16 +75,16 @@ bool AsyncServerContext::StartWrite(const google::protobuf::Message& response,
return err == GRPC_CALL_OK; return err == GRPC_CALL_OK;
} }
bool AsyncServerContext::StartWriteStatus(const Status& status) { bool AsyncServerContext::StartWriteStatus(const Status &status) {
grpc_call_error err = grpc_call_start_write_status( grpc_call_error err = grpc_call_start_write_status(
call_, static_cast<grpc_status_code>(status.code()), call_, static_cast<grpc_status_code>(status.code()),
status.details().empty() ? nullptr status.details().empty() ? nullptr
: const_cast<char*>(status.details().c_str()), : const_cast<char *>(status.details().c_str()),
this); this);
return err == GRPC_CALL_OK; return err == GRPC_CALL_OK;
} }
bool AsyncServerContext::ParseRead(grpc_byte_buffer* read_buffer) { bool AsyncServerContext::ParseRead(grpc_byte_buffer *read_buffer) {
GPR_ASSERT(request_); GPR_ASSERT(request_);
bool success = DeserializeProto(read_buffer, request_); bool success = DeserializeProto(read_buffer, request_);
request_ = nullptr; request_ = nullptr;

@ -48,8 +48,8 @@ CompletionQueue::~CompletionQueue() { grpc_completion_queue_destroy(cq_); }
void CompletionQueue::Shutdown() { grpc_completion_queue_shutdown(cq_); } void CompletionQueue::Shutdown() { grpc_completion_queue_shutdown(cq_); }
CompletionQueue::CompletionType CompletionQueue::Next(void** tag) { CompletionQueue::CompletionType CompletionQueue::Next(void **tag) {
grpc_event* ev; grpc_event *ev;
CompletionType return_type; CompletionType return_type;
bool success; bool success;
@ -65,8 +65,8 @@ CompletionQueue::CompletionType CompletionQueue::Next(void** tag) {
case GRPC_READ: case GRPC_READ:
*tag = ev->tag; *tag = ev->tag;
if (ev->data.read) { if (ev->data.read) {
success = success = static_cast<AsyncServerContext *>(ev->tag)
static_cast<AsyncServerContext*>(ev->tag)->ParseRead(ev->data.read); ->ParseRead(ev->data.read);
return_type = success ? SERVER_READ_OK : SERVER_READ_ERROR; return_type = success ? SERVER_READ_OK : SERVER_READ_ERROR;
} else { } else {
return_type = SERVER_READ_ERROR; return_type = SERVER_READ_ERROR;

@ -49,7 +49,7 @@ namespace grpc {
// TODO(rocking): consider a better default value like num of cores. // TODO(rocking): consider a better default value like num of cores.
static const int kNumThreads = 4; static const int kNumThreads = 4;
Server::Server(ThreadPoolInterface* thread_pool, ServerCredentials* creds) Server::Server(ThreadPoolInterface *thread_pool, ServerCredentials *creds)
: started_(false), : started_(false),
shutdown_(false), shutdown_(false),
num_running_cb_(0), num_running_cb_(0),
@ -82,14 +82,14 @@ Server::~Server() {
} }
} }
void Server::RegisterService(RpcService* service) { void Server::RegisterService(RpcService *service) {
for (int i = 0; i < service->GetMethodCount(); ++i) { for (int i = 0; i < service->GetMethodCount(); ++i) {
RpcServiceMethod* method = service->GetMethod(i); RpcServiceMethod *method = service->GetMethod(i);
method_map_.insert(std::make_pair(method->name(), method)); method_map_.insert(std::make_pair(method->name(), method));
} }
} }
void Server::AddPort(const grpc::string& addr) { void Server::AddPort(const grpc::string &addr) {
GPR_ASSERT(!started_); GPR_ASSERT(!started_);
int success; int success;
if (secure_) { if (secure_) {
@ -131,7 +131,7 @@ void Server::Shutdown() {
// Shutdown the completion queue. // Shutdown the completion queue.
cq_.Shutdown(); cq_.Shutdown();
void* tag = nullptr; void *tag = nullptr;
CompletionQueue::CompletionType t = cq_.Next(&tag); CompletionQueue::CompletionType t = cq_.Next(&tag);
GPR_ASSERT(t == CompletionQueue::QUEUE_CLOSED); GPR_ASSERT(t == CompletionQueue::QUEUE_CLOSED);
} }
@ -147,18 +147,18 @@ void Server::ScheduleCallback() {
void Server::RunRpc() { void Server::RunRpc() {
// Wait for one more incoming rpc. // Wait for one more incoming rpc.
void* tag = nullptr; void *tag = nullptr;
AllowOneRpc(); AllowOneRpc();
CompletionQueue::CompletionType t = cq_.Next(&tag); CompletionQueue::CompletionType t = cq_.Next(&tag);
GPR_ASSERT(t == CompletionQueue::SERVER_RPC_NEW); GPR_ASSERT(t == CompletionQueue::SERVER_RPC_NEW);
AsyncServerContext* server_context = static_cast<AsyncServerContext*>(tag); AsyncServerContext *server_context = static_cast<AsyncServerContext *>(tag);
// server_context could be nullptr during server shutdown. // server_context could be nullptr during server shutdown.
if (server_context != nullptr) { if (server_context != nullptr) {
// Schedule a new callback to handle more rpcs. // Schedule a new callback to handle more rpcs.
ScheduleCallback(); ScheduleCallback();
RpcServiceMethod* method = nullptr; RpcServiceMethod *method = nullptr;
auto iter = method_map_.find(server_context->method()); auto iter = method_map_.find(server_context->method());
if (iter != method_map_.end()) { if (iter != method_map_.end()) {
method = iter->second; method = iter->second;

@ -40,30 +40,30 @@ namespace grpc {
ServerBuilder::ServerBuilder() : thread_pool_(nullptr) {} ServerBuilder::ServerBuilder() : thread_pool_(nullptr) {}
void ServerBuilder::RegisterService(RpcService* service) { void ServerBuilder::RegisterService(RpcService *service) {
services_.push_back(service); services_.push_back(service);
} }
void ServerBuilder::AddPort(const grpc::string& addr) { void ServerBuilder::AddPort(const grpc::string &addr) {
ports_.push_back(addr); ports_.push_back(addr);
} }
void ServerBuilder::SetCredentials( void ServerBuilder::SetCredentials(
const std::shared_ptr<ServerCredentials>& creds) { const std::shared_ptr<ServerCredentials> &creds) {
GPR_ASSERT(!creds_); GPR_ASSERT(!creds_);
creds_ = creds; creds_ = creds;
} }
void ServerBuilder::SetThreadPool(ThreadPoolInterface* thread_pool) { void ServerBuilder::SetThreadPool(ThreadPoolInterface *thread_pool) {
thread_pool_ = thread_pool; thread_pool_ = thread_pool;
} }
std::unique_ptr<Server> ServerBuilder::BuildAndStart() { std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
std::unique_ptr<Server> server(new Server(thread_pool_, creds_.get())); std::unique_ptr<Server> server(new Server(thread_pool_, creds_.get()));
for (auto* service : services_) { for (auto *service : services_) {
server->RegisterService(service); server->RegisterService(service);
} }
for (auto& port : ports_) { for (auto &port : ports_) {
server->AddPort(port); server->AddPort(port);
} }
server->Start(); server->Start();

@ -37,31 +37,31 @@
namespace grpc { namespace grpc {
ServerCredentials::ServerCredentials(grpc_server_credentials* c_creds) ServerCredentials::ServerCredentials(grpc_server_credentials *c_creds)
: creds_(c_creds) {} : creds_(c_creds) {}
ServerCredentials::~ServerCredentials() { ServerCredentials::~ServerCredentials() {
grpc_server_credentials_release(creds_); grpc_server_credentials_release(creds_);
} }
grpc_server_credentials* ServerCredentials::GetRawCreds() { return creds_; } grpc_server_credentials *ServerCredentials::GetRawCreds() { return creds_; }
std::shared_ptr<ServerCredentials> ServerCredentialsFactory::SslCredentials( std::shared_ptr<ServerCredentials> ServerCredentialsFactory::SslCredentials(
const SslServerCredentialsOptions& options) { const SslServerCredentialsOptions &options) {
const unsigned char* pem_root_certs = const unsigned char *pem_root_certs =
options.pem_root_certs.empty() ? nullptr options.pem_root_certs.empty() ? nullptr
: reinterpret_cast<const unsigned char*>( : reinterpret_cast<const unsigned char *>(
options.pem_root_certs.c_str()); options.pem_root_certs.c_str());
const unsigned char* pem_private_key = const unsigned char *pem_private_key =
options.pem_private_key.empty() ? nullptr options.pem_private_key.empty() ? nullptr
: reinterpret_cast<const unsigned char*>( : reinterpret_cast<const unsigned char *>(
options.pem_private_key.c_str()); options.pem_private_key.c_str());
const unsigned char* pem_cert_chain = const unsigned char *pem_cert_chain =
options.pem_cert_chain.empty() ? nullptr options.pem_cert_chain.empty() ? nullptr
: reinterpret_cast<const unsigned char*>( : reinterpret_cast<const unsigned char *>(
options.pem_cert_chain.c_str()); options.pem_cert_chain.c_str());
grpc_server_credentials* c_creds = grpc_ssl_server_credentials_create( grpc_server_credentials *c_creds = grpc_ssl_server_credentials_create(
pem_root_certs, options.pem_root_certs.size(), pem_private_key, pem_root_certs, options.pem_root_certs.size(), pem_private_key,
options.pem_private_key.size(), pem_cert_chain, options.pem_private_key.size(), pem_cert_chain,
options.pem_cert_chain.size()); options.pem_cert_chain.size());

@ -41,8 +41,8 @@
namespace grpc { namespace grpc {
ServerRpcHandler::ServerRpcHandler(AsyncServerContext* async_server_context, ServerRpcHandler::ServerRpcHandler(AsyncServerContext *async_server_context,
RpcServiceMethod* method) RpcServiceMethod *method)
: async_server_context_(async_server_context), method_(method) {} : async_server_context_(async_server_context), method_(method) {}
void ServerRpcHandler::StartRpc() { void ServerRpcHandler::StartRpc() {
@ -71,7 +71,7 @@ void ServerRpcHandler::StartRpc() {
GPR_ASSERT(type == CompletionQueue::SERVER_READ_OK); GPR_ASSERT(type == CompletionQueue::SERVER_READ_OK);
// Run the application's rpc handler // Run the application's rpc handler
MethodHandler* handler = method_->handler(); MethodHandler *handler = method_->handler();
Status status = handler->RunHandler(MethodHandler::HandlerParameter( Status status = handler->RunHandler(MethodHandler::HandlerParameter(
&user_context, request.get(), response.get())); &user_context, request.get(), response.get()));
@ -97,7 +97,7 @@ void ServerRpcHandler::StartRpc() {
cq_.cq(), request.get(), response.get()); cq_.cq(), request.get(), response.get());
// Run the application's rpc handler // Run the application's rpc handler
MethodHandler* handler = method_->handler(); MethodHandler *handler = method_->handler();
Status status = handler->RunHandler(MethodHandler::HandlerParameter( Status status = handler->RunHandler(MethodHandler::HandlerParameter(
&user_context, request.get(), response.get(), &stream_context)); &user_context, request.get(), response.get(), &stream_context));
if (status.IsOk() && if (status.IsOk() &&
@ -110,17 +110,17 @@ void ServerRpcHandler::StartRpc() {
} }
CompletionQueue::CompletionType ServerRpcHandler::WaitForNextEvent() { CompletionQueue::CompletionType ServerRpcHandler::WaitForNextEvent() {
void* tag = nullptr; void *tag = nullptr;
CompletionQueue::CompletionType type = cq_.Next(&tag); CompletionQueue::CompletionType type = cq_.Next(&tag);
if (type != CompletionQueue::QUEUE_CLOSED && if (type != CompletionQueue::QUEUE_CLOSED &&
type != CompletionQueue::RPC_END) { type != CompletionQueue::RPC_END) {
GPR_ASSERT(static_cast<AsyncServerContext*>(tag) == GPR_ASSERT(static_cast<AsyncServerContext *>(tag) ==
async_server_context_.get()); async_server_context_.get());
} }
return type; return type;
} }
void ServerRpcHandler::FinishRpc(const Status& status) { void ServerRpcHandler::FinishRpc(const Status &status) {
async_server_context_->StartWriteStatus(status); async_server_context_->StartWriteStatus(status);
CompletionQueue::CompletionType type; CompletionQueue::CompletionType type;

@ -47,17 +47,17 @@ class RpcServiceMethod;
class ServerRpcHandler { class ServerRpcHandler {
public: public:
// Takes ownership of async_server_context. // Takes ownership of async_server_context.
ServerRpcHandler(AsyncServerContext* async_server_context, ServerRpcHandler(AsyncServerContext *async_server_context,
RpcServiceMethod* method); RpcServiceMethod *method);
void StartRpc(); void StartRpc();
private: private:
CompletionQueue::CompletionType WaitForNextEvent(); CompletionQueue::CompletionType WaitForNextEvent();
void FinishRpc(const Status& status); void FinishRpc(const Status &status);
std::unique_ptr<AsyncServerContext> async_server_context_; std::unique_ptr<AsyncServerContext> async_server_context_;
RpcServiceMethod* method_; RpcServiceMethod *method_;
CompletionQueue cq_; CompletionQueue cq_;
}; };

@ -63,12 +63,12 @@ ThreadPool::~ThreadPool() {
shutdown_ = true; shutdown_ = true;
cv_.notify_all(); cv_.notify_all();
} }
for (auto& t : threads_) { for (auto &t : threads_) {
t.join(); t.join();
} }
} }
void ThreadPool::ScheduleCallback(const std::function<void()>& callback) { void ThreadPool::ScheduleCallback(const std::function<void()> &callback) {
std::lock_guard<std::mutex> lock(mu_); std::lock_guard<std::mutex> lock(mu_);
callbacks_.push(callback); callbacks_.push(callback);
cv_.notify_all(); cv_.notify_all();

@ -49,7 +49,7 @@ class ThreadPool : public ThreadPoolInterface {
explicit ThreadPool(int num_threads); explicit ThreadPool(int num_threads);
~ThreadPool(); ~ThreadPool();
void ScheduleCallback(const std::function<void()>& callback) final; void ScheduleCallback(const std::function<void()> &callback) final;
private: private:
std::mutex mu_; std::mutex mu_;

@ -44,14 +44,14 @@
namespace grpc { namespace grpc {
// Client only ctor // Client only ctor
StreamContext::StreamContext(const RpcMethod& method, ClientContext* context, StreamContext::StreamContext(const RpcMethod &method, ClientContext *context,
const google::protobuf::Message* request, const google::protobuf::Message *request,
google::protobuf::Message* result) google::protobuf::Message *result)
: is_client_(true), : is_client_(true),
method_(&method), method_(&method),
call_(context->call()), call_(context->call()),
cq_(context->cq()), cq_(context->cq()),
request_(const_cast<google::protobuf::Message*>(request)), request_(const_cast<google::protobuf::Message *>(request)),
result_(result), result_(result),
peer_halfclosed_(false), peer_halfclosed_(false),
self_halfclosed_(false) { self_halfclosed_(false) {
@ -59,10 +59,10 @@ StreamContext::StreamContext(const RpcMethod& method, ClientContext* context,
} }
// Server only ctor // Server only ctor
StreamContext::StreamContext(const RpcMethod& method, grpc_call* call, StreamContext::StreamContext(const RpcMethod &method, grpc_call *call,
grpc_completion_queue* cq, grpc_completion_queue *cq,
google::protobuf::Message* request, google::protobuf::Message *request,
google::protobuf::Message* result) google::protobuf::Message *result)
: is_client_(false), : is_client_(false),
method_(&method), method_(&method),
call_(call), call_(call),
@ -84,7 +84,7 @@ void StreamContext::Start(bool buffered) {
client_metadata_read_tag(), client_metadata_read_tag(),
finished_tag(), flag); finished_tag(), flag);
GPR_ASSERT(GRPC_CALL_OK == error); GPR_ASSERT(GRPC_CALL_OK == error);
grpc_event* invoke_ev = grpc_event *invoke_ev =
grpc_completion_queue_pluck(cq(), invoke_tag(), gpr_inf_future); grpc_completion_queue_pluck(cq(), invoke_tag(), gpr_inf_future);
if (invoke_ev->data.invoke_accepted != GRPC_OP_OK) { if (invoke_ev->data.invoke_accepted != GRPC_OP_OK) {
peer_halfclosed_ = true; peer_halfclosed_ = true;
@ -101,11 +101,11 @@ void StreamContext::Start(bool buffered) {
} }
} }
bool StreamContext::Read(google::protobuf::Message* msg) { bool StreamContext::Read(google::protobuf::Message *msg) {
// TODO(yangg) check peer_halfclosed_ here for possible early return. // TODO(yangg) check peer_halfclosed_ here for possible early return.
grpc_call_error err = grpc_call_start_read(call(), read_tag()); grpc_call_error err = grpc_call_start_read(call(), read_tag());
GPR_ASSERT(err == GRPC_CALL_OK); GPR_ASSERT(err == GRPC_CALL_OK);
grpc_event* read_ev = grpc_event *read_ev =
grpc_completion_queue_pluck(cq(), read_tag(), gpr_inf_future); grpc_completion_queue_pluck(cq(), read_tag(), gpr_inf_future);
GPR_ASSERT(read_ev->type == GRPC_READ); GPR_ASSERT(read_ev->type == GRPC_READ);
bool ret = true; bool ret = true;
@ -123,13 +123,13 @@ bool StreamContext::Read(google::protobuf::Message* msg) {
return ret; return ret;
} }
bool StreamContext::Write(const google::protobuf::Message* msg, bool is_last) { bool StreamContext::Write(const google::protobuf::Message *msg, bool is_last) {
// TODO(yangg) check self_halfclosed_ for possible early return. // TODO(yangg) check self_halfclosed_ for possible early return.
bool ret = true; bool ret = true;
grpc_event* ev = nullptr; grpc_event *ev = nullptr;
if (msg) { if (msg) {
grpc_byte_buffer* out_buf = nullptr; grpc_byte_buffer *out_buf = nullptr;
if (!SerializeProto(*msg, &out_buf)) { if (!SerializeProto(*msg, &out_buf)) {
grpc_call_cancel_with_status(call(), GRPC_STATUS_INVALID_ARGUMENT, grpc_call_cancel_with_status(call(), GRPC_STATUS_INVALID_ARGUMENT,
"Failed to serialize outgoing proto"); "Failed to serialize outgoing proto");
@ -163,16 +163,16 @@ bool StreamContext::Write(const google::protobuf::Message* msg, bool is_last) {
return ret; return ret;
} }
const Status& StreamContext::Wait() { const Status &StreamContext::Wait() {
// TODO(yangg) properly support metadata // TODO(yangg) properly support metadata
grpc_event* metadata_ev = grpc_completion_queue_pluck( grpc_event *metadata_ev = grpc_completion_queue_pluck(
cq(), client_metadata_read_tag(), gpr_inf_future); cq(), client_metadata_read_tag(), gpr_inf_future);
grpc_event_finish(metadata_ev); grpc_event_finish(metadata_ev);
// TODO(yangg) protect states by a mutex, including other places. // TODO(yangg) protect states by a mutex, including other places.
if (!self_halfclosed_ || !peer_halfclosed_) { if (!self_halfclosed_ || !peer_halfclosed_) {
Cancel(); Cancel();
} }
grpc_event* finish_ev = grpc_event *finish_ev =
grpc_completion_queue_pluck(cq(), finished_tag(), gpr_inf_future); grpc_completion_queue_pluck(cq(), finished_tag(), gpr_inf_future);
GPR_ASSERT(finish_ev->type == GRPC_FINISHED); GPR_ASSERT(finish_ev->type == GRPC_FINISHED);
final_status_ = Status( final_status_ = Status(

@ -50,43 +50,45 @@ class RpcMethod;
class StreamContext final : public StreamContextInterface { class StreamContext final : public StreamContextInterface {
public: public:
StreamContext(const RpcMethod& method, ClientContext* context, StreamContext(const RpcMethod &method, ClientContext *context,
const google::protobuf::Message* request, const google::protobuf::Message *request,
google::protobuf::Message* result); google::protobuf::Message *result);
StreamContext(const RpcMethod& method, grpc_call* call, StreamContext(const RpcMethod &method, grpc_call *call,
grpc_completion_queue* cq, google::protobuf::Message* request, grpc_completion_queue *cq, google::protobuf::Message *request,
google::protobuf::Message* result); google::protobuf::Message *result);
~StreamContext(); ~StreamContext();
// Start the stream, if there is a final write following immediately, set // Start the stream, if there is a final write following immediately, set
// buffered so that the messages can be sent in batch. // buffered so that the messages can be sent in batch.
void Start(bool buffered) override; void Start(bool buffered) override;
bool Read(google::protobuf::Message* msg) override; bool Read(google::protobuf::Message *msg) override;
bool Write(const google::protobuf::Message* msg, bool is_last) override; bool Write(const google::protobuf::Message *msg, bool is_last) override;
const Status& Wait() override; const Status &Wait() override;
void Cancel() override; void Cancel() override;
google::protobuf::Message* request() override { return request_; } google::protobuf::Message *request() override { return request_; }
google::protobuf::Message* response() override { return result_; } google::protobuf::Message *response() override { return result_; }
private: private:
// Unique tags for plucking events from the c layer. this pointer is casted // Unique tags for plucking events from the c layer. this pointer is casted
// to char* to create single byte step between tags. It implicitly relies on // to char* to create single byte step between tags. It implicitly relies on
// that StreamContext is large enough to contain all the pointers. // that StreamContext is large enough to contain all the pointers.
void* finished_tag() { return reinterpret_cast<char*>(this); } void *finished_tag() { return reinterpret_cast<char *>(this); }
void* read_tag() { return reinterpret_cast<char*>(this) + 1; } void *read_tag() { return reinterpret_cast<char *>(this) + 1; }
void* write_tag() { return reinterpret_cast<char*>(this) + 2; } void *write_tag() { return reinterpret_cast<char *>(this) + 2; }
void* halfclose_tag() { return reinterpret_cast<char*>(this) + 3; } void *halfclose_tag() { return reinterpret_cast<char *>(this) + 3; }
void* invoke_tag() { return reinterpret_cast<char*>(this) + 4; } void *invoke_tag() { return reinterpret_cast<char *>(this) + 4; }
void* client_metadata_read_tag() { return reinterpret_cast<char*>(this) + 5; } void *client_metadata_read_tag() {
grpc_call* call() { return call_; } return reinterpret_cast<char *>(this) + 5;
grpc_completion_queue* cq() { return cq_; } }
grpc_call *call() { return call_; }
grpc_completion_queue *cq() { return cq_; }
bool is_client_; bool is_client_;
const RpcMethod* method_; // not owned const RpcMethod *method_; // not owned
grpc_call* call_; // not owned grpc_call *call_; // not owned
grpc_completion_queue* cq_; // not owned grpc_completion_queue *cq_; // not owned
google::protobuf::Message* request_; // first request, not owned google::protobuf::Message *request_; // first request, not owned
google::protobuf::Message* result_; // last response, not owned google::protobuf::Message *result_; // last response, not owned
bool peer_halfclosed_; bool peer_halfclosed_;
bool self_halfclosed_; bool self_halfclosed_;

@ -35,7 +35,7 @@
namespace grpc { namespace grpc {
const Status& Status::OK = Status(); const Status &Status::OK = Status();
const Status& Status::Cancelled = Status(StatusCode::CANCELLED); const Status &Status::Cancelled = Status(StatusCode::CANCELLED);
} // namespace grpc } // namespace grpc

@ -43,8 +43,8 @@ using std::chrono::system_clock;
namespace grpc { namespace grpc {
// TODO(yangg) prevent potential overflow. // TODO(yangg) prevent potential overflow.
void Timepoint2Timespec(const system_clock::time_point& from, void Timepoint2Timespec(const system_clock::time_point &from,
gpr_timespec* to) { gpr_timespec *to) {
system_clock::duration deadline = from.time_since_epoch(); system_clock::duration deadline = from.time_since_epoch();
seconds secs = duration_cast<seconds>(deadline); seconds secs = duration_cast<seconds>(deadline);
nanoseconds nsecs = duration_cast<nanoseconds>(deadline - secs); nanoseconds nsecs = duration_cast<nanoseconds>(deadline - secs);

@ -41,8 +41,8 @@
namespace grpc { namespace grpc {
// from and to should be absolute time. // from and to should be absolute time.
void Timepoint2Timespec(const std::chrono::system_clock::time_point& from, void Timepoint2Timespec(const std::chrono::system_clock::time_point &from,
gpr_timespec* to); gpr_timespec *to);
std::chrono::system_clock::time_point Timespec2Timepoint(gpr_timespec t); std::chrono::system_clock::time_point Timespec2Timepoint(gpr_timespec t);

@ -16,3 +16,6 @@ install-sh
libtool libtool
missing missing
mkinstalldirs mkinstalldirs
ext/grpc/ltmain.sh

@ -1,5 +1,17 @@
#!/bin/sh
# Loads the local shared library, and runs all of the test cases in tests/ # Loads the local shared library, and runs all of the test cases in tests/
# against it # against it
set -e
cd $(dirname $0) cd $(dirname $0)
php -d extension_dir=../ext/grpc/modules/ -d extension=grpc.so \ default_extension_dir=`php -i | grep extension_dir | sed 's/.*=> //g'`
/usr/local/bin/phpunit -v --debug --strict ../tests/unit_tests
# sym-link in system supplied extensions
for f in $default_extension_dir/*.so
do
ln -s $f ../ext/grpc/modules/$(basename $f) &> /dev/null || true
done
php \
-d extension_dir=../ext/grpc/modules/ \
-d extension=grpc.so \
`which phpunit` -v --debug --strict ../tests/unit_tests

@ -423,16 +423,15 @@ PHP_METHOD(Call, start_read) {
static zend_function_entry call_methods[] = { static zend_function_entry call_methods[] = {
PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(Call, server_accept, NULL, ZEND_ACC_PUBLIC) PHP_ME(Call, server_accept, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Call, server_end_initial_metadata, NULL, ZEND_ACC_PUBLIC) PHP_ME(Call, server_end_initial_metadata, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Call, add_metadata, NULL, ZEND_ACC_PUBLIC) PHP_ME( PHP_ME(Call, add_metadata, NULL, ZEND_ACC_PUBLIC)
Call, cancel, NULL, ZEND_ACC_PUBLIC) PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Call, start_invoke, NULL, ZEND_ACC_PUBLIC) PHP_ME( PHP_ME(Call, start_invoke, NULL, ZEND_ACC_PUBLIC)
Call, start_read, NULL, ZEND_ACC_PUBLIC) PHP_ME(Call, start_read, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Call, start_write, NULL, ZEND_ACC_PUBLIC) PHP_ME( PHP_ME(Call, start_write, NULL, ZEND_ACC_PUBLIC)
Call, start_write_status, NULL, ZEND_ACC_PUBLIC) PHP_ME(Call, start_write_status, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Call, writes_done, NULL, ZEND_ACC_PUBLIC) PHP_ME(Call, writes_done, NULL, ZEND_ACC_PUBLIC) PHP_FE_END};
PHP_FE_END};
void grpc_init_call(TSRMLS_D) { void grpc_init_call(TSRMLS_D) {
zend_class_entry ce; zend_class_entry ce;

@ -155,7 +155,7 @@ PHP_METHOD(Channel, close) {
static zend_function_entry channel_methods[] = { static zend_function_entry channel_methods[] = {
PHP_ME(Channel, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) PHP_ME(Channel, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(Channel, close, NULL, ZEND_ACC_PUBLIC) PHP_FE_END}; PHP_ME(Channel, close, NULL, ZEND_ACC_PUBLIC) PHP_FE_END};
void grpc_init_channel(TSRMLS_D) { void grpc_init_channel(TSRMLS_D) {
zend_class_entry ce; zend_class_entry ce;

@ -63,8 +63,8 @@ zend_object_value create_wrapped_grpc_completion_queue(
*/ */
PHP_METHOD(CompletionQueue, __construct) { PHP_METHOD(CompletionQueue, __construct) {
wrapped_grpc_completion_queue *queue = wrapped_grpc_completion_queue *queue =
(wrapped_grpc_completion_queue *)zend_object_store_get_object( (wrapped_grpc_completion_queue *)zend_object_store_get_object(getThis()
getThis() TSRMLS_CC); TSRMLS_CC);
queue->wrapped = grpc_completion_queue_create(); queue->wrapped = grpc_completion_queue_create();
} }
@ -86,8 +86,8 @@ PHP_METHOD(CompletionQueue, next) {
return; return;
} }
wrapped_grpc_completion_queue *completion_queue = wrapped_grpc_completion_queue *completion_queue =
(wrapped_grpc_completion_queue *)zend_object_store_get_object( (wrapped_grpc_completion_queue *)zend_object_store_get_object(getThis()
getThis() TSRMLS_CC); TSRMLS_CC);
wrapped_grpc_timeval *wrapped_timeout = wrapped_grpc_timeval *wrapped_timeout =
(wrapped_grpc_timeval *)zend_object_store_get_object(timeout TSRMLS_CC); (wrapped_grpc_timeval *)zend_object_store_get_object(timeout TSRMLS_CC);
grpc_event *event = grpc_completion_queue_next(completion_queue->wrapped, grpc_event *event = grpc_completion_queue_next(completion_queue->wrapped,
@ -109,8 +109,8 @@ PHP_METHOD(CompletionQueue, pluck) {
"pluck needs a long and a Timeval", 1 TSRMLS_CC); "pluck needs a long and a Timeval", 1 TSRMLS_CC);
} }
wrapped_grpc_completion_queue *completion_queue = wrapped_grpc_completion_queue *completion_queue =
(wrapped_grpc_completion_queue *)zend_object_store_get_object( (wrapped_grpc_completion_queue *)zend_object_store_get_object(getThis()
getThis() TSRMLS_CC); TSRMLS_CC);
wrapped_grpc_timeval *wrapped_timeout = wrapped_grpc_timeval *wrapped_timeout =
(wrapped_grpc_timeval *)zend_object_store_get_object(timeout TSRMLS_CC); (wrapped_grpc_timeval *)zend_object_store_get_object(timeout TSRMLS_CC);
grpc_event *event = grpc_completion_queue_pluck( grpc_event *event = grpc_completion_queue_pluck(
@ -124,8 +124,8 @@ PHP_METHOD(CompletionQueue, pluck) {
static zend_function_entry completion_queue_methods[] = { static zend_function_entry completion_queue_methods[] = {
PHP_ME(CompletionQueue, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) PHP_ME(CompletionQueue, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(CompletionQueue, next, NULL, ZEND_ACC_PUBLIC) PHP_ME(CompletionQueue, next, NULL, ZEND_ACC_PUBLIC)
PHP_ME(CompletionQueue, pluck, NULL, ZEND_ACC_PUBLIC) PHP_FE_END}; PHP_ME(CompletionQueue, pluck, NULL, ZEND_ACC_PUBLIC) PHP_FE_END};
void grpc_init_completion_queue(TSRMLS_D) { void grpc_init_completion_queue(TSRMLS_D) {
zend_class_entry ce; zend_class_entry ce;

@ -38,7 +38,9 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_LIBRARY(rt,,GRPC_SHARED_LIBADD) PHP_ADD_LIBRARY(rt,,GRPC_SHARED_LIBADD)
PHP_ADD_LIBRARY(rt) PHP_ADD_LIBRARY(rt)
PHP_ADD_LIBPATH($GRPC_DIR/lib) GRPC_LIBDIR=$GRPC_DIR/${GRPC_LIB_SUBDIR-lib}
PHP_ADD_LIBPATH($GRPC_LIBDIR)
PHP_CHECK_LIBRARY(gpr,gpr_now, PHP_CHECK_LIBRARY(gpr,gpr_now,
[ [
@ -48,18 +50,9 @@ if test "$PHP_GRPC" != "no"; then
],[ ],[
AC_MSG_ERROR([wrong gpr lib version or lib not found]) AC_MSG_ERROR([wrong gpr lib version or lib not found])
],[ ],[
-L$GRPC_DIR/lib -L$GRPC_LIBDIR
]) ])
PHP_ADD_LIBRARY(event,,GRPC_SHARED_LIBADD)
PHP_ADD_LIBRARY(event)
PHP_ADD_LIBRARY(event_pthreads,,GRPC_SHARED_LIBADD)
PHP_ADD_LIBRARY(event_pthreads)
PHP_ADD_LIBRARY(event_core,,GRPC_SHARED_LIBADD)
PHP_ADD_LIBRARY(event_core)
PHP_CHECK_LIBRARY(grpc,grpc_channel_destroy, PHP_CHECK_LIBRARY(grpc,grpc_channel_destroy,
[ [
PHP_ADD_LIBRARY(grpc,,GRPC_SHARED_LIBADD) PHP_ADD_LIBRARY(grpc,,GRPC_SHARED_LIBADD)
@ -68,7 +61,7 @@ if test "$PHP_GRPC" != "no"; then
],[ ],[
AC_MSG_ERROR([wrong grpc lib version or lib not found]) AC_MSG_ERROR([wrong grpc lib version or lib not found])
],[ ],[
-L$GRPC_DIR/lib -L$GRPC_LIBDIR
]) ])
PHP_SUBST(GRPC_SHARED_LIBADD) PHP_SUBST(GRPC_SHARED_LIBADD)

@ -151,13 +151,12 @@ PHP_METHOD(Credentials, createFake) {
static zend_function_entry credentials_methods[] = { static zend_function_entry credentials_methods[] = {
PHP_ME(Credentials, createDefault, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(Credentials, createDefault, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Credentials, createSsl, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(Credentials, createSsl, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Credentials, createComposite, NULL, PHP_ME(Credentials, createComposite, NULL,
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Credentials, createGce, NULL, PHP_ME(Credentials, createGce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(Credentials, createFake, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Credentials, createFake, NULL, PHP_FE_END};
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END};
void grpc_init_credentials(TSRMLS_D) { void grpc_init_credentials(TSRMLS_D) {
zend_class_entry ce; zend_class_entry ce;

@ -33,7 +33,8 @@ zend_module_entry grpc_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901 #if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER, STANDARD_MODULE_HEADER,
#endif #endif
"grpc", grpc_functions, PHP_MINIT(grpc), PHP_MSHUTDOWN(grpc), NULL, NULL, "grpc", grpc_functions, PHP_MINIT(grpc),
PHP_MSHUTDOWN(grpc), NULL, NULL,
PHP_MINFO(grpc), PHP_MINFO(grpc),
#if ZEND_MODULE_API_NO >= 20010901 #if ZEND_MODULE_API_NO >= 20010901
PHP_GRPC_VERSION, PHP_GRPC_VERSION,

@ -176,10 +176,10 @@ PHP_METHOD(Server, start) {
static zend_function_entry server_methods[] = { static zend_function_entry server_methods[] = {
PHP_ME(Server, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) PHP_ME(Server, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(Server, request_call, NULL, ZEND_ACC_PUBLIC) PHP_ME(Server, request_call, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Server, add_http2_port, NULL, ZEND_ACC_PUBLIC) PHP_ME(Server, add_http2_port, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Server, add_secure_http2_port, NULL, ZEND_ACC_PUBLIC) PHP_ME(Server, add_secure_http2_port, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Server, start, NULL, ZEND_ACC_PUBLIC) PHP_FE_END}; PHP_ME(Server, start, NULL, ZEND_ACC_PUBLIC) PHP_FE_END};
void grpc_init_server(TSRMLS_D) { void grpc_init_server(TSRMLS_D) {
zend_class_entry ce; zend_class_entry ce;

@ -102,8 +102,8 @@ PHP_METHOD(ServerCredentials, createFake) {
static zend_function_entry server_credentials_methods[] = { static zend_function_entry server_credentials_methods[] = {
PHP_ME(ServerCredentials, createSsl, NULL, PHP_ME(ServerCredentials, createSsl, NULL,
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(ServerCredentials, createFake, NULL, PHP_ME(ServerCredentials, createFake, NULL,
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END}; ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END};
void grpc_init_server_credentials(TSRMLS_D) { void grpc_init_server_credentials(TSRMLS_D) {
zend_class_entry ce; zend_class_entry ce;

@ -217,20 +217,16 @@ PHP_METHOD(Timeval, sleep_until) {
} }
static zend_function_entry timeval_methods[] = { static zend_function_entry timeval_methods[] = {
PHP_ME(Timeval, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) PHP_ME( PHP_ME(Timeval, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
Timeval, add, NULL, PHP_ME(Timeval, add, NULL, ZEND_ACC_PUBLIC)
ZEND_ACC_PUBLIC) PHP_ME(Timeval, compare, NULL, PHP_ME(Timeval, compare, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(Timeval, inf_future, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Timeval, inf_future, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(Timeval, inf_past, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Timeval, inf_past, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(Timeval, now, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Timeval, now, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(Timeval, similar, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Timeval, similar, NULL, PHP_ME(Timeval, sleep_until, NULL, ZEND_ACC_PUBLIC)
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(Timeval, subtract, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Timeval, sleep_until, NULL, ZEND_ACC_PUBLIC) PHP_ME(Timeval, zero, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END};
PHP_ME(Timeval, subtract, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Timeval, zero, NULL,
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_FE_END};
void grpc_init_timeval(TSRMLS_D) { void grpc_init_timeval(TSRMLS_D) {
zend_class_entry ce; zend_class_entry ce;

@ -0,0 +1,10 @@
# This is the configuration used to check the rubocop source code.
inherit_from: .rubocop_todo.yml
AllCops:
Exclude:
- 'bin/apis/**/*'
- 'bin/interop/test/**/*'
- 'bin/math.rb'
- 'bin/math_services.rb'

@ -0,0 +1,52 @@
# This configuration was generated by `rubocop --auto-gen-config`
# on 2015-01-16 02:30:04 -0800 using RuboCop version 0.28.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 3
# Lint/UselessAssignment:
# Enabled: false
# Offense count: 33
Metrics/AbcSize:
Max: 39
# Offense count: 3
# Configuration parameters: CountComments.
Metrics/ClassLength:
Max: 231
# Offense count: 2
Metrics/CyclomaticComplexity:
Max: 8
# Offense count: 36
# Configuration parameters: CountComments.
Metrics/MethodLength:
Max: 37
# Offense count: 8
# Configuration parameters: CountKeywordArgs.
Metrics/ParameterLists:
Max: 8
# Offense count: 2
Metrics/PerceivedComplexity:
Max: 10
# Offense count: 7
# Configuration parameters: AllowedVariables.
Style/GlobalVars:
Enabled: false
# Offense count: 1
# Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
Style/Next:
Enabled: false
# Offense count: 2
# Configuration parameters: Methods.
Style/SingleLineBlockParams:
Enabled: false

@ -1,46 +1,44 @@
# -*- ruby -*- # -*- ruby -*-
require 'rake/extensiontask' require 'rake/extensiontask'
require 'rspec/core/rake_task' require 'rspec/core/rake_task'
require 'rubocop/rake_task'
desc 'Run Rubocop to check for style violations'
RuboCop::RakeTask.new
Rake::ExtensionTask.new 'grpc' do |ext| Rake::ExtensionTask.new 'grpc' do |ext|
ext.lib_dir = File.join('lib', 'grpc') ext.lib_dir = File.join('lib', 'grpc')
end end
SPEC_SUITES = [ SPEC_SUITES = [
{ :id => :wrapper, :title => 'wrapper layer', :files => %w(spec/*.rb) }, { id: :wrapper, title: 'wrapper layer', files: %w(spec/*.rb) },
{ :id => :idiomatic, :title => 'idiomatic layer', :dir => %w(spec/generic), { id: :idiomatic, title: 'idiomatic layer', dir: %w(spec/generic),
:tag => '~bidi' }, tag: '~bidi' },
{ :id => :bidi, :title => 'bidi tests', :dir => %w(spec/generic), { id: :bidi, title: 'bidi tests', dir: %w(spec/generic),
:tag => 'bidi' } tag: 'bidi' }
] ]
desc "Run all RSpec tests" desc 'Run all RSpec tests'
namespace :spec do namespace :spec do
namespace :suite do namespace :suite do
SPEC_SUITES.each do |suite| SPEC_SUITES.each do |suite|
desc "Run all specs in #{suite[:title]} spec suite" desc "Run all specs in #{suite[:title]} spec suite"
RSpec::Core::RakeTask.new(suite[:id]) do |t| RSpec::Core::RakeTask.new(suite[:id]) do |t|
spec_files = [] spec_files = []
if suite[:files] suite[:files].each { |f| spec_files += Dir[f] } if suite[:files]
suite[:files].each { |f| spec_files += Dir[f] }
end
if suite[:dirs] if suite[:dirs]
suite[:dirs].each { |f| spec_files += Dir["#{f}/**/*_spec.rb"] } suite[:dirs].each { |f| spec_files += Dir["#{f}/**/*_spec.rb"] }
end end
t.pattern = spec_files t.pattern = spec_files
t.rspec_opts = "--tag #{suite[:tag]}" if suite[:tag]
if suite[:tag]
t.rspec_opts = "--tag #{suite[:tag]}"
end
end end
end end
end end
end end
task :default => "spec:suite:idiomatic" # this should be spec:suite:bidi task default: 'spec:suite:idiomatic' # this should be spec:suite:bidi
task "spec:suite:wrapper" => :compile task 'spec:suite:wrapper' => :compile
task "spec:suite:idiomatic" => "spec:suite:wrapper" task 'spec:suite:idiomatic' => 'spec:suite:wrapper'
task "spec:suite:bidi" => "spec:suite:idiomatic" task 'spec:suite:bidi' => 'spec:suite:idiomatic'

@ -65,7 +65,7 @@ end
# creates a Credentials from the test certificates. # creates a Credentials from the test certificates.
def test_creds def test_creds
certs = load_test_certs certs = load_test_certs
creds = GRPC::Core::Credentials.new(certs[0]) GRPC::Core::Credentials.new(certs[0])
end end
# creates a test stub that accesses host:port securely. # creates a test stub that accesses host:port securely.
@ -73,15 +73,15 @@ def create_stub(host, port)
address = "#{host}:#{port}" address = "#{host}:#{port}"
stub_opts = { stub_opts = {
:creds => test_creds, :creds => test_creds,
GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.com', GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.com'
} }
logger.info("... connecting securely to #{address}") logger.info("... connecting securely to #{address}")
stub = Grpc::Testing::TestService::Stub.new(address, **stub_opts) Grpc::Testing::TestService::Stub.new(address, **stub_opts)
end end
# produces a string of null chars (\0) of length l. # produces a string of null chars (\0) of length l.
def nulls(l) def nulls(l)
raise 'requires #{l} to be +ve' if l < 0 fail 'requires #{l} to be +ve' if l < 0
[].pack('x' * l).force_encoding('utf-8') [].pack('x' * l).force_encoding('utf-8')
end end
@ -102,13 +102,13 @@ class PingPongPlayer
def each_item def each_item
return enum_for(:each_item) unless block_given? return enum_for(:each_item) unless block_given?
req_cls, p_cls= StreamingOutputCallRequest, ResponseParameters # short req_cls, p_cls = StreamingOutputCallRequest, ResponseParameters # short
count = 0 count = 0
@msg_sizes.each do |m| @msg_sizes.each do |m|
req_size, resp_size = m req_size, resp_size = m
req = req_cls.new(:payload => Payload.new(:body => nulls(req_size)), req = req_cls.new(payload: Payload.new(body: nulls(req_size)),
:response_type => COMPRESSABLE, response_type: COMPRESSABLE,
:response_parameters => [p_cls.new(:size => resp_size)]) response_parameters: [p_cls.new(size: resp_size)])
yield req yield req
resp = @queue.pop resp = @queue.pop
assert_equal(PayloadType.lookup(COMPRESSABLE), resp.payload.type, assert_equal(PayloadType.lookup(COMPRESSABLE), resp.payload.type,
@ -148,11 +148,11 @@ class NamedTests
# ruby server # ruby server
# FAILED # FAILED
def large_unary def large_unary
req_size, wanted_response_size = 271828, 314159 req_size, wanted_response_size = 271_828, 314_159
payload = Payload.new(:type => COMPRESSABLE, :body => nulls(req_size)) payload = Payload.new(type: COMPRESSABLE, body: nulls(req_size))
req = SimpleRequest.new(:response_type => COMPRESSABLE, req = SimpleRequest.new(response_type: COMPRESSABLE,
:response_size => wanted_response_size, response_size: wanted_response_size,
:payload => payload) payload: payload)
resp = @stub.unary_call(req) resp = @stub.unary_call(req)
assert_equal(wanted_response_size, resp.payload.body.length, assert_equal(wanted_response_size, resp.payload.body.length,
'large_unary: payload had the wrong length') 'large_unary: payload had the wrong length')
@ -166,27 +166,27 @@ class NamedTests
# ruby server # ruby server
# FAILED # FAILED
def client_streaming def client_streaming
msg_sizes = [27182, 8, 1828, 45904] msg_sizes = [27_182, 8, 1828, 45_904]
wanted_aggregate_size = 74922 wanted_aggregate_size = 74_922
reqs = msg_sizes.map do |x| reqs = msg_sizes.map do |x|
req = Payload.new(:body => nulls(x)) req = Payload.new(body: nulls(x))
StreamingInputCallRequest.new(:payload => req) StreamingInputCallRequest.new(payload: req)
end end
resp = @stub.streaming_input_call(reqs) resp = @stub.streaming_input_call(reqs)
assert_equal(wanted_aggregate_size, resp.aggregated_payload_size, assert_equal(wanted_aggregate_size, resp.aggregated_payload_size,
'client_streaming: aggregate payload size is incorrect') 'client_streaming: aggregate payload size is incorrect')
p 'OK: client_streaming' p 'OK: client_streaming'
end end
# TESTING: # TESTING:
# PASSED # PASSED
# ruby server # ruby server
# FAILED # FAILED
def server_streaming def server_streaming
msg_sizes = [31415, 9, 2653, 58979] msg_sizes = [31_415, 9, 2653, 58_979]
response_spec = msg_sizes.map { |s| ResponseParameters.new(:size => s) } response_spec = msg_sizes.map { |s| ResponseParameters.new(size: s) }
req = StreamingOutputCallRequest.new(:response_type => COMPRESSABLE, req = StreamingOutputCallRequest.new(response_type: COMPRESSABLE,
:response_parameters => response_spec) response_parameters: response_spec)
resps = @stub.streaming_output_call(req) resps = @stub.streaming_output_call(req)
resps.each_with_index do |r, i| resps.each_with_index do |r, i|
assert i < msg_sizes.length, 'too many responses' assert i < msg_sizes.length, 'too many responses'
@ -203,13 +203,12 @@ class NamedTests
# ruby server # ruby server
# FAILED # FAILED
def ping_pong def ping_pong
msg_sizes = [[27182, 31415], [8, 9], [1828, 2653], [45904, 58979]] msg_sizes = [[27_182, 31_415], [8, 9], [1828, 2653], [45_904, 58_979]]
ppp = PingPongPlayer.new(msg_sizes) ppp = PingPongPlayer.new(msg_sizes)
resps = @stub.full_duplex_call(ppp.each_item) resps = @stub.full_duplex_call(ppp.each_item)
resps.each { |r| ppp.queue.push(r) } resps.each { |r| ppp.queue.push(r) }
p 'OK: ping_pong' p 'OK: ping_pong'
end end
end end
# validates the the command line options, returning them as a Hash. # validates the the command line options, returning them as a Hash.
@ -217,7 +216,7 @@ def parse_options
options = { options = {
'server_host' => nil, 'server_host' => nil,
'server_port' => nil, 'server_port' => nil,
'test_case' => nil, 'test_case' => nil
} }
OptionParser.new do |opts| OptionParser.new do |opts|
opts.banner = 'Usage: --server_host <server_host> --server_port server_port' opts.banner = 'Usage: --server_host <server_host> --server_port server_port'
@ -228,17 +227,17 @@ def parse_options
options['server_port'] = v options['server_port'] = v
end end
# instance_methods(false) gives only the methods defined in that class # instance_methods(false) gives only the methods defined in that class
test_cases = NamedTests.instance_methods(false).map { |t| t.to_s } test_cases = NamedTests.instance_methods(false).map(&:to_s)
test_case_list = test_cases.join(',') test_case_list = test_cases.join(',')
opts.on("--test_case CODE", test_cases, {}, "select a test_case", opts.on('--test_case CODE', test_cases, {}, 'select a test_case',
" (#{test_case_list})") do |v| " (#{test_case_list})") do |v|
options['test_case'] = v options['test_case'] = v
end end
end.parse! end.parse!
['server_host', 'server_port', 'test_case'].each do |arg| %w(server_host, server_port, test_case).each do |arg|
if options[arg].nil? if options[arg].nil?
raise OptionParser::MissingArgument.new("please specify --#{arg}") fail(OptionParser::MissingArgument, "please specify --#{arg}")
end end
end end
options options

@ -62,12 +62,12 @@ end
# creates a ServerCredentials from the test certificates. # creates a ServerCredentials from the test certificates.
def test_server_creds def test_server_creds
certs = load_test_certs certs = load_test_certs
server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2]) GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2])
end end
# produces a string of null chars (\0) of length l. # produces a string of null chars (\0) of length l.
def nulls(l) def nulls(l)
raise 'requires #{l} to be +ve' if l < 0 fail 'requires #{l} to be +ve' if l < 0
[].pack('x' * l).force_encoding('utf-8') [].pack('x' * l).force_encoding('utf-8')
end end
@ -86,7 +86,7 @@ class EnumeratorQueue
loop do loop do
r = @q.pop r = @q.pop
break if r.equal?(@sentinel) break if r.equal?(@sentinel)
raise r if r.is_a?Exception fail r if r.is_a? Exception
yield r yield r
end end
end end
@ -98,27 +98,27 @@ class TestTarget < Grpc::Testing::TestService::Service
include Grpc::Testing include Grpc::Testing
include Grpc::Testing::PayloadType include Grpc::Testing::PayloadType
def empty_call(empty, call) def empty_call(_empty, _call)
Empty.new Empty.new
end end
def unary_call(simple_req, call) def unary_call(simple_req, _call)
req_size = simple_req.response_size req_size = simple_req.response_size
SimpleResponse.new(:payload => Payload.new(:type => COMPRESSABLE, SimpleResponse.new(payload: Payload.new(type: COMPRESSABLE,
:body => nulls(req_size))) body: nulls(req_size)))
end end
def streaming_input_call(call) def streaming_input_call(call)
sizes = call.each_remote_read.map { |x| x.payload.body.length } sizes = call.each_remote_read.map { |x| x.payload.body.length }
sum = sizes.inject { |sum,x| sum + x } sum = sizes.inject { |s, x| s + x }
StreamingInputCallResponse.new(:aggregated_payload_size => sum) StreamingInputCallResponse.new(aggregated_payload_size: sum)
end end
def streaming_output_call(req, call) def streaming_output_call(req, _call)
cls = StreamingOutputCallResponse cls = StreamingOutputCallResponse
req.response_parameters.map do |p| req.response_parameters.map do |p|
cls.new(:payload => Payload.new(:type => req.response_type, cls.new(payload: Payload.new(type: req.response_type,
:body => nulls(p.size))) body: nulls(p.size)))
end end
end end
@ -126,13 +126,13 @@ class TestTarget < Grpc::Testing::TestService::Service
# reqs is a lazy Enumerator of the requests sent by the client. # reqs is a lazy Enumerator of the requests sent by the client.
q = EnumeratorQueue.new(self) q = EnumeratorQueue.new(self)
cls = StreamingOutputCallResponse cls = StreamingOutputCallResponse
t = Thread.new do Thread.new do
begin begin
reqs.each do |req| reqs.each do |req|
logger.info("read #{req.inspect}") logger.info("read #{req.inspect}")
resp_size = req.response_parameters[0].size resp_size = req.response_parameters[0].size
resp = cls.new(:payload => Payload.new(:type => req.response_type, resp = cls.new(payload: Payload.new(type: req.response_type,
:body => nulls(resp_size))) body: nulls(resp_size)))
q.push(resp) q.push(resp)
end end
logger.info('finished reads') logger.info('finished reads')
@ -149,13 +149,12 @@ class TestTarget < Grpc::Testing::TestService::Service
# currently used in any tests # currently used in any tests
full_duplex_call(reqs) full_duplex_call(reqs)
end end
end end
# validates the the command line options, returning them as a Hash. # validates the the command line options, returning them as a Hash.
def parse_options def parse_options
options = { options = {
'port' => nil, 'port' => nil
} }
OptionParser.new do |opts| OptionParser.new do |opts|
opts.banner = 'Usage: --port port' opts.banner = 'Usage: --port port'
@ -165,7 +164,7 @@ def parse_options
end.parse! end.parse!
if options['port'].nil? if options['port'].nil?
raise OptionParser::MissingArgument.new("please specify --port") fail(OptionParser::MissingArgument, 'please specify --port')
end end
options options
end end

@ -29,7 +29,6 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Sample app that accesses a Calc service running on a Ruby gRPC server and # Sample app that accesses a Calc service running on a Ruby gRPC server and
# helps validate RpcServer as a gRPC server using proto2 serialization. # helps validate RpcServer as a gRPC server using proto2 serialization.
# #
@ -49,9 +48,9 @@ include GRPC::Core::TimeConsts
def do_div(stub) def do_div(stub)
logger.info('request_response') logger.info('request_response')
logger.info('----------------') logger.info('----------------')
req = Math::DivArgs.new(:dividend => 7, :divisor => 3) req = Math::DivArgs.new(dividend: 7, divisor: 3)
logger.info("div(7/3): req=#{req.inspect}") logger.info("div(7/3): req=#{req.inspect}")
resp = stub.div(req, deadline=INFINITE_FUTURE) resp = stub.div(req, INFINITE_FUTURE)
logger.info("Answer: #{resp.inspect}") logger.info("Answer: #{resp.inspect}")
logger.info('----------------') logger.info('----------------')
end end
@ -60,7 +59,7 @@ def do_sum(stub)
# to make client streaming requests, pass an enumerable of the inputs # to make client streaming requests, pass an enumerable of the inputs
logger.info('client_streamer') logger.info('client_streamer')
logger.info('---------------') logger.info('---------------')
reqs = [1, 2, 3, 4, 5].map { |x| Math::Num.new(:num => x) } reqs = [1, 2, 3, 4, 5].map { |x| Math::Num.new(num: x) }
logger.info("sum(1, 2, 3, 4, 5): reqs=#{reqs.inspect}") logger.info("sum(1, 2, 3, 4, 5): reqs=#{reqs.inspect}")
resp = stub.sum(reqs) # reqs.is_a?(Enumerable) resp = stub.sum(reqs) # reqs.is_a?(Enumerable)
logger.info("Answer: #{resp.inspect}") logger.info("Answer: #{resp.inspect}")
@ -70,9 +69,9 @@ end
def do_fib(stub) def do_fib(stub)
logger.info('server_streamer') logger.info('server_streamer')
logger.info('----------------') logger.info('----------------')
req = Math::FibArgs.new(:limit => 11) req = Math::FibArgs.new(limit: 11)
logger.info("fib(11): req=#{req.inspect}") logger.info("fib(11): req=#{req.inspect}")
resp = stub.fib(req, deadline=INFINITE_FUTURE) resp = stub.fib(req, INFINITE_FUTURE)
resp.each do |r| resp.each do |r|
logger.info("Answer: #{r.inspect}") logger.info("Answer: #{r.inspect}")
end end
@ -83,11 +82,11 @@ def do_div_many(stub)
logger.info('bidi_streamer') logger.info('bidi_streamer')
logger.info('-------------') logger.info('-------------')
reqs = [] reqs = []
reqs << Math::DivArgs.new(:dividend => 7, :divisor => 3) reqs << Math::DivArgs.new(dividend: 7, divisor: 3)
reqs << Math::DivArgs.new(:dividend => 5, :divisor => 2) reqs << Math::Di5AvArgs.new(dividend: 5, divisor: 2)
reqs << Math::DivArgs.new(:dividend => 7, :divisor => 2) reqs << Math::DivArgs.new(dividend: 7, divisor: 2)
logger.info("div(7/3), div(5/2), div(7/2): reqs=#{reqs.inspect}") logger.info("div(7/3), div(5/2), div(7/2): reqs=#{reqs.inspect}")
resp = stub.div_many(reqs, deadline=10) resp = stub.div_many(reqs, 10)
resp.each do |r| resp.each do |r|
logger.info("Answer: #{r.inspect}") logger.info("Answer: #{r.inspect}")
end end
@ -103,7 +102,7 @@ end
def test_creds def test_creds
certs = load_test_certs certs = load_test_certs
creds = GRPC::Core::Credentials.new(certs[0]) GRPC::Core::Credentials.new(certs[0])
end end
def main def main
@ -117,7 +116,7 @@ def main
options['host'] = v options['host'] = v
end end
opts.on('-s', '--secure', 'access using test creds') do |v| opts.on('-s', '--secure', 'access using test creds') do |v|
options['secure'] = true options['secure'] = v
end end
end.parse! end.parse!
@ -128,7 +127,7 @@ def main
if options['secure'] if options['secure']
stub_opts = { stub_opts = {
:creds => test_creds, :creds => test_creds,
GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.com', GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.com'
} }
p stub_opts p stub_opts
p options['host'] p options['host']

@ -46,9 +46,8 @@ require 'optparse'
# Holds state for a fibonacci series # Holds state for a fibonacci series
class Fibber class Fibber
def initialize(limit) def initialize(limit)
raise "bad limit: got #{limit}, want limit > 0" if limit < 1 fail "bad limit: got #{limit}, want limit > 0" if limit < 1
@limit = limit @limit = limit
end end
@ -57,14 +56,14 @@ class Fibber
idx, current, previous = 0, 1, 1 idx, current, previous = 0, 1, 1
until idx == @limit until idx == @limit
if idx == 0 || idx == 1 if idx == 0 || idx == 1
yield Math::Num.new(:num => 1) yield Math::Num.new(num: 1)
idx += 1 idx += 1
next next
end end
tmp = current tmp = current
current = previous + current current = previous + current
previous = tmp previous = tmp
yield Math::Num.new(:num => current) yield Math::Num.new(num: current)
idx += 1 idx += 1
end end
end end
@ -85,43 +84,41 @@ class EnumeratorQueue
loop do loop do
r = @q.pop r = @q.pop
break if r.equal?(@sentinel) break if r.equal?(@sentinel)
raise r if r.is_a?Exception fail r if r.is_a? Exception
yield r yield r
end end
end end
end end
# The Math::Math:: module occurs because the service has the same name as its # The Math::Math:: module occurs because the service has the same name as its
# package. That practice should be avoided by defining real services. # package. That practice should be avoided by defining real services.
class Calculator < Math::Math::Service class Calculator < Math::Math::Service
def div(div_args, _call)
def div(div_args, call)
if div_args.divisor == 0 if div_args.divisor == 0
# To send non-OK status handlers raise a StatusError with the code and # To send non-OK status handlers raise a StatusError with the code and
# and detail they want sent as a Status. # and detail they want sent as a Status.
raise GRPC::StatusError.new(GRPC::Status::INVALID_ARGUMENT, fail GRPC::StatusError.new(GRPC::Status::INVALID_ARGUMENT,
'divisor cannot be 0') 'divisor cannot be 0')
end end
Math::DivReply.new(:quotient => div_args.dividend/div_args.divisor, Math::DivReply.new(quotient: div_args.dividend / div_args.divisor,
:remainder => div_args.dividend % div_args.divisor) remainder: div_args.dividend % div_args.divisor)
end end
def sum(call) def sum(call)
# the requests are accesible as the Enumerator call#each_request # the requests are accesible as the Enumerator call#each_request
nums = call.each_remote_read.collect { |x| x.num } nums = call.each_remote_read.collect(&:num)
sum = nums.inject { |sum,x| sum + x } sum = nums.inject { |s, x| s + x }
Math::Num.new(:num => sum) Math::Num.new(num: sum)
end end
def fib(fib_args, call) def fib(fib_args, _call)
if fib_args.limit < 1 if fib_args.limit < 1
raise StatusError.new(Status::INVALID_ARGUMENT, 'limit must be >= 0') fail StatusError.new(Status::INVALID_ARGUMENT, 'limit must be >= 0')
end end
# return an Enumerator of Nums # return an Enumerator of Nums
Fibber.new(fib_args.limit).generator() Fibber.new(fib_args.limit).generator
# just return the generator, GRPC::GenericServer sends each actual response # just return the generator, GRPC::GenericServer sends each actual response
end end
@ -132,10 +129,10 @@ class Calculator < Math::Math::Service
begin begin
requests.each do |req| requests.each do |req|
logger.info("read #{req.inspect}") logger.info("read #{req.inspect}")
resp = Math::DivReply.new(:quotient => req.dividend/req.divisor, resp = Math::DivReply.new(quotient: req.dividend / req.divisor,
:remainder => req.dividend % req.divisor) remainder: req.dividend % req.divisor)
q.push(resp) q.push(resp)
Thread::pass # let the internal Bidi threads run Thread.pass # let the internal Bidi threads run
end end
logger.info('finished reads') logger.info('finished reads')
q.push(self) q.push(self)
@ -147,7 +144,6 @@ class Calculator < Math::Math::Service
t.priority = -2 # hint that the div_many thread should not be favoured t.priority = -2 # hint that the div_many thread should not be favoured
q.each_item q.each_item
end end
end end
def load_test_certs def load_test_certs
@ -159,7 +155,7 @@ end
def test_server_creds def test_server_creds
certs = load_test_certs certs = load_test_certs
server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2]) GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2])
end end
def main def main
@ -173,7 +169,7 @@ def main
options['host'] = v options['host'] = v
end end
opts.on('-s', '--secure', 'access using test creds') do |v| opts.on('-s', '--secure', 'access using test creds') do |v|
options['secure'] = true options['secure'] = v
end end
end.parse! end.parse!

@ -40,16 +40,18 @@ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
require 'grpc' require 'grpc'
require 'optparse' require 'optparse'
# a simple non-protobuf message class.
class NoProtoMsg class NoProtoMsg
def self.marshal(o) def self.marshal(_o)
'' ''
end end
def self.unmarshal(o) def self.unmarshal(_o)
NoProtoMsg.new NoProtoMsg.new
end end
end end
# service the uses the non-protobuf message class.
class NoProtoService class NoProtoService
include GRPC::GenericService include GRPC::GenericService
rpc :AnRPC, NoProtoMsg, NoProtoMsg rpc :AnRPC, NoProtoMsg, NoProtoMsg
@ -66,7 +68,7 @@ end
def test_creds def test_creds
certs = load_test_certs certs = load_test_certs
creds = GRPC::Core::Credentials.new(certs[0]) GRPC::Core::Credentials.new(certs[0])
end end
def main def main
@ -80,14 +82,14 @@ def main
options['host'] = v options['host'] = v
end end
opts.on('-s', '--secure', 'access using test creds') do |v| opts.on('-s', '--secure', 'access using test creds') do |v|
options['secure'] = true options['secure'] = v
end end
end.parse! end.parse!
if options['secure'] if options['secure']
stub_opts = { stub_opts = {
:creds => test_creds, :creds => test_creds,
GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.com', GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.com'
} }
p stub_opts p stub_opts
p options['host'] p options['host']

@ -40,26 +40,29 @@ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
require 'grpc' require 'grpc'
require 'optparse' require 'optparse'
# a simple non-protobuf message class.
class NoProtoMsg class NoProtoMsg
def self.marshal(o) def self.marshal(_o)
'' ''
end end
def self.unmarshal(o) def self.unmarshal(_o)
NoProtoMsg.new NoProtoMsg.new
end end
end end
# service the uses the non-protobuf message class.
class NoProtoService class NoProtoService
include GRPC::GenericService include GRPC::GenericService
rpc :AnRPC, NoProtoMsg, NoProtoMsg rpc :AnRPC, NoProtoMsg, NoProtoMsg
end end
# an implementation of the non-protobuf service.
class NoProto < NoProtoService class NoProto < NoProtoService
def initialize(default_var='ignored') def initialize(_default_var = 'ignored')
end end
def an_rpc(req, call) def an_rpc(req, _call)
logger.info('echo service received a request') logger.info('echo service received a request')
req req
end end
@ -74,7 +77,7 @@ end
def test_server_creds def test_server_creds
certs = load_test_certs certs = load_test_certs
server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2]) GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2])
end end
def main def main
@ -88,7 +91,7 @@ def main
options['host'] = v options['host'] = v
end end
opts.on('-s', '--secure', 'access using test creds') do |v| opts.on('-s', '--secure', 'access using test creds') do |v|
options['secure'] = true options['secure'] = v
end end
end.parse! end.parse!
@ -106,5 +109,4 @@ def main
s.run s.run
end end
main main

@ -33,29 +33,29 @@ LIBDIR = RbConfig::CONFIG['libdir']
INCLUDEDIR = RbConfig::CONFIG['includedir'] INCLUDEDIR = RbConfig::CONFIG['includedir']
HEADER_DIRS = [ HEADER_DIRS = [
# Search /opt/local (Mac source install) # Search /opt/local (Mac source install)
'/opt/local/include', '/opt/local/include',
# Search /usr/local (Source install) # Search /usr/local (Source install)
'/usr/local/include', '/usr/local/include',
# Check the ruby install locations # Check the ruby install locations
INCLUDEDIR, INCLUDEDIR
] ]
LIB_DIRS = [ LIB_DIRS = [
# Search /opt/local (Mac source install) # Search /opt/local (Mac source install)
'/opt/local/lib', '/opt/local/lib',
# Search /usr/local (Source install) # Search /usr/local (Source install)
'/usr/local/lib', '/usr/local/lib',
# Check the ruby install locations # Check the ruby install locations
LIBDIR, LIBDIR
] ]
def crash(msg) def crash(msg)
print(" extconf failure: %s\n" % msg) print(" extconf failure: #{msg}\n")
exit 1 exit 1
end end

@ -1,31 +1,34 @@
# encoding: utf-8 # encoding: utf-8
$:.push File.expand_path("../lib", __FILE__) $LOAD_PATH.push File.expand_path('../lib', __FILE__)
require 'grpc/version' require 'grpc/version'
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = "grpc" s.name = 'grpc'
s.version = Google::RPC::VERSION s.version = Google::RPC::VERSION
s.authors = ["One Platform Team"] s.authors = ['One Platform Team']
s.email = "stubby-team@google.com" s.email = 'stubby-team@google.com'
s.homepage = "http://go/grpc" s.homepage = 'http://go/grpc'
s.summary = 'Google RPC system in Ruby' s.summary = 'Google RPC system in Ruby'
s.description = 'Send RPCs from Ruby' s.description = 'Send RPCs from Ruby'
s.files = `git ls-files`.split("\n") s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- spec/*`.split("\n") s.test_files = `git ls-files -- spec/*`.split("\n")
s.executables = `git ls-files -- examples/*.rb`.split("\n").map{ |f| File.basename(f) } s.executables = `git ls-files -- bin/*.rb`.split("\n").map do |f|
s.require_paths = ['lib' ] File.basename(f)
end
s.require_paths = ['lib']
s.platform = Gem::Platform::RUBY s.platform = Gem::Platform::RUBY
s.add_dependency 'xray' s.add_dependency 'xray'
s.add_dependency 'logging', '~> 1.8' s.add_dependency 'logging', '~> 1.8'
s.add_dependency 'google-protobuf', '~> 3.0.0alpha.1.1' s.add_dependency 'google-protobuf', '~> 3.0.0alpha.1.1'
s.add_dependency 'minitest', '~> 5.4' # not a dev dependency, used by the interop tests s.add_dependency 'minitest', '~> 5.4' # reqd for interop tests
s.add_development_dependency "bundler", "~> 1.7" s.add_development_dependency 'bundler', '~> 1.7'
s.add_development_dependency "rake", "~> 10.0" s.add_development_dependency 'rake', '~> 10.0'
s.add_development_dependency 'rake-compiler', '~> 0' s.add_development_dependency 'rake-compiler', '~> 0'
s.add_development_dependency 'rspec', "~> 3.0" s.add_development_dependency 'rubocop', '~> 0.28.0'
s.add_development_dependency 'rspec', '~> 3.0'
s.extensions = %w[ext/grpc/extconf.rb] s.extensions = %w(ext/grpc/extconf.rb)
end end

@ -29,25 +29,21 @@
require 'beefcake' require 'beefcake'
# Re-open the beefcake message module to add a static encode
#
# This is a temporary measure while beefcake is used as the default proto
# library for developing grpc ruby. Once that changes to the official proto
# library this can be removed. It's necessary to allow the update the service
# module to assume a static encode method.
#
# TODO(temiola): remove me, once official code generation is available in protoc
module Beefcake module Beefcake
# Re-open the beefcake message module to add a static encode
#
# This is a temporary measure while beefcake is used as the default proto
# library for developing grpc ruby. Once that changes to the official proto
# library this can be removed. It's necessary to allow the update the service
# module to assume a static encode method.
# TODO(temiola): remove this.
module Message module Message
# additional mixin module that adds static encode method when include # additional mixin module that adds static encode method when include
module StaticEncode module StaticEncode
# encodes o with its instance#encode method # encodes o with its instance#encode method
def encode(o) def encode(o)
o.encode o.encode
end end
end end
# extend self.included in Beefcake::Message to include StaticEncode # extend self.included in Beefcake::Message to include StaticEncode
@ -57,6 +53,5 @@ module Beefcake
o.extend Decode o.extend Decode
o.send(:include, Encode) o.send(:include, Encode)
end end
end end
end end

@ -30,9 +30,12 @@
module Google module Google
module RPC module RPC
module Core module Core
class Event # Add an inspect method to C-defined Event class. # Event is a class defined in the c extension
#
# Here, we add an inspect method.
class Event
def inspect def inspect
'<%s: type:%s, tag:%s result:%s>' % [self.class, type, tag, result] "<#{self.class}: type:#{type}, tag:#{tag} result:#{result}>"
end end
end end
end end

@ -32,9 +32,10 @@ require 'grpc'
module Google module Google
module RPC module RPC
module Core module Core
# TimeConsts is a module from the C extension.
module TimeConsts # re-opens a module in the C extension. #
# Here it's re-opened to add a utility func.
module TimeConsts
# Converts a time delta to an absolute deadline. # Converts a time delta to an absolute deadline.
# #
# Assumes timeish is a relative time, and converts its to an absolute, # Assumes timeish is a relative time, and converts its to an absolute,
@ -48,24 +49,23 @@ module Google
# @param timeish [Number|TimeSpec] # @param timeish [Number|TimeSpec]
# @return timeish [Number|TimeSpec] # @return timeish [Number|TimeSpec]
def from_relative_time(timeish) def from_relative_time(timeish)
if timeish.is_a?TimeSpec if timeish.is_a? TimeSpec
timeish timeish
elsif timeish.nil? elsif timeish.nil?
TimeConsts::ZERO TimeConsts::ZERO
elsif !timeish.is_a?Numeric elsif !timeish.is_a? Numeric
raise TypeError('Cannot make an absolute deadline from %s', fail(TypeError,
timeish.inspect) "Cannot make an absolute deadline from #{timeish.inspect}")
elsif timeish < 0 elsif timeish < 0
TimeConsts::INFINITE_FUTURE TimeConsts::INFINITE_FUTURE
elsif timeish == 0 elsif timeish == 0
TimeConsts::ZERO TimeConsts::ZERO
else !timeish.nil? else
Time.now + timeish Time.now + timeish
end end
end end
module_function :from_relative_time module_function :from_relative_time
end end
end end
end end

@ -30,9 +30,8 @@
require 'grpc' require 'grpc'
module Google module Google
# Google::RPC contains the General RPC module.
module RPC module RPC
# OutOfTime is an exception class that indicates that an RPC exceeded its # OutOfTime is an exception class that indicates that an RPC exceeded its
# deadline. # deadline.
OutOfTime = Class.new(StandardError) OutOfTime = Class.new(StandardError)
@ -42,12 +41,11 @@ module Google
# error should be returned to the other end of a GRPC connection; when # error should be returned to the other end of a GRPC connection; when
# caught it means that this end received a status error. # caught it means that this end received a status error.
class BadStatus < StandardError class BadStatus < StandardError
attr_reader :code, :details attr_reader :code, :details
# @param code [Numeric] the status code # @param code [Numeric] the status code
# @param details [String] the details of the exception # @param details [String] the details of the exception
def initialize(code, details='unknown cause') def initialize(code, details = 'unknown cause')
super("#{code}:#{details}") super("#{code}:#{details}")
@code = code @code = code
@details = details @details = details
@ -60,9 +58,6 @@ module Google
def to_status def to_status
Status.new(code, details) Status.new(code, details)
end end
end end
end end
end end

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

Loading…
Cancel
Save