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

pull/4038/head
David Garcia Quintas 9 years ago
commit 278c0fbb61
  1. 4
      setup.py
  2. 263
      src/compiler/python_generator.cc
  3. 3
      src/compiler/python_generator.h
  4. 3
      src/compiler/python_plugin.cc
  5. 2
      src/core/iomgr/pollset_multipoller_with_epoll.c
  6. 16
      src/csharp/Grpc.Core.Tests/PInvokeTest.cs
  7. 23
      src/csharp/Grpc.Core/Grpc.Core.csproj
  8. 18
      src/csharp/Grpc.Core/GrpcEnvironment.cs
  9. 70
      src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
  10. 7
      src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs
  11. 12
      src/csharp/Grpc.Core/Internal/CallCredentialsSafeHandle.cs
  12. 95
      src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
  13. 22
      src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
  14. 19
      src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs
  15. 38
      src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
  16. 7
      src/csharp/Grpc.Core/Internal/CompletionQueueEvent.cs
  17. 29
      src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
  18. 37
      src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
  19. 158
      src/csharp/Grpc.Core/Internal/NativeExtension.cs
  20. 9
      src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs
  21. 17
      src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs
  22. 816
      src/csharp/Grpc.Core/Internal/NativeMethods.cs
  23. 110
      src/csharp/Grpc.Core/Internal/PlatformApis.cs
  24. 12
      src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
  25. 42
      src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
  26. 30
      src/csharp/Grpc.Core/Internal/Timespec.cs
  27. 158
      src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
  28. 9
      src/csharp/Grpc.Core/NativeDeps.Linux.targets
  29. 9
      src/csharp/Grpc.Core/NativeDeps.Mac.targets
  30. 9
      src/csharp/Grpc.Core/NativeDeps.Windows.targets
  31. 28
      src/csharp/Grpc.Core/NativeDeps.targets
  32. 66
      src/php/ext/grpc/config.m4
  33. 11
      src/php/ext/grpc/package.xml
  34. 10
      src/php/ext/grpc/tests/grpc-basic.phpt
  35. 4
      test/core/end2end/gen_build_yaml.py
  36. 2
      test/cpp/qps/client.h
  37. 4
      tools/buildgen/generate_projects.py
  38. 79
      tools/jenkins/build_and_run_docker.sh
  39. 39
      tools/jenkins/build_artifacts.sh
  40. 41
      tools/jenkins/docker_run.sh
  41. 64
      tools/jenkins/grpc_artifact_linux_x64/Dockerfile
  42. 64
      tools/jenkins/grpc_artifact_linux_x86/Dockerfile
  43. 4
      tools/jenkins/grpc_interop_csharp/build_interop.sh
  44. 9
      tools/jenkins/grpc_jenkins_slave/Dockerfile
  45. 9
      tools/jenkins/grpc_jenkins_slave_32bits/Dockerfile
  46. 38
      tools/run_tests/build_artifact_csharp.sh
  47. 236
      tools/run_tests/build_artifacts.py
  48. 5
      tools/run_tests/build_csharp.sh
  49. 8
      tools/run_tests/build_php.sh
  50. 4
      tools/run_tests/jobset.py
  51. 46
      tools/run_tests/post_tests_php.sh
  52. 5
      tools/run_tests/run_csharp.sh
  53. 9
      tools/run_tests/run_tests.py
  54. 852
      tools/run_tests/tests.json

@ -42,8 +42,8 @@ from setuptools.command import egg_info
# Redirect the manifest template from MANIFEST.in to PYTHON-MANIFEST.in. # Redirect the manifest template from MANIFEST.in to PYTHON-MANIFEST.in.
egg_info.manifest_maker.template = 'PYTHON-MANIFEST.in' egg_info.manifest_maker.template = 'PYTHON-MANIFEST.in'
PYTHON_STEM = './src/python/grpcio/' PYTHON_STEM = './src/python/grpcio'
CORE_INCLUDE = ('./include', './',) CORE_INCLUDE = ('./include', '.',)
BORINGSSL_INCLUDE = ('./third_party/boringssl/include',) BORINGSSL_INCLUDE = ('./third_party/boringssl/include',)
# Ensure we're in the proper directory whether or not we're being used by pip. # Ensure we're in the proper directory whether or not we're being used by pip.

@ -1,6 +1,6 @@
/* /*
* *
* Copyright 2015, Google Inc. * Copyright 2015-2016, Google Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -148,91 +148,6 @@ class IndentScope {
// END FORMATTING BOILERPLATE // // END FORMATTING BOILERPLATE //
//////////////////////////////// ////////////////////////////////
bool PrintAlphaServicer(const ServiceDescriptor* service,
Printer* out) {
grpc::string doc = "<fill me in later!>";
map<grpc::string, grpc::string> dict = ListToDict({
"Service", service->name(),
"Documentation", doc,
});
out->Print(dict, "class EarlyAdopter$Service$Servicer(object):\n");
{
IndentScope raii_class_indent(out);
out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
out->Print("__metaclass__ = abc.ABCMeta\n");
for (int i = 0; i < service->method_count(); ++i) {
auto meth = service->method(i);
grpc::string arg_name = meth->client_streaming() ?
"request_iterator" : "request";
out->Print("@abc.abstractmethod\n");
out->Print("def $Method$(self, $ArgName$, context):\n",
"Method", meth->name(), "ArgName", arg_name);
{
IndentScope raii_method_indent(out);
out->Print("raise NotImplementedError()\n");
}
}
}
return true;
}
bool PrintAlphaServer(const ServiceDescriptor* service, Printer* out) {
grpc::string doc = "<fill me in later!>";
map<grpc::string, grpc::string> dict = ListToDict({
"Service", service->name(),
"Documentation", doc,
});
out->Print(dict, "class EarlyAdopter$Service$Server(object):\n");
{
IndentScope raii_class_indent(out);
out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
out->Print("__metaclass__ = abc.ABCMeta\n");
out->Print("@abc.abstractmethod\n");
out->Print("def start(self):\n");
{
IndentScope raii_method_indent(out);
out->Print("raise NotImplementedError()\n");
}
out->Print("@abc.abstractmethod\n");
out->Print("def stop(self):\n");
{
IndentScope raii_method_indent(out);
out->Print("raise NotImplementedError()\n");
}
}
return true;
}
bool PrintAlphaStub(const ServiceDescriptor* service,
Printer* out) {
grpc::string doc = "<fill me in later!>";
map<grpc::string, grpc::string> dict = ListToDict({
"Service", service->name(),
"Documentation", doc,
});
out->Print(dict, "class EarlyAdopter$Service$Stub(object):\n");
{
IndentScope raii_class_indent(out);
out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
out->Print("__metaclass__ = abc.ABCMeta\n");
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* meth = service->method(i);
grpc::string arg_name = meth->client_streaming() ?
"request_iterator" : "request";
auto methdict = ListToDict({"Method", meth->name(), "ArgName", arg_name});
out->Print("@abc.abstractmethod\n");
out->Print(methdict, "def $Method$(self, $ArgName$):\n");
{
IndentScope raii_method_indent(out);
out->Print("raise NotImplementedError()\n");
}
out->Print(methdict, "$Method$.async = None\n");
}
}
return true;
}
// TODO(protobuf team): Export `ModuleName` from protobuf's // TODO(protobuf team): Export `ModuleName` from protobuf's
// `src/google/protobuf/compiler/python/python_generator.cc` file. // `src/google/protobuf/compiler/python/python_generator.cc` file.
grpc::string ModuleName(const grpc::string& filename) { grpc::string ModuleName(const grpc::string& filename) {
@ -268,172 +183,6 @@ bool GetModuleAndMessagePath(const Descriptor* type,
return true; return true;
} }
bool PrintAlphaServerFactory(const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service, Printer* out) {
out->Print("def early_adopter_create_$Service$_server(servicer, port, "
"private_key=None, certificate_chain=None):\n",
"Service", service->name());
{
IndentScope raii_create_server_indent(out);
map<grpc::string, grpc::string> method_description_constructors;
map<grpc::string, pair<grpc::string, grpc::string>>
input_message_modules_and_classes;
map<grpc::string, pair<grpc::string, grpc::string>>
output_message_modules_and_classes;
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
const grpc::string method_description_constructor =
grpc::string(method->client_streaming() ? "stream_" : "unary_") +
grpc::string(method->server_streaming() ? "stream_" : "unary_") +
"service_description";
pair<grpc::string, grpc::string> input_message_module_and_class;
if (!GetModuleAndMessagePath(method->input_type(),
&input_message_module_and_class)) {
return false;
}
pair<grpc::string, grpc::string> output_message_module_and_class;
if (!GetModuleAndMessagePath(method->output_type(),
&output_message_module_and_class)) {
return false;
}
// Import the modules that define the messages used in RPCs.
out->Print("import $Module$\n", "Module",
input_message_module_and_class.first);
out->Print("import $Module$\n", "Module",
output_message_module_and_class.first);
method_description_constructors.insert(
make_pair(method->name(), method_description_constructor));
input_message_modules_and_classes.insert(
make_pair(method->name(), input_message_module_and_class));
output_message_modules_and_classes.insert(
make_pair(method->name(), output_message_module_and_class));
}
out->Print("method_service_descriptions = {\n");
for (auto name_and_description_constructor =
method_description_constructors.begin();
name_and_description_constructor !=
method_description_constructors.end();
name_and_description_constructor++) {
IndentScope raii_descriptions_indent(out);
const grpc::string method_name = name_and_description_constructor->first;
auto input_message_module_and_class =
input_message_modules_and_classes.find(method_name);
auto output_message_module_and_class =
output_message_modules_and_classes.find(method_name);
out->Print("\"$Method$\": alpha_utilities.$Constructor$(\n", "Method",
method_name, "Constructor",
name_and_description_constructor->second);
{
IndentScope raii_description_arguments_indent(out);
out->Print("servicer.$Method$,\n", "Method", method_name);
out->Print(
"$InputTypeModule$.$InputTypeClass$.FromString,\n",
"InputTypeModule", input_message_module_and_class->second.first,
"InputTypeClass", input_message_module_and_class->second.second);
out->Print(
"$OutputTypeModule$.$OutputTypeClass$.SerializeToString,\n",
"OutputTypeModule", output_message_module_and_class->second.first,
"OutputTypeClass", output_message_module_and_class->second.second);
}
out->Print("),\n");
}
out->Print("}\n");
out->Print(
"return early_adopter_implementations.server("
"\"$PackageQualifiedServiceName$\","
" method_service_descriptions, port, private_key=private_key,"
" certificate_chain=certificate_chain)\n",
"PackageQualifiedServiceName", package_qualified_service_name);
}
return true;
}
bool PrintAlphaStubFactory(const grpc::string& package_qualified_service_name,
const ServiceDescriptor* service, Printer* out) {
map<grpc::string, grpc::string> dict = ListToDict({
"Service", service->name(),
});
out->Print(dict, "def early_adopter_create_$Service$_stub(host, port,"
" metadata_transformer=None,"
" secure=False, root_certificates=None, private_key=None,"
" certificate_chain=None, server_host_override=None):\n");
{
IndentScope raii_create_server_indent(out);
map<grpc::string, grpc::string> method_description_constructors;
map<grpc::string, pair<grpc::string, grpc::string>>
input_message_modules_and_classes;
map<grpc::string, pair<grpc::string, grpc::string>>
output_message_modules_and_classes;
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
const grpc::string method_description_constructor =
grpc::string(method->client_streaming() ? "stream_" : "unary_") +
grpc::string(method->server_streaming() ? "stream_" : "unary_") +
"invocation_description";
pair<grpc::string, grpc::string> input_message_module_and_class;
if (!GetModuleAndMessagePath(method->input_type(),
&input_message_module_and_class)) {
return false;
}
pair<grpc::string, grpc::string> output_message_module_and_class;
if (!GetModuleAndMessagePath(method->output_type(),
&output_message_module_and_class)) {
return false;
}
// Import the modules that define the messages used in RPCs.
out->Print("import $Module$\n", "Module",
input_message_module_and_class.first);
out->Print("import $Module$\n", "Module",
output_message_module_and_class.first);
method_description_constructors.insert(
make_pair(method->name(), method_description_constructor));
input_message_modules_and_classes.insert(
make_pair(method->name(), input_message_module_and_class));
output_message_modules_and_classes.insert(
make_pair(method->name(), output_message_module_and_class));
}
out->Print("method_invocation_descriptions = {\n");
for (auto name_and_description_constructor =
method_description_constructors.begin();
name_and_description_constructor !=
method_description_constructors.end();
name_and_description_constructor++) {
IndentScope raii_descriptions_indent(out);
const grpc::string method_name = name_and_description_constructor->first;
auto input_message_module_and_class =
input_message_modules_and_classes.find(method_name);
auto output_message_module_and_class =
output_message_modules_and_classes.find(method_name);
out->Print("\"$Method$\": alpha_utilities.$Constructor$(\n", "Method",
method_name, "Constructor",
name_and_description_constructor->second);
{
IndentScope raii_description_arguments_indent(out);
out->Print(
"$InputTypeModule$.$InputTypeClass$.SerializeToString,\n",
"InputTypeModule", input_message_module_and_class->second.first,
"InputTypeClass", input_message_module_and_class->second.second);
out->Print(
"$OutputTypeModule$.$OutputTypeClass$.FromString,\n",
"OutputTypeModule", output_message_module_and_class->second.first,
"OutputTypeClass", output_message_module_and_class->second.second);
}
out->Print("),\n");
}
out->Print("}\n");
out->Print(
"return early_adopter_implementations.stub("
"\"$PackageQualifiedServiceName$\","
" method_invocation_descriptions, host, port,"
" metadata_transformer=metadata_transformer, secure=secure,"
" root_certificates=root_certificates, private_key=private_key,"
" certificate_chain=certificate_chain,"
" server_host_override=server_host_override)\n",
"PackageQualifiedServiceName", package_qualified_service_name);
}
return true;
}
bool PrintBetaServicer(const ServiceDescriptor* service, bool PrintBetaServicer(const ServiceDescriptor* service,
Printer* out) { Printer* out) {
grpc::string doc = "<fill me in later!>"; grpc::string doc = "<fill me in later!>";
@ -703,9 +452,6 @@ bool PrintPreamble(const FileDescriptor* file,
out->Print("import abc\n"); out->Print("import abc\n");
out->Print("from $Package$ import implementations as beta_implementations\n", out->Print("from $Package$ import implementations as beta_implementations\n",
"Package", config.beta_package_root); "Package", config.beta_package_root);
out->Print("from $Package$ import implementations as early_adopter_implementations\n",
"Package", config.early_adopter_package_root);
out->Print("from grpc.framework.alpha import utilities as alpha_utilities\n");
out->Print("from grpc.framework.common import cardinality\n"); out->Print("from grpc.framework.common import cardinality\n");
out->Print("from grpc.framework.interfaces.face import utilities as face_utilities\n"); out->Print("from grpc.framework.interfaces.face import utilities as face_utilities\n");
return true; return true;
@ -730,12 +476,7 @@ pair<bool, grpc::string> GetServices(const FileDescriptor* file,
for (int i = 0; i < file->service_count(); ++i) { for (int i = 0; i < file->service_count(); ++i) {
auto service = file->service(i); auto service = file->service(i);
auto package_qualified_service_name = package + service->name(); auto package_qualified_service_name = package + service->name();
if (!(PrintAlphaServicer(service, &out) && if (!(PrintBetaServicer(service, &out) &&
PrintAlphaServer(service, &out) &&
PrintAlphaStub(service, &out) &&
PrintAlphaServerFactory(package_qualified_service_name, service, &out) &&
PrintAlphaStubFactory(package_qualified_service_name, service, &out) &&
PrintBetaServicer(service, &out) &&
PrintBetaStub(service, &out) && PrintBetaStub(service, &out) &&
PrintBetaServerFactory(package_qualified_service_name, service, &out) && PrintBetaServerFactory(package_qualified_service_name, service, &out) &&
PrintBetaStubFactory(package_qualified_service_name, service, &out))) { PrintBetaStubFactory(package_qualified_service_name, service, &out))) {

@ -1,6 +1,6 @@
/* /*
* *
* Copyright 2015, Google Inc. * Copyright 2015-2016, Google Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -43,7 +43,6 @@ namespace grpc_python_generator {
// Data pertaining to configuration of the generator with respect to anything // Data pertaining to configuration of the generator with respect to anything
// that may be used internally at Google. // that may be used internally at Google.
struct GeneratorConfiguration { struct GeneratorConfiguration {
grpc::string early_adopter_package_root;
grpc::string beta_package_root; grpc::string beta_package_root;
}; };

@ -1,6 +1,6 @@
/* /*
* *
* Copyright 2015, Google Inc. * Copyright 2015-2016, Google Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -38,7 +38,6 @@
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
grpc_python_generator::GeneratorConfiguration config; grpc_python_generator::GeneratorConfiguration config;
config.early_adopter_package_root = "grpc.early_adopter";
config.beta_package_root = "grpc.beta"; config.beta_package_root = "grpc.beta";
grpc_python_generator::PythonGrpcGenerator generator(config); grpc_python_generator::PythonGrpcGenerator generator(config);
return grpc::protobuf::compiler::PluginMain(argc, argv, &generator); return grpc::protobuf::compiler::PluginMain(argc, argv, &generator);

@ -90,8 +90,10 @@ static void remove_epoll_fd_from_global_list(int epoll_fd) {
void grpc_remove_fd_from_all_epoll_sets(int fd) { void grpc_remove_fd_from_all_epoll_sets(int fd) {
int err; int err;
gpr_once_init(&init_epoll_fd_list_mu, init_mu);
gpr_mu_lock(&epoll_fd_list_mu); gpr_mu_lock(&epoll_fd_list_mu);
if (epoll_fd_global_list.count == 0) { if (epoll_fd_global_list.count == 0) {
gpr_mu_unlock(&epoll_fd_list_mu);
return; return;
} }
for (size_t i = 0; i < epoll_fd_global_list.count; i++) { for (size_t i = 0; i < epoll_fd_global_list.count; i++) {

@ -1,6 +1,6 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -45,13 +45,9 @@ namespace Grpc.Core.Tests
{ {
public class PInvokeTest public class PInvokeTest
{ {
int counter; static readonly NativeMethods Native = NativeMethods.Get();
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_test_callback([MarshalAs(UnmanagedType.FunctionPtr)] OpCompletionDelegate callback);
[DllImport("grpc_csharp_ext.dll")] int counter;
static extern IntPtr grpcsharp_test_nop(IntPtr ptr);
/// <summary> /// <summary>
/// (~1.26us .NET Windows) /// (~1.26us .NET Windows)
@ -87,7 +83,7 @@ namespace Grpc.Core.Tests
1000000, 10000000, 1000000, 10000000,
() => () =>
{ {
grpcsharp_test_callback(handler); Native.grpcsharp_test_callback(handler);
}); });
Assert.AreNotEqual(0, counter); Assert.AreNotEqual(0, counter);
} }
@ -106,7 +102,7 @@ namespace Grpc.Core.Tests
10000, 10000, 10000, 10000,
() => () =>
{ {
grpcsharp_test_callback(new OpCompletionDelegate(Handler)); Native.grpcsharp_test_callback(new OpCompletionDelegate(Handler));
}); });
Assert.AreNotEqual(0, counter); Assert.AreNotEqual(0, counter);
} }
@ -122,7 +118,7 @@ namespace Grpc.Core.Tests
1000000, 100000000, 1000000, 100000000,
() => () =>
{ {
grpcsharp_test_nop(IntPtr.Zero); Native.grpcsharp_test_nop(IntPtr.Zero);
}); });
} }

@ -19,7 +19,6 @@
<DefineConstants>DEBUG;</DefineConstants> <DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<NativeDependenciesConfiguration>Debug</NativeDependenciesConfiguration>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
@ -27,7 +26,6 @@
<OutputPath>bin\Release</OutputPath> <OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<NativeDependenciesConfiguration>Release</NativeDependenciesConfiguration>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
@ -38,7 +36,6 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<SignAssembly>True</SignAssembly> <SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
<NativeDependenciesConfiguration>Release</NativeDependenciesConfiguration>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
@ -52,6 +49,10 @@
<Compile Include="AsyncAuthInterceptor.cs" /> <Compile Include="AsyncAuthInterceptor.cs" />
<Compile Include="CallCredentials.cs" /> <Compile Include="CallCredentials.cs" />
<Compile Include="IClientStreamWriter.cs" /> <Compile Include="IClientStreamWriter.cs" />
<Compile Include="Internal\NativeMethods.cs" />
<Compile Include="Internal\PlatformApis.cs" />
<Compile Include="Internal\NativeExtension.cs" />
<Compile Include="Internal\UnmanagedLibrary.cs" />
<Compile Include="Internal\NativeMetadataCredentialsPlugin.cs" /> <Compile Include="Internal\NativeMetadataCredentialsPlugin.cs" />
<Compile Include="Internal\INativeCall.cs" /> <Compile Include="Internal\INativeCall.cs" />
<Compile Include="IServerStreamWriter.cs" /> <Compile Include="IServerStreamWriter.cs" />
@ -131,20 +132,6 @@
<None Include="Grpc.Core.nuspec" /> <None Include="Grpc.Core.nuspec" />
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<Choose> <Import Project="NativeDeps.targets" />
<!-- Under older versions of Monodevelop, Choose is not supported and is just
ignored, which gives us the desired effect. -->
<When Condition=" '$(OS)' != 'Unix' ">
<ItemGroup>
<Content Include="..\..\..\vsprojects\$(NativeDependenciesConfiguration)\grpc_csharp_ext.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</When>
<Otherwise />
</Choose>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup />
<ItemGroup />
<ItemGroup />
</Project> </Project>

@ -1,6 +1,6 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -47,15 +47,6 @@ namespace Grpc.Core
{ {
const int THREAD_POOL_SIZE = 4; const int THREAD_POOL_SIZE = 4;
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_init();
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_shutdown();
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_version_string(); // returns not-owned const char*
static object staticLock = new object(); static object staticLock = new object();
static GrpcEnvironment instance; static GrpcEnvironment instance;
static int refCount; static int refCount;
@ -136,7 +127,6 @@ namespace Grpc.Core
/// </summary> /// </summary>
private GrpcEnvironment() private GrpcEnvironment()
{ {
NativeLogRedirector.Redirect();
GrpcNativeInit(); GrpcNativeInit();
completionRegistry = new CompletionRegistry(this); completionRegistry = new CompletionRegistry(this);
threadPool = new GrpcThreadPool(this, THREAD_POOL_SIZE); threadPool = new GrpcThreadPool(this, THREAD_POOL_SIZE);
@ -181,18 +171,18 @@ namespace Grpc.Core
/// </summary> /// </summary>
internal static string GetCoreVersionString() internal static string GetCoreVersionString()
{ {
var ptr = grpcsharp_version_string(); // the pointer is not owned var ptr = NativeMethods.Get().grpcsharp_version_string(); // the pointer is not owned
return Marshal.PtrToStringAnsi(ptr); return Marshal.PtrToStringAnsi(ptr);
} }
internal static void GrpcNativeInit() internal static void GrpcNativeInit()
{ {
grpcsharp_init(); NativeMethods.Get().grpcsharp_init();
} }
internal static void GrpcNativeShutdown() internal static void GrpcNativeShutdown()
{ {
grpcsharp_shutdown(); NativeMethods.Get().grpcsharp_shutdown();
} }
/// <summary> /// <summary>

@ -42,47 +42,7 @@ namespace Grpc.Core.Internal
/// </summary> /// </summary>
internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid
{ {
[DllImport("grpc_csharp_ext.dll")] static readonly NativeMethods Native = NativeMethods.Get();
static extern BatchContextSafeHandle grpcsharp_batch_context_create();
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_batch_context_recv_initial_metadata(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_batch_context_recv_message_to_buffer(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen);
[DllImport("grpc_csharp_ext.dll")]
static extern StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_batch_context_recv_status_on_client_details(BatchContextSafeHandle ctx); // returns const char*
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern CallSafeHandle grpcsharp_batch_context_server_rpc_new_call(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_batch_context_server_rpc_new_method(BatchContextSafeHandle ctx); // returns const char*
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_batch_context_server_rpc_new_host(BatchContextSafeHandle ctx); // returns const char*
[DllImport("grpc_csharp_ext.dll")]
static extern Timespec grpcsharp_batch_context_server_rpc_new_deadline(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_batch_context_server_rpc_new_request_metadata(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern int grpcsharp_batch_context_recv_close_on_server_cancelled(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_batch_context_destroy(IntPtr ctx);
private BatchContextSafeHandle() private BatchContextSafeHandle()
{ {
@ -90,7 +50,7 @@ namespace Grpc.Core.Internal
public static BatchContextSafeHandle Create() public static BatchContextSafeHandle Create()
{ {
return grpcsharp_batch_context_create(); return Native.grpcsharp_batch_context_create();
} }
public IntPtr Handle public IntPtr Handle
@ -104,17 +64,17 @@ namespace Grpc.Core.Internal
// Gets data of recv_initial_metadata completion. // Gets data of recv_initial_metadata completion.
public Metadata GetReceivedInitialMetadata() public Metadata GetReceivedInitialMetadata()
{ {
IntPtr metadataArrayPtr = grpcsharp_batch_context_recv_initial_metadata(this); IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_initial_metadata(this);
return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr); return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
} }
// Gets data of recv_status_on_client completion. // Gets data of recv_status_on_client completion.
public ClientSideStatus GetReceivedStatusOnClient() public ClientSideStatus GetReceivedStatusOnClient()
{ {
string details = Marshal.PtrToStringAnsi(grpcsharp_batch_context_recv_status_on_client_details(this)); string details = Marshal.PtrToStringAnsi(Native.grpcsharp_batch_context_recv_status_on_client_details(this));
var status = new Status(grpcsharp_batch_context_recv_status_on_client_status(this), details); var status = new Status(Native.grpcsharp_batch_context_recv_status_on_client_status(this), details);
IntPtr metadataArrayPtr = grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this); IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this);
var metadata = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr); var metadata = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
return new ClientSideStatus(status, metadata); return new ClientSideStatus(status, metadata);
@ -123,26 +83,26 @@ namespace Grpc.Core.Internal
// Gets data of recv_message completion. // Gets data of recv_message completion.
public byte[] GetReceivedMessage() public byte[] GetReceivedMessage()
{ {
IntPtr len = grpcsharp_batch_context_recv_message_length(this); IntPtr len = Native.grpcsharp_batch_context_recv_message_length(this);
if (len == new IntPtr(-1)) if (len == new IntPtr(-1))
{ {
return null; return null;
} }
byte[] data = new byte[(int)len]; byte[] data = new byte[(int)len];
grpcsharp_batch_context_recv_message_to_buffer(this, data, new UIntPtr((ulong)data.Length)); Native.grpcsharp_batch_context_recv_message_to_buffer(this, data, new UIntPtr((ulong)data.Length));
return data; return data;
} }
// Gets data of server_rpc_new completion. // Gets data of server_rpc_new completion.
public ServerRpcNew GetServerRpcNew(Server server) public ServerRpcNew GetServerRpcNew(Server server)
{ {
var call = grpcsharp_batch_context_server_rpc_new_call(this); var call = Native.grpcsharp_batch_context_server_rpc_new_call(this);
var method = Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_method(this)); var method = Marshal.PtrToStringAnsi(Native.grpcsharp_batch_context_server_rpc_new_method(this));
var host = Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_host(this)); var host = Marshal.PtrToStringAnsi(Native.grpcsharp_batch_context_server_rpc_new_host(this));
var deadline = grpcsharp_batch_context_server_rpc_new_deadline(this); var deadline = Native.grpcsharp_batch_context_server_rpc_new_deadline(this);
IntPtr metadataArrayPtr = grpcsharp_batch_context_server_rpc_new_request_metadata(this); IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_server_rpc_new_request_metadata(this);
var metadata = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr); var metadata = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
return new ServerRpcNew(server, call, method, host, deadline, metadata); return new ServerRpcNew(server, call, method, host, deadline, metadata);
@ -151,12 +111,12 @@ namespace Grpc.Core.Internal
// Gets data of receive_close_on_server completion. // Gets data of receive_close_on_server completion.
public bool GetReceivedCloseOnServerCancelled() public bool GetReceivedCloseOnServerCancelled()
{ {
return grpcsharp_batch_context_recv_close_on_server_cancelled(this) != 0; return Native.grpcsharp_batch_context_recv_close_on_server_cancelled(this) != 0;
} }
protected override bool ReleaseHandle() protected override bool ReleaseHandle()
{ {
grpcsharp_batch_context_destroy(handle); Native.grpcsharp_batch_context_destroy(handle);
return true; return true;
} }
} }

@ -1,5 +1,5 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -39,8 +39,7 @@ namespace Grpc.Core.Internal
/// </summary> /// </summary>
internal class CStringSafeHandle : SafeHandleZeroIsInvalid internal class CStringSafeHandle : SafeHandleZeroIsInvalid
{ {
[DllImport("grpc_csharp_ext.dll")] static readonly NativeMethods Native = NativeMethods.Get();
static extern void gprsharp_free(IntPtr ptr);
private CStringSafeHandle() private CStringSafeHandle()
{ {
@ -53,7 +52,7 @@ namespace Grpc.Core.Internal
protected override bool ReleaseHandle() protected override bool ReleaseHandle()
{ {
gprsharp_free(handle); Native.gprsharp_free(handle);
return true; return true;
} }
} }

@ -1,5 +1,5 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -40,11 +40,7 @@ namespace Grpc.Core.Internal
/// </summary> /// </summary>
internal class CallCredentialsSafeHandle : SafeHandleZeroIsInvalid internal class CallCredentialsSafeHandle : SafeHandleZeroIsInvalid
{ {
[DllImport("grpc_csharp_ext.dll")] static readonly NativeMethods Native = NativeMethods.Get();
static extern CallCredentialsSafeHandle grpcsharp_composite_call_credentials_create(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_call_credentials_release(IntPtr credentials);
private CallCredentialsSafeHandle() private CallCredentialsSafeHandle()
{ {
@ -52,12 +48,12 @@ namespace Grpc.Core.Internal
public static CallCredentialsSafeHandle CreateComposite(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2) public static CallCredentialsSafeHandle CreateComposite(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2)
{ {
return grpcsharp_composite_call_credentials_create(creds1, creds2); return Native.grpcsharp_composite_call_credentials_create(creds1, creds2);
} }
protected override bool ReleaseHandle() protected override bool ReleaseHandle()
{ {
grpcsharp_call_credentials_release(handle); Native.grpcsharp_call_credentials_release(handle);
return true; return true;
} }
} }

@ -44,71 +44,12 @@ namespace Grpc.Core.Internal
internal class CallSafeHandle : SafeHandleZeroIsInvalid, INativeCall internal class CallSafeHandle : SafeHandleZeroIsInvalid, INativeCall
{ {
public static readonly CallSafeHandle NullInstance = new CallSafeHandle(); public static readonly CallSafeHandle NullInstance = new CallSafeHandle();
static readonly NativeMethods Native = NativeMethods.Get();
const uint GRPC_WRITE_BUFFER_HINT = 1; const uint GRPC_WRITE_BUFFER_HINT = 1;
CompletionRegistry completionRegistry; CompletionRegistry completionRegistry;
CompletionQueueSafeHandle completionQueue; CompletionQueueSafeHandle completionQueue;
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_cancel(CallSafeHandle call);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_start_unary(CallSafeHandle call,
BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_start_client_streaming(CallSafeHandle call,
BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_start_server_streaming(CallSafeHandle call,
BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len,
MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_start_duplex_streaming(CallSafeHandle call,
BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_send_message(CallSafeHandle call,
BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, WriteFlags writeFlags, bool sendEmptyInitialMetadata);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_send_close_from_client(CallSafeHandle call,
BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_send_status_from_server(CallSafeHandle call,
BatchContextSafeHandle ctx, StatusCode statusCode, string statusMessage, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_recv_message(CallSafeHandle call,
BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_recv_initial_metadata(CallSafeHandle call,
BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_start_serverside(CallSafeHandle call,
BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_send_initial_metadata(CallSafeHandle call,
BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_set_credentials(CallSafeHandle call, CallCredentialsSafeHandle credentials);
[DllImport("grpc_csharp_ext.dll")]
static extern CStringSafeHandle grpcsharp_call_get_peer(CallSafeHandle call);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_call_destroy(IntPtr call);
private CallSafeHandle() private CallSafeHandle()
{ {
} }
@ -121,7 +62,7 @@ namespace Grpc.Core.Internal
public void SetCredentials(CallCredentialsSafeHandle credentials) public void SetCredentials(CallCredentialsSafeHandle credentials)
{ {
grpcsharp_call_set_credentials(this, credentials).CheckOk(); Native.grpcsharp_call_set_credentials(this, credentials).CheckOk();
} }
public void StartUnary(UnaryResponseClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags) public void StartUnary(UnaryResponseClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
@ -130,7 +71,7 @@ namespace Grpc.Core.Internal
{ {
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata())); completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()));
grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags) Native.grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags)
.CheckOk(); .CheckOk();
} }
} }
@ -139,7 +80,7 @@ namespace Grpc.Core.Internal
{ {
using (Profilers.ForCurrentThread().NewScope("CallSafeHandle.StartUnary")) using (Profilers.ForCurrentThread().NewScope("CallSafeHandle.StartUnary"))
{ {
grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags) Native.grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags)
.CheckOk(); .CheckOk();
} }
} }
@ -150,7 +91,7 @@ namespace Grpc.Core.Internal
{ {
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata())); completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()));
grpcsharp_call_start_client_streaming(this, ctx, metadataArray).CheckOk(); Native.grpcsharp_call_start_client_streaming(this, ctx, metadataArray).CheckOk();
} }
} }
@ -160,7 +101,7 @@ namespace Grpc.Core.Internal
{ {
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient())); completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient()));
grpcsharp_call_start_server_streaming(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags).CheckOk(); Native.grpcsharp_call_start_server_streaming(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags).CheckOk();
} }
} }
@ -170,7 +111,7 @@ namespace Grpc.Core.Internal
{ {
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient())); completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient()));
grpcsharp_call_start_duplex_streaming(this, ctx, metadataArray).CheckOk(); Native.grpcsharp_call_start_duplex_streaming(this, ctx, metadataArray).CheckOk();
} }
} }
@ -180,7 +121,7 @@ namespace Grpc.Core.Internal
{ {
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success)); completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
grpcsharp_call_send_message(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, sendEmptyInitialMetadata).CheckOk(); Native.grpcsharp_call_send_message(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, sendEmptyInitialMetadata).CheckOk();
} }
} }
@ -190,7 +131,7 @@ namespace Grpc.Core.Internal
{ {
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success)); completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
grpcsharp_call_send_close_from_client(this, ctx).CheckOk(); Native.grpcsharp_call_send_close_from_client(this, ctx).CheckOk();
} }
} }
@ -200,7 +141,7 @@ namespace Grpc.Core.Internal
{ {
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success)); completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, status.Detail, metadataArray, sendEmptyInitialMetadata).CheckOk(); Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, status.Detail, metadataArray, sendEmptyInitialMetadata).CheckOk();
} }
} }
@ -210,7 +151,7 @@ namespace Grpc.Core.Internal
{ {
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedMessage())); completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedMessage()));
grpcsharp_call_recv_message(this, ctx).CheckOk(); Native.grpcsharp_call_recv_message(this, ctx).CheckOk();
} }
} }
@ -220,7 +161,7 @@ namespace Grpc.Core.Internal
{ {
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedInitialMetadata())); completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedInitialMetadata()));
grpcsharp_call_recv_initial_metadata(this, ctx).CheckOk(); Native.grpcsharp_call_recv_initial_metadata(this, ctx).CheckOk();
} }
} }
@ -230,7 +171,7 @@ namespace Grpc.Core.Internal
{ {
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedCloseOnServerCancelled())); completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedCloseOnServerCancelled()));
grpcsharp_call_start_serverside(this, ctx).CheckOk(); Native.grpcsharp_call_start_serverside(this, ctx).CheckOk();
} }
} }
@ -240,23 +181,23 @@ namespace Grpc.Core.Internal
{ {
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success)); completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
grpcsharp_call_send_initial_metadata(this, ctx, metadataArray).CheckOk(); Native.grpcsharp_call_send_initial_metadata(this, ctx, metadataArray).CheckOk();
} }
} }
public void Cancel() public void Cancel()
{ {
grpcsharp_call_cancel(this).CheckOk(); Native.grpcsharp_call_cancel(this).CheckOk();
} }
public void CancelWithStatus(Status status) public void CancelWithStatus(Status status)
{ {
grpcsharp_call_cancel_with_status(this, status.StatusCode, status.Detail).CheckOk(); Native.grpcsharp_call_cancel_with_status(this, status.StatusCode, status.Detail).CheckOk();
} }
public string GetPeer() public string GetPeer()
{ {
using (var cstring = grpcsharp_call_get_peer(this)) using (var cstring = Native.grpcsharp_call_get_peer(this))
{ {
return cstring.GetValue(); return cstring.GetValue();
} }
@ -264,7 +205,7 @@ namespace Grpc.Core.Internal
protected override bool ReleaseHandle() protected override bool ReleaseHandle()
{ {
grpcsharp_call_destroy(handle); Native.grpcsharp_call_destroy(handle);
return true; return true;
} }

@ -1,5 +1,5 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -39,17 +39,7 @@ namespace Grpc.Core.Internal
/// </summary> /// </summary>
internal class ChannelArgsSafeHandle : SafeHandleZeroIsInvalid internal class ChannelArgsSafeHandle : SafeHandleZeroIsInvalid
{ {
[DllImport("grpc_csharp_ext.dll")] static readonly NativeMethods Native = NativeMethods.Get();
static extern ChannelArgsSafeHandle grpcsharp_channel_args_create(UIntPtr numArgs);
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
static extern void grpcsharp_channel_args_set_string(ChannelArgsSafeHandle args, UIntPtr index, string key, string value);
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
static extern void grpcsharp_channel_args_set_integer(ChannelArgsSafeHandle args, UIntPtr index, string key, int value);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_channel_args_destroy(IntPtr args);
private ChannelArgsSafeHandle() private ChannelArgsSafeHandle()
{ {
@ -62,22 +52,22 @@ namespace Grpc.Core.Internal
public static ChannelArgsSafeHandle Create(int size) public static ChannelArgsSafeHandle Create(int size)
{ {
return grpcsharp_channel_args_create(new UIntPtr((uint)size)); return Native.grpcsharp_channel_args_create(new UIntPtr((uint)size));
} }
public void SetString(int index, string key, string value) public void SetString(int index, string key, string value)
{ {
grpcsharp_channel_args_set_string(this, new UIntPtr((uint)index), key, value); Native.grpcsharp_channel_args_set_string(this, new UIntPtr((uint)index), key, value);
} }
public void SetInteger(int index, string key, int value) public void SetInteger(int index, string key, int value)
{ {
grpcsharp_channel_args_set_integer(this, new UIntPtr((uint)index), key, value); Native.grpcsharp_channel_args_set_integer(this, new UIntPtr((uint)index), key, value);
} }
protected override bool ReleaseHandle() protected override bool ReleaseHandle()
{ {
grpcsharp_channel_args_destroy(handle); Native.grpcsharp_channel_args_destroy(handle);
return true; return true;
} }
} }

@ -1,5 +1,5 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -40,14 +40,7 @@ namespace Grpc.Core.Internal
/// </summary> /// </summary>
internal class ChannelCredentialsSafeHandle : SafeHandleZeroIsInvalid internal class ChannelCredentialsSafeHandle : SafeHandleZeroIsInvalid
{ {
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] static readonly NativeMethods Native = NativeMethods.Get();
static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey);
[DllImport("grpc_csharp_ext.dll")]
static extern ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_channel_credentials_release(IntPtr credentials);
private ChannelCredentialsSafeHandle() private ChannelCredentialsSafeHandle()
{ {
@ -64,22 +57,22 @@ namespace Grpc.Core.Internal
{ {
if (keyCertPair != null) if (keyCertPair != null)
{ {
return grpcsharp_ssl_credentials_create(pemRootCerts, keyCertPair.CertificateChain, keyCertPair.PrivateKey); return Native.grpcsharp_ssl_credentials_create(pemRootCerts, keyCertPair.CertificateChain, keyCertPair.PrivateKey);
} }
else else
{ {
return grpcsharp_ssl_credentials_create(pemRootCerts, null, null); return Native.grpcsharp_ssl_credentials_create(pemRootCerts, null, null);
} }
} }
public static ChannelCredentialsSafeHandle CreateComposite(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds) public static ChannelCredentialsSafeHandle CreateComposite(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds)
{ {
return grpcsharp_composite_channel_credentials_create(channelCreds, callCreds); return Native.grpcsharp_composite_channel_credentials_create(channelCreds, callCreds);
} }
protected override bool ReleaseHandle() protected override bool ReleaseHandle()
{ {
grpcsharp_channel_credentials_release(handle); Native.grpcsharp_channel_credentials_release(handle);
return true; return true;
} }
} }

@ -1,5 +1,5 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -41,27 +41,7 @@ namespace Grpc.Core.Internal
/// </summary> /// </summary>
internal class ChannelSafeHandle : SafeHandleZeroIsInvalid internal class ChannelSafeHandle : SafeHandleZeroIsInvalid
{ {
[DllImport("grpc_csharp_ext.dll")] static readonly NativeMethods Native = NativeMethods.Get();
static extern ChannelSafeHandle grpcsharp_insecure_channel_create(string target, ChannelArgsSafeHandle channelArgs);
[DllImport("grpc_csharp_ext.dll")]
static extern ChannelSafeHandle grpcsharp_secure_channel_create(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs);
[DllImport("grpc_csharp_ext.dll")]
static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
[DllImport("grpc_csharp_ext.dll")]
static extern ChannelState grpcsharp_channel_check_connectivity_state(ChannelSafeHandle channel, int tryToConnect);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_channel_watch_connectivity_state(ChannelSafeHandle channel, ChannelState lastObservedState,
Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern CStringSafeHandle grpcsharp_channel_get_target(ChannelSafeHandle call);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_channel_destroy(IntPtr channel);
private ChannelSafeHandle() private ChannelSafeHandle()
{ {
@ -72,7 +52,7 @@ namespace Grpc.Core.Internal
// Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle. // Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle.
// Doing so would make object finalizer crash if we end up abandoning the handle. // Doing so would make object finalizer crash if we end up abandoning the handle.
GrpcEnvironment.GrpcNativeInit(); GrpcEnvironment.GrpcNativeInit();
return grpcsharp_insecure_channel_create(target, channelArgs); return Native.grpcsharp_insecure_channel_create(target, channelArgs);
} }
public static ChannelSafeHandle CreateSecure(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs) public static ChannelSafeHandle CreateSecure(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs)
@ -80,14 +60,14 @@ namespace Grpc.Core.Internal
// Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle. // Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle.
// Doing so would make object finalizer crash if we end up abandoning the handle. // Doing so would make object finalizer crash if we end up abandoning the handle.
GrpcEnvironment.GrpcNativeInit(); GrpcEnvironment.GrpcNativeInit();
return grpcsharp_secure_channel_create(credentials, target, channelArgs); return Native.grpcsharp_secure_channel_create(credentials, target, channelArgs);
} }
public CallSafeHandle CreateCall(CompletionRegistry registry, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline, CallCredentialsSafeHandle credentials) public CallSafeHandle CreateCall(CompletionRegistry registry, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline, CallCredentialsSafeHandle credentials)
{ {
using (Profilers.ForCurrentThread().NewScope("ChannelSafeHandle.CreateCall")) using (Profilers.ForCurrentThread().NewScope("ChannelSafeHandle.CreateCall"))
{ {
var result = grpcsharp_channel_create_call(this, parentCall, propagationMask, cq, method, host, deadline); var result = Native.grpcsharp_channel_create_call(this, parentCall, propagationMask, cq, method, host, deadline);
if (credentials != null) if (credentials != null)
{ {
result.SetCredentials(credentials); result.SetCredentials(credentials);
@ -99,7 +79,7 @@ namespace Grpc.Core.Internal
public ChannelState CheckConnectivityState(bool tryToConnect) public ChannelState CheckConnectivityState(bool tryToConnect)
{ {
return grpcsharp_channel_check_connectivity_state(this, tryToConnect ? 1 : 0); return Native.grpcsharp_channel_check_connectivity_state(this, tryToConnect ? 1 : 0);
} }
public void WatchConnectivityState(ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, public void WatchConnectivityState(ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq,
@ -107,12 +87,12 @@ namespace Grpc.Core.Internal
{ {
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, callback); completionRegistry.RegisterBatchCompletion(ctx, callback);
grpcsharp_channel_watch_connectivity_state(this, lastObservedState, deadline, cq, ctx); Native.grpcsharp_channel_watch_connectivity_state(this, lastObservedState, deadline, cq, ctx);
} }
public string GetTarget() public string GetTarget()
{ {
using (var cstring = grpcsharp_channel_get_target(this)) using (var cstring = Native.grpcsharp_channel_get_target(this))
{ {
return cstring.GetValue(); return cstring.GetValue();
} }
@ -120,7 +100,7 @@ namespace Grpc.Core.Internal
protected override bool ReleaseHandle() protected override bool ReleaseHandle()
{ {
grpcsharp_channel_destroy(handle); Native.grpcsharp_channel_destroy(handle);
GrpcEnvironment.GrpcNativeShutdown(); GrpcEnvironment.GrpcNativeShutdown();
return true; return true;
} }

@ -1,6 +1,6 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -42,8 +42,7 @@ namespace Grpc.Core.Internal
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct CompletionQueueEvent internal struct CompletionQueueEvent
{ {
[DllImport("grpc_csharp_ext.dll")] static readonly NativeMethods Native = NativeMethods.Get();
static extern int grpcsharp_sizeof_grpc_event();
public GRPCCompletionType type; public GRPCCompletionType type;
public int success; public int success;
@ -53,7 +52,7 @@ namespace Grpc.Core.Internal
{ {
get get
{ {
return grpcsharp_sizeof_grpc_event(); return Native.grpcsharp_sizeof_grpc_event();
} }
} }
} }

@ -1,5 +1,5 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -42,22 +42,9 @@ namespace Grpc.Core.Internal
/// </summary> /// </summary>
internal class CompletionQueueSafeHandle : SafeHandleZeroIsInvalid internal class CompletionQueueSafeHandle : SafeHandleZeroIsInvalid
{ {
AtomicCounter shutdownRefcount = new AtomicCounter(1); static readonly NativeMethods Native = NativeMethods.Get();
[DllImport("grpc_csharp_ext.dll")]
static extern CompletionQueueSafeHandle grpcsharp_completion_queue_create();
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq);
[DllImport("grpc_csharp_ext.dll")] AtomicCounter shutdownRefcount = new AtomicCounter(1);
static extern CompletionQueueEvent grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq);
[DllImport("grpc_csharp_ext.dll")]
static extern CompletionQueueEvent grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_completion_queue_destroy(IntPtr cq);
private CompletionQueueSafeHandle() private CompletionQueueSafeHandle()
{ {
@ -65,20 +52,20 @@ namespace Grpc.Core.Internal
public static CompletionQueueSafeHandle Create() public static CompletionQueueSafeHandle Create()
{ {
return grpcsharp_completion_queue_create(); return Native.grpcsharp_completion_queue_create();
} }
public CompletionQueueEvent Next() public CompletionQueueEvent Next()
{ {
return grpcsharp_completion_queue_next(this); return Native.grpcsharp_completion_queue_next(this);
} }
public CompletionQueueEvent Pluck(IntPtr tag) public CompletionQueueEvent Pluck(IntPtr tag)
{ {
using (Profilers.ForCurrentThread().NewScope("CompletionQueueSafeHandle.Pluck")) using (Profilers.ForCurrentThread().NewScope("CompletionQueueSafeHandle.Pluck"))
{ {
return grpcsharp_completion_queue_pluck(this, tag); return Native.grpcsharp_completion_queue_pluck(this, tag);
} }
} }
@ -98,7 +85,7 @@ namespace Grpc.Core.Internal
protected override bool ReleaseHandle() protected override bool ReleaseHandle()
{ {
grpcsharp_completion_queue_destroy(handle); Native.grpcsharp_completion_queue_destroy(handle);
return true; return true;
} }
@ -106,7 +93,7 @@ namespace Grpc.Core.Internal
{ {
if (shutdownRefcount.Decrement() == 0) if (shutdownRefcount.Decrement() == 0)
{ {
grpcsharp_completion_queue_shutdown(this); Native.grpcsharp_completion_queue_shutdown(this);
} }
} }

@ -1,5 +1,5 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -40,26 +40,7 @@ namespace Grpc.Core.Internal
/// </summary> /// </summary>
internal class MetadataArraySafeHandle : SafeHandleZeroIsInvalid internal class MetadataArraySafeHandle : SafeHandleZeroIsInvalid
{ {
[DllImport("grpc_csharp_ext.dll")] static readonly NativeMethods Native = NativeMethods.Get();
static extern MetadataArraySafeHandle grpcsharp_metadata_array_create(UIntPtr capacity);
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
static extern void grpcsharp_metadata_array_add(MetadataArraySafeHandle array, string key, byte[] value, UIntPtr valueLength);
[DllImport("grpc_csharp_ext.dll")]
static extern UIntPtr grpcsharp_metadata_array_count(IntPtr metadataArray);
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_metadata_array_get_key(IntPtr metadataArray, UIntPtr index);
[DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_metadata_array_get_value(IntPtr metadataArray, UIntPtr index);
[DllImport("grpc_csharp_ext.dll")]
static extern UIntPtr grpcsharp_metadata_array_get_value_length(IntPtr metadataArray, UIntPtr index);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_metadata_array_destroy_full(IntPtr array);
private MetadataArraySafeHandle() private MetadataArraySafeHandle()
{ {
@ -70,11 +51,11 @@ namespace Grpc.Core.Internal
using (Profilers.ForCurrentThread().NewScope("MetadataArraySafeHandle.Create")) using (Profilers.ForCurrentThread().NewScope("MetadataArraySafeHandle.Create"))
{ {
// TODO(jtattermusch): we might wanna check that the metadata is readonly // TODO(jtattermusch): we might wanna check that the metadata is readonly
var metadataArray = grpcsharp_metadata_array_create(new UIntPtr((ulong)metadata.Count)); var metadataArray = Native.grpcsharp_metadata_array_create(new UIntPtr((ulong)metadata.Count));
for (int i = 0; i < metadata.Count; i++) for (int i = 0; i < metadata.Count; i++)
{ {
var valueBytes = metadata[i].GetSerializedValueUnsafe(); var valueBytes = metadata[i].GetSerializedValueUnsafe();
grpcsharp_metadata_array_add(metadataArray, metadata[i].Key, valueBytes, new UIntPtr((ulong)valueBytes.Length)); Native.grpcsharp_metadata_array_add(metadataArray, metadata[i].Key, valueBytes, new UIntPtr((ulong)valueBytes.Length));
} }
return metadataArray; return metadataArray;
} }
@ -90,15 +71,15 @@ namespace Grpc.Core.Internal
return null; return null;
} }
ulong count = grpcsharp_metadata_array_count(metadataArray).ToUInt64(); ulong count = Native.grpcsharp_metadata_array_count(metadataArray).ToUInt64();
var metadata = new Metadata(); var metadata = new Metadata();
for (ulong i = 0; i < count; i++) for (ulong i = 0; i < count; i++)
{ {
var index = new UIntPtr(i); var index = new UIntPtr(i);
string key = Marshal.PtrToStringAnsi(grpcsharp_metadata_array_get_key(metadataArray, index)); string key = Marshal.PtrToStringAnsi(Native.grpcsharp_metadata_array_get_key(metadataArray, index));
var bytes = new byte[grpcsharp_metadata_array_get_value_length(metadataArray, index).ToUInt64()]; var bytes = new byte[Native.grpcsharp_metadata_array_get_value_length(metadataArray, index).ToUInt64()];
Marshal.Copy(grpcsharp_metadata_array_get_value(metadataArray, index), bytes, 0, bytes.Length); Marshal.Copy(Native.grpcsharp_metadata_array_get_value(metadataArray, index), bytes, 0, bytes.Length);
metadata.Add(Metadata.Entry.CreateUnsafe(key, bytes)); metadata.Add(Metadata.Entry.CreateUnsafe(key, bytes));
} }
return metadata; return metadata;
@ -114,7 +95,7 @@ namespace Grpc.Core.Internal
protected override bool ReleaseHandle() protected override bool ReleaseHandle()
{ {
grpcsharp_metadata_array_destroy_full(handle); Native.grpcsharp_metadata_array_destroy_full(handle);
return true; return true;
} }
} }

@ -0,0 +1,158 @@
#region Copyright notice and license
// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System;
using System.IO;
using System.Reflection;
using Grpc.Core.Logging;
namespace Grpc.Core.Internal
{
/// <summary>
/// Takes care of loading C# native extension and provides access to PInvoke calls the library exports.
/// </summary>
internal sealed class NativeExtension
{
const string NativeLibrariesDir = "nativelibs";
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<NativeExtension>();
static readonly object staticLock = new object();
static volatile NativeExtension instance;
readonly NativeMethods nativeMethods;
private NativeExtension()
{
this.nativeMethods = new NativeMethods(Load());
// Redirect the the native logs as the very first thing after loading the native extension
// to make sure we don't lose any logs.
NativeLogRedirector.Redirect(this.nativeMethods);
Logger.Debug("gRPC native library loaded successfully.");
}
/// <summary>
/// Gets singleton instance of this class.
/// The native extension is loaded when called for the first time.
/// </summary>
public static NativeExtension Get()
{
if (instance == null)
{
lock (staticLock)
{
if (instance == null) {
instance = new NativeExtension();
}
}
}
return instance;
}
/// <summary>
/// Provides access to the exported native methods.
/// </summary>
public NativeMethods NativeMethods
{
get { return this.nativeMethods; }
}
/// <summary>
/// Detects which configuration of native extension to load and load it.
/// </summary>
private static UnmanagedLibrary Load()
{
// TODO: allow customizing path to native extension (possibly through exposing a GrpcEnvironment property).
var libraryFlavor = string.Format("{0}_{1}", GetPlatformString(), GetArchitectureString());
var fullPath = Path.Combine(GetExecutingAssemblyDirectory(),
NativeLibrariesDir, libraryFlavor, GetNativeLibraryFilename());
return new UnmanagedLibrary(fullPath);
}
private static string GetExecutingAssemblyDirectory()
{
return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
}
private static string GetPlatformString()
{
if (PlatformApis.IsWindows)
{
return "windows";
}
if (PlatformApis.IsLinux)
{
return "linux";
}
if (PlatformApis.IsMacOSX)
{
return "macosx";
}
throw new InvalidOperationException("Unsupported platform.");
}
// Currently, only Intel platform is supported.
private static string GetArchitectureString()
{
if (PlatformApis.Is64Bit)
{
return "x64";
}
else
{
return "x86";
}
}
// platform specific file name of the extension library
private static string GetNativeLibraryFilename()
{
if (PlatformApis.IsWindows)
{
return "grpc_csharp_ext.dll";
}
if (PlatformApis.IsLinux)
{
return "libgrpc_csharp_ext.so";
}
if (PlatformApis.IsMacOSX)
{
return "libgrpc_csharp_ext.dylib";
}
throw new InvalidOperationException("Unsupported platform.");
}
}
}

@ -1,6 +1,6 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -51,20 +51,17 @@ namespace Grpc.Core.Internal
static object staticLock = new object(); static object staticLock = new object();
static GprLogDelegate writeCallback; static GprLogDelegate writeCallback;
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_redirect_log(GprLogDelegate callback);
/// <summary> /// <summary>
/// Redirects logs from native gRPC C core library to a general logger. /// Redirects logs from native gRPC C core library to a general logger.
/// </summary> /// </summary>
public static void Redirect() public static void Redirect(NativeMethods native)
{ {
lock (staticLock) lock (staticLock)
{ {
if (writeCallback == null) if (writeCallback == null)
{ {
writeCallback = new GprLogDelegate(HandleWrite); writeCallback = new GprLogDelegate(HandleWrite);
grpcsharp_redirect_log(writeCallback); native.grpcsharp_redirect_log(writeCallback);
} }
} }
} }

@ -1,5 +1,5 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -44,12 +44,7 @@ namespace Grpc.Core.Internal
{ {
const string GetMetadataExceptionMsg = "Exception occured in metadata credentials plugin."; const string GetMetadataExceptionMsg = "Exception occured in metadata credentials plugin.";
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<NativeMetadataCredentialsPlugin>(); static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<NativeMetadataCredentialsPlugin>();
static readonly NativeMethods Native = NativeMethods.Get();
[DllImport("grpc_csharp_ext.dll")]
static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor);
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
static extern void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails);
AsyncAuthInterceptor interceptor; AsyncAuthInterceptor interceptor;
GCHandle gcHandle; GCHandle gcHandle;
@ -63,7 +58,7 @@ namespace Grpc.Core.Internal
// Make sure the callback doesn't get garbage collected until it is destroyed. // Make sure the callback doesn't get garbage collected until it is destroyed.
this.gcHandle = GCHandle.Alloc(this.nativeInterceptor, GCHandleType.Normal); this.gcHandle = GCHandle.Alloc(this.nativeInterceptor, GCHandleType.Normal);
this.credentials = grpcsharp_metadata_credentials_create_from_plugin(nativeInterceptor); this.credentials = Native.grpcsharp_metadata_credentials_create_from_plugin(nativeInterceptor);
} }
public CallCredentialsSafeHandle Credentials public CallCredentialsSafeHandle Credentials
@ -87,7 +82,7 @@ namespace Grpc.Core.Internal
} }
catch (Exception e) catch (Exception e)
{ {
grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionMsg); Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionMsg);
Logger.Error(e, GetMetadataExceptionMsg); Logger.Error(e, GetMetadataExceptionMsg);
} }
} }
@ -101,12 +96,12 @@ namespace Grpc.Core.Internal
using (var metadataArray = MetadataArraySafeHandle.Create(metadata)) using (var metadataArray = MetadataArraySafeHandle.Create(metadata))
{ {
grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, metadataArray, StatusCode.OK, null); Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, metadataArray, StatusCode.OK, null);
} }
} }
catch (Exception e) catch (Exception e)
{ {
grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionMsg); Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionMsg);
Logger.Error(e, GetMetadataExceptionMsg); Logger.Error(e, GetMetadataExceptionMsg);
} }
} }

@ -0,0 +1,816 @@
#region Copyright notice and license
// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using Grpc.Core.Logging;
using Grpc.Core.Utils;
namespace Grpc.Core.Internal
{
/// <summary>
/// Provides access to all native methods provided by <c>NativeExtension</c>.
/// An extra level of indirection is added to P/Invoke calls to allow intelligent loading
/// of the right configuration of the native extension based on current platform, architecture etc.
/// </summary>
internal class NativeMethods
{
#region Native methods
public readonly Delegates.grpcsharp_init_delegate grpcsharp_init;
public readonly Delegates.grpcsharp_shutdown_delegate grpcsharp_shutdown;
public readonly Delegates.grpcsharp_version_string_delegate grpcsharp_version_string;
public readonly Delegates.grpcsharp_batch_context_create_delegate grpcsharp_batch_context_create;
public readonly Delegates.grpcsharp_batch_context_recv_initial_metadata_delegate grpcsharp_batch_context_recv_initial_metadata;
public readonly Delegates.grpcsharp_batch_context_recv_message_length_delegate grpcsharp_batch_context_recv_message_length;
public readonly Delegates.grpcsharp_batch_context_recv_message_to_buffer_delegate grpcsharp_batch_context_recv_message_to_buffer;
public readonly Delegates.grpcsharp_batch_context_recv_status_on_client_status_delegate grpcsharp_batch_context_recv_status_on_client_status;
public readonly Delegates.grpcsharp_batch_context_recv_status_on_client_details_delegate grpcsharp_batch_context_recv_status_on_client_details;
public readonly Delegates.grpcsharp_batch_context_recv_status_on_client_trailing_metadata_delegate grpcsharp_batch_context_recv_status_on_client_trailing_metadata;
public readonly Delegates.grpcsharp_batch_context_server_rpc_new_call_delegate grpcsharp_batch_context_server_rpc_new_call;
public readonly Delegates.grpcsharp_batch_context_server_rpc_new_method_delegate grpcsharp_batch_context_server_rpc_new_method;
public readonly Delegates.grpcsharp_batch_context_server_rpc_new_host_delegate grpcsharp_batch_context_server_rpc_new_host;
public readonly Delegates.grpcsharp_batch_context_server_rpc_new_deadline_delegate grpcsharp_batch_context_server_rpc_new_deadline;
public readonly Delegates.grpcsharp_batch_context_server_rpc_new_request_metadata_delegate grpcsharp_batch_context_server_rpc_new_request_metadata;
public readonly Delegates.grpcsharp_batch_context_recv_close_on_server_cancelled_delegate grpcsharp_batch_context_recv_close_on_server_cancelled;
public readonly Delegates.grpcsharp_batch_context_destroy_delegate grpcsharp_batch_context_destroy;
public readonly Delegates.grpcsharp_composite_call_credentials_create_delegate grpcsharp_composite_call_credentials_create;
public readonly Delegates.grpcsharp_call_credentials_release_delegate grpcsharp_call_credentials_release;
public readonly Delegates.grpcsharp_call_cancel_delegate grpcsharp_call_cancel;
public readonly Delegates.grpcsharp_call_cancel_with_status_delegate grpcsharp_call_cancel_with_status;
public readonly Delegates.grpcsharp_call_start_unary_delegate grpcsharp_call_start_unary;
public readonly Delegates.grpcsharp_call_start_client_streaming_delegate grpcsharp_call_start_client_streaming;
public readonly Delegates.grpcsharp_call_start_server_streaming_delegate grpcsharp_call_start_server_streaming;
public readonly Delegates.grpcsharp_call_start_duplex_streaming_delegate grpcsharp_call_start_duplex_streaming;
public readonly Delegates.grpcsharp_call_send_message_delegate grpcsharp_call_send_message;
public readonly Delegates.grpcsharp_call_send_close_from_client_delegate grpcsharp_call_send_close_from_client;
public readonly Delegates.grpcsharp_call_send_status_from_server_delegate grpcsharp_call_send_status_from_server;
public readonly Delegates.grpcsharp_call_recv_message_delegate grpcsharp_call_recv_message;
public readonly Delegates.grpcsharp_call_recv_initial_metadata_delegate grpcsharp_call_recv_initial_metadata;
public readonly Delegates.grpcsharp_call_start_serverside_delegate grpcsharp_call_start_serverside;
public readonly Delegates.grpcsharp_call_send_initial_metadata_delegate grpcsharp_call_send_initial_metadata;
public readonly Delegates.grpcsharp_call_set_credentials_delegate grpcsharp_call_set_credentials;
public readonly Delegates.grpcsharp_call_get_peer_delegate grpcsharp_call_get_peer;
public readonly Delegates.grpcsharp_call_destroy_delegate grpcsharp_call_destroy;
public readonly Delegates.grpcsharp_channel_args_create_delegate grpcsharp_channel_args_create;
public readonly Delegates.grpcsharp_channel_args_set_string_delegate grpcsharp_channel_args_set_string;
public readonly Delegates.grpcsharp_channel_args_set_integer_delegate grpcsharp_channel_args_set_integer;
public readonly Delegates.grpcsharp_channel_args_destroy_delegate grpcsharp_channel_args_destroy;
public readonly Delegates.grpcsharp_ssl_credentials_create_delegate grpcsharp_ssl_credentials_create;
public readonly Delegates.grpcsharp_composite_channel_credentials_create_delegate grpcsharp_composite_channel_credentials_create;
public readonly Delegates.grpcsharp_channel_credentials_release_delegate grpcsharp_channel_credentials_release;
public readonly Delegates.grpcsharp_insecure_channel_create_delegate grpcsharp_insecure_channel_create;
public readonly Delegates.grpcsharp_secure_channel_create_delegate grpcsharp_secure_channel_create;
public readonly Delegates.grpcsharp_channel_create_call_delegate grpcsharp_channel_create_call;
public readonly Delegates.grpcsharp_channel_check_connectivity_state_delegate grpcsharp_channel_check_connectivity_state;
public readonly Delegates.grpcsharp_channel_watch_connectivity_state_delegate grpcsharp_channel_watch_connectivity_state;
public readonly Delegates.grpcsharp_channel_get_target_delegate grpcsharp_channel_get_target;
public readonly Delegates.grpcsharp_channel_destroy_delegate grpcsharp_channel_destroy;
public readonly Delegates.grpcsharp_sizeof_grpc_event_delegate grpcsharp_sizeof_grpc_event;
public readonly Delegates.grpcsharp_completion_queue_create_delegate grpcsharp_completion_queue_create;
public readonly Delegates.grpcsharp_completion_queue_shutdown_delegate grpcsharp_completion_queue_shutdown;
public readonly Delegates.grpcsharp_completion_queue_next_delegate grpcsharp_completion_queue_next;
public readonly Delegates.grpcsharp_completion_queue_pluck_delegate grpcsharp_completion_queue_pluck;
public readonly Delegates.grpcsharp_completion_queue_destroy_delegate grpcsharp_completion_queue_destroy;
public readonly Delegates.gprsharp_free_delegate gprsharp_free;
public readonly Delegates.grpcsharp_metadata_array_create_delegate grpcsharp_metadata_array_create;
public readonly Delegates.grpcsharp_metadata_array_add_delegate grpcsharp_metadata_array_add;
public readonly Delegates.grpcsharp_metadata_array_count_delegate grpcsharp_metadata_array_count;
public readonly Delegates.grpcsharp_metadata_array_get_key_delegate grpcsharp_metadata_array_get_key;
public readonly Delegates.grpcsharp_metadata_array_get_value_delegate grpcsharp_metadata_array_get_value;
public readonly Delegates.grpcsharp_metadata_array_get_value_length_delegate grpcsharp_metadata_array_get_value_length;
public readonly Delegates.grpcsharp_metadata_array_destroy_full_delegate grpcsharp_metadata_array_destroy_full;
public readonly Delegates.grpcsharp_redirect_log_delegate grpcsharp_redirect_log;
public readonly Delegates.grpcsharp_metadata_credentials_create_from_plugin_delegate grpcsharp_metadata_credentials_create_from_plugin;
public readonly Delegates.grpcsharp_metadata_credentials_notify_from_plugin_delegate grpcsharp_metadata_credentials_notify_from_plugin;
public readonly Delegates.grpcsharp_ssl_server_credentials_create_delegate grpcsharp_ssl_server_credentials_create;
public readonly Delegates.grpcsharp_server_credentials_release_delegate grpcsharp_server_credentials_release;
public readonly Delegates.grpcsharp_server_create_delegate grpcsharp_server_create;
public readonly Delegates.grpcsharp_server_add_insecure_http2_port_delegate grpcsharp_server_add_insecure_http2_port;
public readonly Delegates.grpcsharp_server_add_secure_http2_port_delegate grpcsharp_server_add_secure_http2_port;
public readonly Delegates.grpcsharp_server_start_delegate grpcsharp_server_start;
public readonly Delegates.grpcsharp_server_request_call_delegate grpcsharp_server_request_call;
public readonly Delegates.grpcsharp_server_cancel_all_calls_delegate grpcsharp_server_cancel_all_calls;
public readonly Delegates.grpcsharp_server_shutdown_and_notify_callback_delegate grpcsharp_server_shutdown_and_notify_callback;
public readonly Delegates.grpcsharp_server_destroy_delegate grpcsharp_server_destroy;
public readonly Delegates.gprsharp_now_delegate gprsharp_now;
public readonly Delegates.gprsharp_inf_future_delegate gprsharp_inf_future;
public readonly Delegates.gprsharp_inf_past_delegate gprsharp_inf_past;
public readonly Delegates.gprsharp_convert_clock_type_delegate gprsharp_convert_clock_type;
public readonly Delegates.gprsharp_sizeof_timespec_delegate gprsharp_sizeof_timespec;
public readonly Delegates.grpcsharp_test_callback_delegate grpcsharp_test_callback;
public readonly Delegates.grpcsharp_test_nop_delegate grpcsharp_test_nop;
#endregion
public NativeMethods(UnmanagedLibrary library)
{
if (PlatformApis.IsLinux || PlatformApis.IsMacOSX)
{
this.grpcsharp_init = GetMethodDelegate<Delegates.grpcsharp_init_delegate>(library);
this.grpcsharp_shutdown = GetMethodDelegate<Delegates.grpcsharp_shutdown_delegate>(library);
this.grpcsharp_version_string = GetMethodDelegate<Delegates.grpcsharp_version_string_delegate>(library);
this.grpcsharp_batch_context_create = GetMethodDelegate<Delegates.grpcsharp_batch_context_create_delegate>(library);
this.grpcsharp_batch_context_recv_initial_metadata = GetMethodDelegate<Delegates.grpcsharp_batch_context_recv_initial_metadata_delegate>(library);
this.grpcsharp_batch_context_recv_message_length = GetMethodDelegate<Delegates.grpcsharp_batch_context_recv_message_length_delegate>(library);
this.grpcsharp_batch_context_recv_message_to_buffer = GetMethodDelegate<Delegates.grpcsharp_batch_context_recv_message_to_buffer_delegate>(library);
this.grpcsharp_batch_context_recv_status_on_client_status = GetMethodDelegate<Delegates.grpcsharp_batch_context_recv_status_on_client_status_delegate>(library);
this.grpcsharp_batch_context_recv_status_on_client_details = GetMethodDelegate<Delegates.grpcsharp_batch_context_recv_status_on_client_details_delegate>(library);
this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = GetMethodDelegate<Delegates.grpcsharp_batch_context_recv_status_on_client_trailing_metadata_delegate>(library);
this.grpcsharp_batch_context_server_rpc_new_call = GetMethodDelegate<Delegates.grpcsharp_batch_context_server_rpc_new_call_delegate>(library);
this.grpcsharp_batch_context_server_rpc_new_method = GetMethodDelegate<Delegates.grpcsharp_batch_context_server_rpc_new_method_delegate>(library);
this.grpcsharp_batch_context_server_rpc_new_host = GetMethodDelegate<Delegates.grpcsharp_batch_context_server_rpc_new_host_delegate>(library);
this.grpcsharp_batch_context_server_rpc_new_deadline = GetMethodDelegate<Delegates.grpcsharp_batch_context_server_rpc_new_deadline_delegate>(library);
this.grpcsharp_batch_context_server_rpc_new_request_metadata = GetMethodDelegate<Delegates.grpcsharp_batch_context_server_rpc_new_request_metadata_delegate>(library);
this.grpcsharp_batch_context_recv_close_on_server_cancelled = GetMethodDelegate<Delegates.grpcsharp_batch_context_recv_close_on_server_cancelled_delegate>(library);
this.grpcsharp_batch_context_destroy = GetMethodDelegate<Delegates.grpcsharp_batch_context_destroy_delegate>(library);
this.grpcsharp_composite_call_credentials_create = GetMethodDelegate<Delegates.grpcsharp_composite_call_credentials_create_delegate>(library);
this.grpcsharp_call_credentials_release = GetMethodDelegate<Delegates.grpcsharp_call_credentials_release_delegate>(library);
this.grpcsharp_call_cancel = GetMethodDelegate<Delegates.grpcsharp_call_cancel_delegate>(library);
this.grpcsharp_call_cancel_with_status = GetMethodDelegate<Delegates.grpcsharp_call_cancel_with_status_delegate>(library);
this.grpcsharp_call_start_unary = GetMethodDelegate<Delegates.grpcsharp_call_start_unary_delegate>(library);
this.grpcsharp_call_start_client_streaming = GetMethodDelegate<Delegates.grpcsharp_call_start_client_streaming_delegate>(library);
this.grpcsharp_call_start_server_streaming = GetMethodDelegate<Delegates.grpcsharp_call_start_server_streaming_delegate>(library);
this.grpcsharp_call_start_duplex_streaming = GetMethodDelegate<Delegates.grpcsharp_call_start_duplex_streaming_delegate>(library);
this.grpcsharp_call_send_message = GetMethodDelegate<Delegates.grpcsharp_call_send_message_delegate>(library);
this.grpcsharp_call_send_close_from_client = GetMethodDelegate<Delegates.grpcsharp_call_send_close_from_client_delegate>(library);
this.grpcsharp_call_send_status_from_server = GetMethodDelegate<Delegates.grpcsharp_call_send_status_from_server_delegate>(library);
this.grpcsharp_call_recv_message = GetMethodDelegate<Delegates.grpcsharp_call_recv_message_delegate>(library);
this.grpcsharp_call_recv_initial_metadata = GetMethodDelegate<Delegates.grpcsharp_call_recv_initial_metadata_delegate>(library);
this.grpcsharp_call_start_serverside = GetMethodDelegate<Delegates.grpcsharp_call_start_serverside_delegate>(library);
this.grpcsharp_call_send_initial_metadata = GetMethodDelegate<Delegates.grpcsharp_call_send_initial_metadata_delegate>(library);
this.grpcsharp_call_set_credentials = GetMethodDelegate<Delegates.grpcsharp_call_set_credentials_delegate>(library);
this.grpcsharp_call_get_peer = GetMethodDelegate<Delegates.grpcsharp_call_get_peer_delegate>(library);
this.grpcsharp_call_destroy = GetMethodDelegate<Delegates.grpcsharp_call_destroy_delegate>(library);
this.grpcsharp_channel_args_create = GetMethodDelegate<Delegates.grpcsharp_channel_args_create_delegate>(library);
this.grpcsharp_channel_args_set_string = GetMethodDelegate<Delegates.grpcsharp_channel_args_set_string_delegate>(library);
this.grpcsharp_channel_args_set_integer = GetMethodDelegate<Delegates.grpcsharp_channel_args_set_integer_delegate>(library);
this.grpcsharp_channel_args_destroy = GetMethodDelegate<Delegates.grpcsharp_channel_args_destroy_delegate>(library);
this.grpcsharp_ssl_credentials_create = GetMethodDelegate<Delegates.grpcsharp_ssl_credentials_create_delegate>(library);
this.grpcsharp_composite_channel_credentials_create = GetMethodDelegate<Delegates.grpcsharp_composite_channel_credentials_create_delegate>(library);
this.grpcsharp_channel_credentials_release = GetMethodDelegate<Delegates.grpcsharp_channel_credentials_release_delegate>(library);
this.grpcsharp_insecure_channel_create = GetMethodDelegate<Delegates.grpcsharp_insecure_channel_create_delegate>(library);
this.grpcsharp_secure_channel_create = GetMethodDelegate<Delegates.grpcsharp_secure_channel_create_delegate>(library);
this.grpcsharp_channel_create_call = GetMethodDelegate<Delegates.grpcsharp_channel_create_call_delegate>(library);
this.grpcsharp_channel_check_connectivity_state = GetMethodDelegate<Delegates.grpcsharp_channel_check_connectivity_state_delegate>(library);
this.grpcsharp_channel_watch_connectivity_state = GetMethodDelegate<Delegates.grpcsharp_channel_watch_connectivity_state_delegate>(library);
this.grpcsharp_channel_get_target = GetMethodDelegate<Delegates.grpcsharp_channel_get_target_delegate>(library);
this.grpcsharp_channel_destroy = GetMethodDelegate<Delegates.grpcsharp_channel_destroy_delegate>(library);
this.grpcsharp_sizeof_grpc_event = GetMethodDelegate<Delegates.grpcsharp_sizeof_grpc_event_delegate>(library);
this.grpcsharp_completion_queue_create = GetMethodDelegate<Delegates.grpcsharp_completion_queue_create_delegate>(library);
this.grpcsharp_completion_queue_shutdown = GetMethodDelegate<Delegates.grpcsharp_completion_queue_shutdown_delegate>(library);
this.grpcsharp_completion_queue_next = GetMethodDelegate<Delegates.grpcsharp_completion_queue_next_delegate>(library);
this.grpcsharp_completion_queue_pluck = GetMethodDelegate<Delegates.grpcsharp_completion_queue_pluck_delegate>(library);
this.grpcsharp_completion_queue_destroy = GetMethodDelegate<Delegates.grpcsharp_completion_queue_destroy_delegate>(library);
this.gprsharp_free = GetMethodDelegate<Delegates.gprsharp_free_delegate>(library);
this.grpcsharp_metadata_array_create = GetMethodDelegate<Delegates.grpcsharp_metadata_array_create_delegate>(library);
this.grpcsharp_metadata_array_add = GetMethodDelegate<Delegates.grpcsharp_metadata_array_add_delegate>(library);
this.grpcsharp_metadata_array_count = GetMethodDelegate<Delegates.grpcsharp_metadata_array_count_delegate>(library);
this.grpcsharp_metadata_array_get_key = GetMethodDelegate<Delegates.grpcsharp_metadata_array_get_key_delegate>(library);
this.grpcsharp_metadata_array_get_value = GetMethodDelegate<Delegates.grpcsharp_metadata_array_get_value_delegate>(library);
this.grpcsharp_metadata_array_get_value_length = GetMethodDelegate<Delegates.grpcsharp_metadata_array_get_value_length_delegate>(library);
this.grpcsharp_metadata_array_destroy_full = GetMethodDelegate<Delegates.grpcsharp_metadata_array_destroy_full_delegate>(library);
this.grpcsharp_redirect_log = GetMethodDelegate<Delegates.grpcsharp_redirect_log_delegate>(library);
this.grpcsharp_metadata_credentials_create_from_plugin = GetMethodDelegate<Delegates.grpcsharp_metadata_credentials_create_from_plugin_delegate>(library);
this.grpcsharp_metadata_credentials_notify_from_plugin = GetMethodDelegate<Delegates.grpcsharp_metadata_credentials_notify_from_plugin_delegate>(library);
this.grpcsharp_ssl_server_credentials_create = GetMethodDelegate<Delegates.grpcsharp_ssl_server_credentials_create_delegate>(library);
this.grpcsharp_server_credentials_release = GetMethodDelegate<Delegates.grpcsharp_server_credentials_release_delegate>(library);
this.grpcsharp_server_create = GetMethodDelegate<Delegates.grpcsharp_server_create_delegate>(library);
this.grpcsharp_server_add_insecure_http2_port = GetMethodDelegate<Delegates.grpcsharp_server_add_insecure_http2_port_delegate>(library);
this.grpcsharp_server_add_secure_http2_port = GetMethodDelegate<Delegates.grpcsharp_server_add_secure_http2_port_delegate>(library);
this.grpcsharp_server_start = GetMethodDelegate<Delegates.grpcsharp_server_start_delegate>(library);
this.grpcsharp_server_request_call = GetMethodDelegate<Delegates.grpcsharp_server_request_call_delegate>(library);
this.grpcsharp_server_cancel_all_calls = GetMethodDelegate<Delegates.grpcsharp_server_cancel_all_calls_delegate>(library);
this.grpcsharp_server_shutdown_and_notify_callback = GetMethodDelegate<Delegates.grpcsharp_server_shutdown_and_notify_callback_delegate>(library);
this.grpcsharp_server_destroy = GetMethodDelegate<Delegates.grpcsharp_server_destroy_delegate>(library);
this.gprsharp_now = GetMethodDelegate<Delegates.gprsharp_now_delegate>(library);
this.gprsharp_inf_future = GetMethodDelegate<Delegates.gprsharp_inf_future_delegate>(library);
this.gprsharp_inf_past = GetMethodDelegate<Delegates.gprsharp_inf_past_delegate>(library);
this.gprsharp_convert_clock_type = GetMethodDelegate<Delegates.gprsharp_convert_clock_type_delegate>(library);
this.gprsharp_sizeof_timespec = GetMethodDelegate<Delegates.gprsharp_sizeof_timespec_delegate>(library);
this.grpcsharp_test_callback = GetMethodDelegate<Delegates.grpcsharp_test_callback_delegate>(library);
this.grpcsharp_test_nop = GetMethodDelegate<Delegates.grpcsharp_test_nop_delegate>(library);
}
else
{
// Windows or fallback
this.grpcsharp_init = PInvokeMethods.grpcsharp_init;
this.grpcsharp_shutdown = PInvokeMethods.grpcsharp_shutdown;
this.grpcsharp_version_string = PInvokeMethods.grpcsharp_version_string;
this.grpcsharp_batch_context_create = PInvokeMethods.grpcsharp_batch_context_create;
this.grpcsharp_batch_context_recv_initial_metadata = PInvokeMethods.grpcsharp_batch_context_recv_initial_metadata;
this.grpcsharp_batch_context_recv_message_length = PInvokeMethods.grpcsharp_batch_context_recv_message_length;
this.grpcsharp_batch_context_recv_message_to_buffer = PInvokeMethods.grpcsharp_batch_context_recv_message_to_buffer;
this.grpcsharp_batch_context_recv_status_on_client_status = PInvokeMethods.grpcsharp_batch_context_recv_status_on_client_status;
this.grpcsharp_batch_context_recv_status_on_client_details = PInvokeMethods.grpcsharp_batch_context_recv_status_on_client_details;
this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = PInvokeMethods.grpcsharp_batch_context_recv_status_on_client_trailing_metadata;
this.grpcsharp_batch_context_server_rpc_new_call = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_call;
this.grpcsharp_batch_context_server_rpc_new_method = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_method;
this.grpcsharp_batch_context_server_rpc_new_host = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_host;
this.grpcsharp_batch_context_server_rpc_new_deadline = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_deadline;
this.grpcsharp_batch_context_server_rpc_new_request_metadata = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_request_metadata;
this.grpcsharp_batch_context_recv_close_on_server_cancelled = PInvokeMethods.grpcsharp_batch_context_recv_close_on_server_cancelled;
this.grpcsharp_batch_context_destroy = PInvokeMethods.grpcsharp_batch_context_destroy;
this.grpcsharp_composite_call_credentials_create = PInvokeMethods.grpcsharp_composite_call_credentials_create;
this.grpcsharp_call_credentials_release = PInvokeMethods.grpcsharp_call_credentials_release;
this.grpcsharp_call_cancel = PInvokeMethods.grpcsharp_call_cancel;
this.grpcsharp_call_cancel_with_status = PInvokeMethods.grpcsharp_call_cancel_with_status;
this.grpcsharp_call_start_unary = PInvokeMethods.grpcsharp_call_start_unary;
this.grpcsharp_call_start_client_streaming = PInvokeMethods.grpcsharp_call_start_client_streaming;
this.grpcsharp_call_start_server_streaming = PInvokeMethods.grpcsharp_call_start_server_streaming;
this.grpcsharp_call_start_duplex_streaming = PInvokeMethods.grpcsharp_call_start_duplex_streaming;
this.grpcsharp_call_send_message = PInvokeMethods.grpcsharp_call_send_message;
this.grpcsharp_call_send_close_from_client = PInvokeMethods.grpcsharp_call_send_close_from_client;
this.grpcsharp_call_send_status_from_server = PInvokeMethods.grpcsharp_call_send_status_from_server;
this.grpcsharp_call_recv_message = PInvokeMethods.grpcsharp_call_recv_message;
this.grpcsharp_call_recv_initial_metadata = PInvokeMethods.grpcsharp_call_recv_initial_metadata;
this.grpcsharp_call_start_serverside = PInvokeMethods.grpcsharp_call_start_serverside;
this.grpcsharp_call_send_initial_metadata = PInvokeMethods.grpcsharp_call_send_initial_metadata;
this.grpcsharp_call_set_credentials = PInvokeMethods.grpcsharp_call_set_credentials;
this.grpcsharp_call_get_peer = PInvokeMethods.grpcsharp_call_get_peer;
this.grpcsharp_call_destroy = PInvokeMethods.grpcsharp_call_destroy;
this.grpcsharp_channel_args_create = PInvokeMethods.grpcsharp_channel_args_create;
this.grpcsharp_channel_args_set_string = PInvokeMethods.grpcsharp_channel_args_set_string;
this.grpcsharp_channel_args_set_integer = PInvokeMethods.grpcsharp_channel_args_set_integer;
this.grpcsharp_channel_args_destroy = PInvokeMethods.grpcsharp_channel_args_destroy;
this.grpcsharp_ssl_credentials_create = PInvokeMethods.grpcsharp_ssl_credentials_create;
this.grpcsharp_composite_channel_credentials_create = PInvokeMethods.grpcsharp_composite_channel_credentials_create;
this.grpcsharp_channel_credentials_release = PInvokeMethods.grpcsharp_channel_credentials_release;
this.grpcsharp_insecure_channel_create = PInvokeMethods.grpcsharp_insecure_channel_create;
this.grpcsharp_secure_channel_create = PInvokeMethods.grpcsharp_secure_channel_create;
this.grpcsharp_channel_create_call = PInvokeMethods.grpcsharp_channel_create_call;
this.grpcsharp_channel_check_connectivity_state = PInvokeMethods.grpcsharp_channel_check_connectivity_state;
this.grpcsharp_channel_watch_connectivity_state = PInvokeMethods.grpcsharp_channel_watch_connectivity_state;
this.grpcsharp_channel_get_target = PInvokeMethods.grpcsharp_channel_get_target;
this.grpcsharp_channel_destroy = PInvokeMethods.grpcsharp_channel_destroy;
this.grpcsharp_sizeof_grpc_event = PInvokeMethods.grpcsharp_sizeof_grpc_event;
this.grpcsharp_completion_queue_create = PInvokeMethods.grpcsharp_completion_queue_create;
this.grpcsharp_completion_queue_shutdown = PInvokeMethods.grpcsharp_completion_queue_shutdown;
this.grpcsharp_completion_queue_next = PInvokeMethods.grpcsharp_completion_queue_next;
this.grpcsharp_completion_queue_pluck = PInvokeMethods.grpcsharp_completion_queue_pluck;
this.grpcsharp_completion_queue_destroy = PInvokeMethods.grpcsharp_completion_queue_destroy;
this.gprsharp_free = PInvokeMethods.gprsharp_free;
this.grpcsharp_metadata_array_create = PInvokeMethods.grpcsharp_metadata_array_create;
this.grpcsharp_metadata_array_add = PInvokeMethods.grpcsharp_metadata_array_add;
this.grpcsharp_metadata_array_count = PInvokeMethods.grpcsharp_metadata_array_count;
this.grpcsharp_metadata_array_get_key = PInvokeMethods.grpcsharp_metadata_array_get_key;
this.grpcsharp_metadata_array_get_value = PInvokeMethods.grpcsharp_metadata_array_get_value;
this.grpcsharp_metadata_array_get_value_length = PInvokeMethods.grpcsharp_metadata_array_get_value_length;
this.grpcsharp_metadata_array_destroy_full = PInvokeMethods.grpcsharp_metadata_array_destroy_full;
this.grpcsharp_redirect_log = PInvokeMethods.grpcsharp_redirect_log;
this.grpcsharp_metadata_credentials_create_from_plugin = PInvokeMethods.grpcsharp_metadata_credentials_create_from_plugin;
this.grpcsharp_metadata_credentials_notify_from_plugin = PInvokeMethods.grpcsharp_metadata_credentials_notify_from_plugin;
this.grpcsharp_ssl_server_credentials_create = PInvokeMethods.grpcsharp_ssl_server_credentials_create;
this.grpcsharp_server_credentials_release = PInvokeMethods.grpcsharp_server_credentials_release;
this.grpcsharp_server_create = PInvokeMethods.grpcsharp_server_create;
this.grpcsharp_server_add_insecure_http2_port = PInvokeMethods.grpcsharp_server_add_insecure_http2_port;
this.grpcsharp_server_add_secure_http2_port = PInvokeMethods.grpcsharp_server_add_secure_http2_port;
this.grpcsharp_server_start = PInvokeMethods.grpcsharp_server_start;
this.grpcsharp_server_request_call = PInvokeMethods.grpcsharp_server_request_call;
this.grpcsharp_server_cancel_all_calls = PInvokeMethods.grpcsharp_server_cancel_all_calls;
this.grpcsharp_server_shutdown_and_notify_callback = PInvokeMethods.grpcsharp_server_shutdown_and_notify_callback;
this.grpcsharp_server_destroy = PInvokeMethods.grpcsharp_server_destroy;
this.gprsharp_now = PInvokeMethods.gprsharp_now;
this.gprsharp_inf_future = PInvokeMethods.gprsharp_inf_future;
this.gprsharp_inf_past = PInvokeMethods.gprsharp_inf_past;
this.gprsharp_convert_clock_type = PInvokeMethods.gprsharp_convert_clock_type;
this.gprsharp_sizeof_timespec = PInvokeMethods.gprsharp_sizeof_timespec;
this.grpcsharp_test_callback = PInvokeMethods.grpcsharp_test_callback;
this.grpcsharp_test_nop = PInvokeMethods.grpcsharp_test_nop;
}
}
/// <summary>
/// Gets singleton instance of this class.
/// </summary>
public static NativeMethods Get()
{
return NativeExtension.Get().NativeMethods;
}
static T GetMethodDelegate<T>(UnmanagedLibrary library)
where T : class
{
var methodName = RemoveStringSuffix(typeof(T).Name, "_delegate");
return library.GetNativeMethodDelegate<T>(methodName);
}
static string RemoveStringSuffix(string str, string toRemove)
{
if (!str.EndsWith(toRemove))
{
return str;
}
return str.Substring(0, str.Length - toRemove.Length);
}
/// <summary>
/// Delegate types for all published native methods. Declared under inner class to prevent scope pollution.
/// </summary>
public class Delegates
{
public delegate void grpcsharp_init_delegate();
public delegate void grpcsharp_shutdown_delegate();
public delegate IntPtr grpcsharp_version_string_delegate(); // returns not-owned const char*
public delegate BatchContextSafeHandle grpcsharp_batch_context_create_delegate();
public delegate IntPtr grpcsharp_batch_context_recv_initial_metadata_delegate(BatchContextSafeHandle ctx);
public delegate IntPtr grpcsharp_batch_context_recv_message_length_delegate(BatchContextSafeHandle ctx);
public delegate void grpcsharp_batch_context_recv_message_to_buffer_delegate(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen);
public delegate StatusCode grpcsharp_batch_context_recv_status_on_client_status_delegate(BatchContextSafeHandle ctx);
public delegate IntPtr grpcsharp_batch_context_recv_status_on_client_details_delegate(BatchContextSafeHandle ctx); // returns const char*
public delegate IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata_delegate(BatchContextSafeHandle ctx);
public delegate CallSafeHandle grpcsharp_batch_context_server_rpc_new_call_delegate(BatchContextSafeHandle ctx);
public delegate IntPtr grpcsharp_batch_context_server_rpc_new_method_delegate(BatchContextSafeHandle ctx); // returns const char*
public delegate IntPtr grpcsharp_batch_context_server_rpc_new_host_delegate(BatchContextSafeHandle ctx); // returns const char*
public delegate Timespec grpcsharp_batch_context_server_rpc_new_deadline_delegate(BatchContextSafeHandle ctx);
public delegate IntPtr grpcsharp_batch_context_server_rpc_new_request_metadata_delegate(BatchContextSafeHandle ctx);
public delegate int grpcsharp_batch_context_recv_close_on_server_cancelled_delegate(BatchContextSafeHandle ctx);
public delegate void grpcsharp_batch_context_destroy_delegate(IntPtr ctx);
public delegate CallCredentialsSafeHandle grpcsharp_composite_call_credentials_create_delegate(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2);
public delegate void grpcsharp_call_credentials_release_delegate(IntPtr credentials);
public delegate GRPCCallError grpcsharp_call_cancel_delegate(CallSafeHandle call);
public delegate GRPCCallError grpcsharp_call_cancel_with_status_delegate(CallSafeHandle call, StatusCode status, string description);
public delegate GRPCCallError grpcsharp_call_start_unary_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
public delegate GRPCCallError grpcsharp_call_start_client_streaming_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
public delegate GRPCCallError grpcsharp_call_start_server_streaming_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len,
MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
public delegate GRPCCallError grpcsharp_call_start_duplex_streaming_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
public delegate GRPCCallError grpcsharp_call_send_message_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, WriteFlags writeFlags, bool sendEmptyInitialMetadata);
public delegate GRPCCallError grpcsharp_call_send_close_from_client_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx);
public delegate GRPCCallError grpcsharp_call_send_status_from_server_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx, StatusCode statusCode, string statusMessage, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata);
public delegate GRPCCallError grpcsharp_call_recv_message_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx);
public delegate GRPCCallError grpcsharp_call_recv_initial_metadata_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx);
public delegate GRPCCallError grpcsharp_call_start_serverside_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx);
public delegate GRPCCallError grpcsharp_call_send_initial_metadata_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
public delegate GRPCCallError grpcsharp_call_set_credentials_delegate(CallSafeHandle call, CallCredentialsSafeHandle credentials);
public delegate CStringSafeHandle grpcsharp_call_get_peer_delegate(CallSafeHandle call);
public delegate void grpcsharp_call_destroy_delegate(IntPtr call);
public delegate ChannelArgsSafeHandle grpcsharp_channel_args_create_delegate(UIntPtr numArgs);
public delegate void grpcsharp_channel_args_set_string_delegate(ChannelArgsSafeHandle args, UIntPtr index, string key, string value);
public delegate void grpcsharp_channel_args_set_integer_delegate(ChannelArgsSafeHandle args, UIntPtr index, string key, int value);
public delegate void grpcsharp_channel_args_destroy_delegate(IntPtr args);
public delegate ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create_delegate(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey);
public delegate ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create_delegate(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds);
public delegate void grpcsharp_channel_credentials_release_delegate(IntPtr credentials);
public delegate ChannelSafeHandle grpcsharp_insecure_channel_create_delegate(string target, ChannelArgsSafeHandle channelArgs);
public delegate ChannelSafeHandle grpcsharp_secure_channel_create_delegate(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs);
public delegate CallSafeHandle grpcsharp_channel_create_call_delegate(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
public delegate ChannelState grpcsharp_channel_check_connectivity_state_delegate(ChannelSafeHandle channel, int tryToConnect);
public delegate void grpcsharp_channel_watch_connectivity_state_delegate(ChannelSafeHandle channel, ChannelState lastObservedState,
Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
public delegate CStringSafeHandle grpcsharp_channel_get_target_delegate(ChannelSafeHandle call);
public delegate void grpcsharp_channel_destroy_delegate(IntPtr channel);
public delegate int grpcsharp_sizeof_grpc_event_delegate();
public delegate CompletionQueueSafeHandle grpcsharp_completion_queue_create_delegate();
public delegate void grpcsharp_completion_queue_shutdown_delegate(CompletionQueueSafeHandle cq);
public delegate CompletionQueueEvent grpcsharp_completion_queue_next_delegate(CompletionQueueSafeHandle cq);
public delegate CompletionQueueEvent grpcsharp_completion_queue_pluck_delegate(CompletionQueueSafeHandle cq, IntPtr tag);
public delegate void grpcsharp_completion_queue_destroy_delegate(IntPtr cq);
public delegate void gprsharp_free_delegate(IntPtr ptr);
public delegate MetadataArraySafeHandle grpcsharp_metadata_array_create_delegate(UIntPtr capacity);
public delegate void grpcsharp_metadata_array_add_delegate(MetadataArraySafeHandle array, string key, byte[] value, UIntPtr valueLength);
public delegate UIntPtr grpcsharp_metadata_array_count_delegate(IntPtr metadataArray);
public delegate IntPtr grpcsharp_metadata_array_get_key_delegate(IntPtr metadataArray, UIntPtr index);
public delegate IntPtr grpcsharp_metadata_array_get_value_delegate(IntPtr metadataArray, UIntPtr index);
public delegate UIntPtr grpcsharp_metadata_array_get_value_length_delegate(IntPtr metadataArray, UIntPtr index);
public delegate void grpcsharp_metadata_array_destroy_full_delegate(IntPtr array);
public delegate void grpcsharp_redirect_log_delegate(GprLogDelegate callback);
public delegate CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin_delegate(NativeMetadataInterceptor interceptor);
public delegate void grpcsharp_metadata_credentials_notify_from_plugin_delegate(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails);
public delegate ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create_delegate(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, bool forceClientAuth);
public delegate void grpcsharp_server_credentials_release_delegate(IntPtr credentials);
public delegate ServerSafeHandle grpcsharp_server_create_delegate(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args);
public delegate int grpcsharp_server_add_insecure_http2_port_delegate(ServerSafeHandle server, string addr);
public delegate int grpcsharp_server_add_secure_http2_port_delegate(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds);
public delegate void grpcsharp_server_start_delegate(ServerSafeHandle server);
public delegate GRPCCallError grpcsharp_server_request_call_delegate(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
public delegate void grpcsharp_server_cancel_all_calls_delegate(ServerSafeHandle server);
public delegate void grpcsharp_server_shutdown_and_notify_callback_delegate(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
public delegate void grpcsharp_server_destroy_delegate(IntPtr server);
public delegate Timespec gprsharp_now_delegate(GPRClockType clockType);
public delegate Timespec gprsharp_inf_future_delegate(GPRClockType clockType);
public delegate Timespec gprsharp_inf_past_delegate(GPRClockType clockType);
public delegate Timespec gprsharp_convert_clock_type_delegate(Timespec t, GPRClockType targetClock);
public delegate int gprsharp_sizeof_timespec_delegate();
public delegate GRPCCallError grpcsharp_test_callback_delegate([MarshalAs(UnmanagedType.FunctionPtr)] OpCompletionDelegate callback);
public delegate IntPtr grpcsharp_test_nop_delegate(IntPtr ptr);
}
/// <summary>
/// Default PInvoke bindings for native methods that are used on Windows.
/// Alternatively, they can also be used as a fallback on Mono
/// (if libgrpc_csharp_ext is installed on your system, or is made accessible through e.g. LD_LIBRARY_PATH environment variable
/// or using Mono's dllMap feature).
/// </summary>
private class PInvokeMethods
{
// Environment
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_init();
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_shutdown();
[DllImport("grpc_csharp_ext.dll")]
public static extern IntPtr grpcsharp_version_string(); // returns not-owned const char*
// BatchContextSafeHandle
[DllImport("grpc_csharp_ext.dll")]
public static extern BatchContextSafeHandle grpcsharp_batch_context_create();
[DllImport("grpc_csharp_ext.dll")]
public static extern IntPtr grpcsharp_batch_context_recv_initial_metadata(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_batch_context_recv_message_to_buffer(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen);
[DllImport("grpc_csharp_ext.dll")]
public static extern StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern IntPtr grpcsharp_batch_context_recv_status_on_client_details(BatchContextSafeHandle ctx); // returns const char*
[DllImport("grpc_csharp_ext.dll")]
public static extern IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern CallSafeHandle grpcsharp_batch_context_server_rpc_new_call(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern IntPtr grpcsharp_batch_context_server_rpc_new_method(BatchContextSafeHandle ctx); // returns const char*
[DllImport("grpc_csharp_ext.dll")]
public static extern IntPtr grpcsharp_batch_context_server_rpc_new_host(BatchContextSafeHandle ctx); // returns const char*
[DllImport("grpc_csharp_ext.dll")]
public static extern Timespec grpcsharp_batch_context_server_rpc_new_deadline(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern IntPtr grpcsharp_batch_context_server_rpc_new_request_metadata(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern int grpcsharp_batch_context_recv_close_on_server_cancelled(BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_batch_context_destroy(IntPtr ctx);
// CallCredentialsSafeHandle
[DllImport("grpc_csharp_ext.dll")]
public static extern CallCredentialsSafeHandle grpcsharp_composite_call_credentials_create(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_call_credentials_release(IntPtr credentials);
// CallSafeHandle
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_cancel(CallSafeHandle call);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_start_unary(CallSafeHandle call,
BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_start_client_streaming(CallSafeHandle call,
BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_start_server_streaming(CallSafeHandle call,
BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len,
MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_start_duplex_streaming(CallSafeHandle call,
BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_send_message(CallSafeHandle call,
BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, WriteFlags writeFlags, bool sendEmptyInitialMetadata);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_send_close_from_client(CallSafeHandle call,
BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_send_status_from_server(CallSafeHandle call,
BatchContextSafeHandle ctx, StatusCode statusCode, string statusMessage, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_recv_message(CallSafeHandle call,
BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_recv_initial_metadata(CallSafeHandle call,
BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_start_serverside(CallSafeHandle call,
BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_send_initial_metadata(CallSafeHandle call,
BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_set_credentials(CallSafeHandle call, CallCredentialsSafeHandle credentials);
[DllImport("grpc_csharp_ext.dll")]
public static extern CStringSafeHandle grpcsharp_call_get_peer(CallSafeHandle call);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_call_destroy(IntPtr call);
// ChannelArgsSafeHandle
[DllImport("grpc_csharp_ext.dll")]
public static extern ChannelArgsSafeHandle grpcsharp_channel_args_create(UIntPtr numArgs);
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
public static extern void grpcsharp_channel_args_set_string(ChannelArgsSafeHandle args, UIntPtr index, string key, string value);
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
public static extern void grpcsharp_channel_args_set_integer(ChannelArgsSafeHandle args, UIntPtr index, string key, int value);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_channel_args_destroy(IntPtr args);
// ChannelCredentialsSafeHandle
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey);
[DllImport("grpc_csharp_ext.dll")]
public static extern ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_channel_credentials_release(IntPtr credentials);
// ChannelSafeHandle
[DllImport("grpc_csharp_ext.dll")]
public static extern ChannelSafeHandle grpcsharp_insecure_channel_create(string target, ChannelArgsSafeHandle channelArgs);
[DllImport("grpc_csharp_ext.dll")]
public static extern ChannelSafeHandle grpcsharp_secure_channel_create(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs);
[DllImport("grpc_csharp_ext.dll")]
public static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
[DllImport("grpc_csharp_ext.dll")]
public static extern ChannelState grpcsharp_channel_check_connectivity_state(ChannelSafeHandle channel, int tryToConnect);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_channel_watch_connectivity_state(ChannelSafeHandle channel, ChannelState lastObservedState,
Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern CStringSafeHandle grpcsharp_channel_get_target(ChannelSafeHandle call);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_channel_destroy(IntPtr channel);
// CompletionQueueEvent
[DllImport("grpc_csharp_ext.dll")]
public static extern int grpcsharp_sizeof_grpc_event();
// CompletionQueueSafeHandle
[DllImport("grpc_csharp_ext.dll")]
public static extern CompletionQueueSafeHandle grpcsharp_completion_queue_create();
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq);
[DllImport("grpc_csharp_ext.dll")]
public static extern CompletionQueueEvent grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq);
[DllImport("grpc_csharp_ext.dll")]
public static extern CompletionQueueEvent grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_completion_queue_destroy(IntPtr cq);
// CStringSafeHandle
[DllImport("grpc_csharp_ext.dll")]
public static extern void gprsharp_free(IntPtr ptr);
// MetadataArraySafeHandle
[DllImport("grpc_csharp_ext.dll")]
public static extern MetadataArraySafeHandle grpcsharp_metadata_array_create(UIntPtr capacity);
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
public static extern void grpcsharp_metadata_array_add(MetadataArraySafeHandle array, string key, byte[] value, UIntPtr valueLength);
[DllImport("grpc_csharp_ext.dll")]
public static extern UIntPtr grpcsharp_metadata_array_count(IntPtr metadataArray);
[DllImport("grpc_csharp_ext.dll")]
public static extern IntPtr grpcsharp_metadata_array_get_key(IntPtr metadataArray, UIntPtr index);
[DllImport("grpc_csharp_ext.dll")]
public static extern IntPtr grpcsharp_metadata_array_get_value(IntPtr metadataArray, UIntPtr index);
[DllImport("grpc_csharp_ext.dll")]
public static extern UIntPtr grpcsharp_metadata_array_get_value_length(IntPtr metadataArray, UIntPtr index);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_metadata_array_destroy_full(IntPtr array);
// NativeLogRedirector
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_redirect_log(GprLogDelegate callback);
// NativeMetadataCredentialsPlugin
[DllImport("grpc_csharp_ext.dll")]
public static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor);
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
public static extern void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails);
// ServerCredentialsSafeHandle
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
public static extern ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, bool forceClientAuth);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_server_credentials_release(IntPtr credentials);
// ServerSafeHandle
[DllImport("grpc_csharp_ext.dll")]
public static extern ServerSafeHandle grpcsharp_server_create(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args);
[DllImport("grpc_csharp_ext.dll")]
public static extern int grpcsharp_server_add_insecure_http2_port(ServerSafeHandle server, string addr);
[DllImport("grpc_csharp_ext.dll")]
public static extern int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_server_start(ServerSafeHandle server);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_server_cancel_all_calls(ServerSafeHandle server);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_server_shutdown_and_notify_callback(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
public static extern void grpcsharp_server_destroy(IntPtr server);
// Timespec
[DllImport("grpc_csharp_ext.dll")]
public static extern Timespec gprsharp_now(GPRClockType clockType);
[DllImport("grpc_csharp_ext.dll")]
public static extern Timespec gprsharp_inf_future(GPRClockType clockType);
[DllImport("grpc_csharp_ext.dll")]
public static extern Timespec gprsharp_inf_past(GPRClockType clockType);
[DllImport("grpc_csharp_ext.dll")]
public static extern Timespec gprsharp_convert_clock_type(Timespec t, GPRClockType targetClock);
[DllImport("grpc_csharp_ext.dll")]
public static extern int gprsharp_sizeof_timespec();
// Testing
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_test_callback([MarshalAs(UnmanagedType.FunctionPtr)] OpCompletionDelegate callback);
[DllImport("grpc_csharp_ext.dll")]
public static extern IntPtr grpcsharp_test_nop(IntPtr ptr);
}
}
}

@ -0,0 +1,110 @@
#region Copyright notice and license
// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
namespace Grpc.Core.Internal
{
/// <summary>
/// Utility methods for detecting platform and architecture.
/// </summary>
internal static class PlatformApis
{
static readonly bool isLinux;
static readonly bool isMacOSX;
static readonly bool isWindows;
static PlatformApis()
{
var platform = Environment.OSVersion.Platform;
// PlatformID.MacOSX is never returned, commonly used trick is to identify Mac is by using uname.
isMacOSX = (platform == PlatformID.Unix && GetUname() == "Darwin");
isLinux = (platform == PlatformID.Unix && !isMacOSX);
isWindows = (platform == PlatformID.Win32NT || platform == PlatformID.Win32S || platform == PlatformID.Win32Windows);
}
public static bool IsLinux
{
get { return isLinux; }
}
public static bool IsMacOSX
{
get { return isMacOSX; }
}
public static bool IsWindows
{
get { return isWindows; }
}
public static bool Is64Bit
{
get { return IntPtr.Size == 8; }
}
[DllImport("libc")]
static extern int uname(IntPtr buf);
static string GetUname()
{
var buffer = Marshal.AllocHGlobal(8192);
try
{
if (uname(buffer) == 0)
{
return Marshal.PtrToStringAnsi(buffer);
}
return string.Empty;
}
catch
{
return string.Empty;
}
finally
{
if (buffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(buffer);
}
}
}
}
}

@ -1,5 +1,5 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -41,11 +41,7 @@ namespace Grpc.Core.Internal
/// </summary> /// </summary>
internal class ServerCredentialsSafeHandle : SafeHandleZeroIsInvalid internal class ServerCredentialsSafeHandle : SafeHandleZeroIsInvalid
{ {
[DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] static readonly NativeMethods Native = NativeMethods.Get();
static extern ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, bool forceClientAuth);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_server_credentials_release(IntPtr credentials);
private ServerCredentialsSafeHandle() private ServerCredentialsSafeHandle()
{ {
@ -54,7 +50,7 @@ namespace Grpc.Core.Internal
public static ServerCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, bool forceClientAuth) public static ServerCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, bool forceClientAuth)
{ {
Preconditions.CheckArgument(keyCertPairCertChainArray.Length == keyCertPairPrivateKeyArray.Length); Preconditions.CheckArgument(keyCertPairCertChainArray.Length == keyCertPairPrivateKeyArray.Length);
return grpcsharp_ssl_server_credentials_create(pemRootCerts, return Native.grpcsharp_ssl_server_credentials_create(pemRootCerts,
keyCertPairCertChainArray, keyCertPairPrivateKeyArray, keyCertPairCertChainArray, keyCertPairPrivateKeyArray,
new UIntPtr((ulong)keyCertPairCertChainArray.Length), new UIntPtr((ulong)keyCertPairCertChainArray.Length),
forceClientAuth); forceClientAuth);
@ -62,7 +58,7 @@ namespace Grpc.Core.Internal
protected override bool ReleaseHandle() protected override bool ReleaseHandle()
{ {
grpcsharp_server_credentials_release(handle); Native.grpcsharp_server_credentials_release(handle);
return true; return true;
} }
} }

@ -1,6 +1,6 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -44,29 +44,7 @@ namespace Grpc.Core.Internal
/// </summary> /// </summary>
internal sealed class ServerSafeHandle : SafeHandleZeroIsInvalid internal sealed class ServerSafeHandle : SafeHandleZeroIsInvalid
{ {
[DllImport("grpc_csharp_ext.dll")] static readonly NativeMethods Native = NativeMethods.Get();
static extern ServerSafeHandle grpcsharp_server_create(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args);
[DllImport("grpc_csharp_ext.dll")]
static extern int grpcsharp_server_add_insecure_http2_port(ServerSafeHandle server, string addr);
[DllImport("grpc_csharp_ext.dll")]
static extern int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_server_start(ServerSafeHandle server);
[DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_server_cancel_all_calls(ServerSafeHandle server);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_server_shutdown_and_notify_callback(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_server_destroy(IntPtr server);
private ServerSafeHandle() private ServerSafeHandle()
{ {
@ -77,41 +55,41 @@ namespace Grpc.Core.Internal
// Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle. // Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle.
// Doing so would make object finalizer crash if we end up abandoning the handle. // Doing so would make object finalizer crash if we end up abandoning the handle.
GrpcEnvironment.GrpcNativeInit(); GrpcEnvironment.GrpcNativeInit();
return grpcsharp_server_create(cq, args); return Native.grpcsharp_server_create(cq, args);
} }
public int AddInsecurePort(string addr) public int AddInsecurePort(string addr)
{ {
return grpcsharp_server_add_insecure_http2_port(this, addr); return Native.grpcsharp_server_add_insecure_http2_port(this, addr);
} }
public int AddSecurePort(string addr, ServerCredentialsSafeHandle credentials) public int AddSecurePort(string addr, ServerCredentialsSafeHandle credentials)
{ {
return grpcsharp_server_add_secure_http2_port(this, addr, credentials); return Native.grpcsharp_server_add_secure_http2_port(this, addr, credentials);
} }
public void Start() public void Start()
{ {
grpcsharp_server_start(this); Native.grpcsharp_server_start(this);
} }
public void ShutdownAndNotify(BatchCompletionDelegate callback, GrpcEnvironment environment) public void ShutdownAndNotify(BatchCompletionDelegate callback, GrpcEnvironment environment)
{ {
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
environment.CompletionRegistry.RegisterBatchCompletion(ctx, callback); environment.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
grpcsharp_server_shutdown_and_notify_callback(this, environment.CompletionQueue, ctx); Native.grpcsharp_server_shutdown_and_notify_callback(this, environment.CompletionQueue, ctx);
} }
public void RequestCall(BatchCompletionDelegate callback, GrpcEnvironment environment) public void RequestCall(BatchCompletionDelegate callback, GrpcEnvironment environment)
{ {
var ctx = BatchContextSafeHandle.Create(); var ctx = BatchContextSafeHandle.Create();
environment.CompletionRegistry.RegisterBatchCompletion(ctx, callback); environment.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
grpcsharp_server_request_call(this, environment.CompletionQueue, ctx).CheckOk(); Native.grpcsharp_server_request_call(this, environment.CompletionQueue, ctx).CheckOk();
} }
protected override bool ReleaseHandle() protected override bool ReleaseHandle()
{ {
grpcsharp_server_destroy(handle); Native.grpcsharp_server_destroy(handle);
GrpcEnvironment.GrpcNativeShutdown(); GrpcEnvironment.GrpcNativeShutdown();
return true; return true;
} }
@ -119,7 +97,7 @@ namespace Grpc.Core.Internal
// Only to be called after ShutdownAndNotify. // Only to be called after ShutdownAndNotify.
public void CancelAllCalls() public void CancelAllCalls()
{ {
grpcsharp_server_cancel_all_calls(this); Native.grpcsharp_server_cancel_all_calls(this);
} }
} }
} }

@ -1,5 +1,5 @@
#region Copyright notice and license #region Copyright notice and license
// Copyright 2015, Google Inc. // Copyright 2015-2016, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -46,23 +46,9 @@ namespace Grpc.Core.Internal
const long NanosPerTick = 100; const long NanosPerTick = 100;
const long TicksPerSecond = NanosPerSecond / NanosPerTick; const long TicksPerSecond = NanosPerSecond / NanosPerTick;
static readonly NativeMethods Native = NativeMethods.Get();
static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
[DllImport("grpc_csharp_ext.dll")]
static extern Timespec gprsharp_now(GPRClockType clockType);
[DllImport("grpc_csharp_ext.dll")]
static extern Timespec gprsharp_inf_future(GPRClockType clockType);
[DllImport("grpc_csharp_ext.dll")]
static extern Timespec gprsharp_inf_past(GPRClockType clockType);
[DllImport("grpc_csharp_ext.dll")]
static extern Timespec gprsharp_convert_clock_type(Timespec t, GPRClockType targetClock);
[DllImport("grpc_csharp_ext.dll")]
static extern int gprsharp_sizeof_timespec();
public Timespec(long tv_sec, int tv_nsec) : this(tv_sec, tv_nsec, GPRClockType.Realtime) public Timespec(long tv_sec, int tv_nsec) : this(tv_sec, tv_nsec, GPRClockType.Realtime)
{ {
} }
@ -85,7 +71,7 @@ namespace Grpc.Core.Internal
{ {
get get
{ {
return gprsharp_inf_future(GPRClockType.Realtime); return Native.gprsharp_inf_future(GPRClockType.Realtime);
} }
} }
@ -96,7 +82,7 @@ namespace Grpc.Core.Internal
{ {
get get
{ {
return gprsharp_inf_past(GPRClockType.Realtime); return Native.gprsharp_inf_past(GPRClockType.Realtime);
} }
} }
@ -107,7 +93,7 @@ namespace Grpc.Core.Internal
{ {
get get
{ {
return gprsharp_now(GPRClockType.Realtime); return Native.gprsharp_now(GPRClockType.Realtime);
} }
} }
@ -138,7 +124,7 @@ namespace Grpc.Core.Internal
/// </summary> /// </summary>
public Timespec ToClockType(GPRClockType targetClock) public Timespec ToClockType(GPRClockType targetClock)
{ {
return gprsharp_convert_clock_type(this, targetClock); return Native.gprsharp_convert_clock_type(this, targetClock);
} }
/// <summary> /// <summary>
@ -241,7 +227,7 @@ namespace Grpc.Core.Internal
{ {
get get
{ {
return gprsharp_now(GPRClockType.Precise); return Native.gprsharp_now(GPRClockType.Precise);
} }
} }
@ -249,7 +235,7 @@ namespace Grpc.Core.Internal
{ {
get get
{ {
return gprsharp_sizeof_timespec(); return Native.gprsharp_sizeof_timespec();
} }
} }
} }

@ -0,0 +1,158 @@
#region Copyright notice and license
// Copyright 2015-2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using Grpc.Core.Logging;
using Grpc.Core.Utils;
namespace Grpc.Core.Internal
{
/// <summary>
/// Represents a dynamically loaded unmanaged library in a (partially) platform independent manner.
/// An important difference in library loading semantics is that on Windows, once we load a dynamic library using LoadLibrary,
/// that library becomes instantly available for <c>DllImport</c> P/Invoke calls referring to the same library name.
/// On Unix systems, dlopen has somewhat different semantics, so we need to use dlsym and <c>Marshal.GetDelegateForFunctionPointer</c>
/// to obtain delegates to native methods.
/// See http://stackoverflow.com/questions/13461989/p-invoke-to-dynamically-loaded-library-on-mono.
/// </summary>
internal class UnmanagedLibrary
{
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<UnmanagedLibrary>();
// flags for dlopen
const int RTLD_LAZY = 1;
const int RTLD_GLOBAL = 8;
readonly string libraryPath;
readonly IntPtr handle;
public UnmanagedLibrary(string libraryPath)
{
this.libraryPath = Preconditions.CheckNotNull(libraryPath);
if (!File.Exists(this.libraryPath))
{
throw new FileNotFoundException("Error loading native library. File does not exist.", this.libraryPath);
}
Logger.Debug("Attempting to load native library \"{0}\"", this.libraryPath);
this.handle = PlatformSpecificLoadLibrary(this.libraryPath);
if (this.handle == IntPtr.Zero)
{
throw new IOException(string.Format("Error loading native library \"{0}\"", this.libraryPath));
}
}
/// <summary>
/// Loads symbol in a platform specific way.
/// </summary>
/// <param name="symbolName"></param>
/// <returns></returns>
public IntPtr LoadSymbol(string symbolName)
{
if (PlatformApis.IsLinux)
{
return Linux.dlsym(this.handle, symbolName);
}
if (PlatformApis.IsMacOSX)
{
return MacOSX.dlsym(this.handle, symbolName);
}
throw new InvalidOperationException("Unsupported platform.");
}
public T GetNativeMethodDelegate<T>(string methodName)
where T : class
{
var ptr = LoadSymbol(methodName);
if (ptr == IntPtr.Zero)
{
throw new MissingMethodException(string.Format("The native method \"{0}\" does not exist", methodName));
}
return Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;
}
/// <summary>
/// Loads library in a platform specific way.
/// </summary>
private static IntPtr PlatformSpecificLoadLibrary(string libraryPath)
{
if (PlatformApis.IsWindows)
{
return Windows.LoadLibrary(libraryPath);
}
if (PlatformApis.IsLinux)
{
return Linux.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
}
if (PlatformApis.IsMacOSX)
{
return MacOSX.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
}
throw new InvalidOperationException("Unsupported platform.");
}
private static class Windows
{
[DllImport("kernel32.dll")]
internal static extern IntPtr LoadLibrary(string filename);
}
private static class Linux
{
[DllImport("libdl.so")]
internal static extern IntPtr dlopen(string filename, int flags);
[DllImport("libdl.so")]
internal static extern IntPtr dlsym(IntPtr handle, string symbol);
}
private static class MacOSX
{
[DllImport("libSystem.dylib")]
internal static extern IntPtr dlopen(string filename, int flags);
[DllImport("libSystem.dylib")]
internal static extern IntPtr dlsym(IntPtr handle, string symbol);
}
}
}

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Content Include="..\..\..\libs\$(NativeDependenciesConfigurationUnix)\libgrpc_csharp_ext.so">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>nativelibs\linux_x64\libgrpc_csharp_ext.so</Link>
</Content>
</ItemGroup>
</Project>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Content Include="..\..\..\libs\$(NativeDependenciesConfigurationUnix)\libgrpc_csharp_ext.dylib">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>nativelibs\macosx_x86\libgrpc_csharp_ext.dylib</Link>
</Content>
</ItemGroup>
</Project>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Content Include="..\..\..\vsprojects\$(NativeDependenciesConfiguration)\grpc_csharp_ext.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Link>nativelibs\windows_x86\grpc_csharp_ext.dll</Link>
</Content>
</ItemGroup>
</Project>

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(NativeDependenciesConfiguration)' == '' ">
<NativeDependenciesConfiguration Condition=" '$(Configuration)' == 'Debug' ">Debug</NativeDependenciesConfiguration>
<NativeDependenciesConfiguration Condition=" '$(Configuration)' == 'Release' ">Release</NativeDependenciesConfiguration>
<NativeDependenciesConfiguration Condition=" '$(Configuration)' == 'ReleaseSigned' ">Release</NativeDependenciesConfiguration>
</PropertyGroup>
<PropertyGroup Condition=" '$(NativeDependenciesConfigurationUnix)' == '' ">
<NativeDependenciesConfigurationUnix Condition=" '$(Configuration)' == 'Debug' ">dbg</NativeDependenciesConfigurationUnix>
<NativeDependenciesConfigurationUnix Condition=" '$(Configuration)' == 'Release' ">opt</NativeDependenciesConfigurationUnix>
<NativeDependenciesConfigurationUnix Condition=" '$(Configuration)' == 'ReleaseSigned' ">opt</NativeDependenciesConfigurationUnix>
</PropertyGroup>
<!-- Autodetect platform -->
<PropertyGroup Condition=" '$(OS)' != 'Unix' ">
<NativeDepsPlatform>Windows</NativeDepsPlatform>
</PropertyGroup>
<PropertyGroup Condition=" '$(OS)' == 'Unix' And Exists('/Applications') And Exists('/Library') And Exists('/System') ">
<NativeDepsPlatform>Mac</NativeDepsPlatform>
</PropertyGroup>
<PropertyGroup Condition=" '$(OS)' == 'Unix' And '$(NativeDepsPlatform)' == '' ">
<NativeDepsPlatform>Linux</NativeDepsPlatform>
</PropertyGroup>
<Import Project="NativeDeps.$(NativeDepsPlatform).targets" />
</Project>

@ -1,6 +1,9 @@
PHP_ARG_ENABLE(grpc, whether to enable grpc support, PHP_ARG_ENABLE(grpc, whether to enable grpc support,
[ --enable-grpc Enable grpc support]) [ --enable-grpc Enable grpc support])
PHP_ARG_ENABLE(coverage, whether to include code coverage symbols,
[ --enable-coverage Enable coverage support], no, no)
if test "$PHP_GRPC" != "no"; then if test "$PHP_GRPC" != "no"; then
dnl Write more examples of tests here... dnl Write more examples of tests here...
@ -75,3 +78,66 @@ if test "$PHP_GRPC" != "no"; then
channel_credentials.c completion_queue.c timeval.c server.c \ channel_credentials.c completion_queue.c timeval.c server.c \
server_credentials.c php_grpc.c, $ext_shared, , -Wall -Werror -std=c11) server_credentials.c php_grpc.c, $ext_shared, , -Wall -Werror -std=c11)
fi fi
if test "$PHP_COVERAGE" = "yes"; then
if test "$GCC" != "yes"; then
AC_MSG_ERROR([GCC is required for --enable-coverage])
fi
dnl Check if ccache is being used
case `$php_shtool path $CC` in
*ccache*[)] gcc_ccache=yes;;
*[)] gcc_ccache=no;;
esac
if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then
AC_MSG_ERROR([ccache must be disabled when --enable-coverage option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.])
fi
lcov_version_list="1.5 1.6 1.7 1.9 1.10 1.11"
AC_CHECK_PROG(LCOV, lcov, lcov)
AC_CHECK_PROG(GENHTML, genhtml, genhtml)
PHP_SUBST(LCOV)
PHP_SUBST(GENHTML)
if test "$LCOV"; then
AC_CACHE_CHECK([for lcov version], php_cv_lcov_version, [
php_cv_lcov_version=invalid
lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'` #'
for lcov_check_version in $lcov_version_list; do
if test "$lcov_version" = "$lcov_check_version"; then
php_cv_lcov_version="$lcov_check_version (ok)"
fi
done
])
else
lcov_msg="To enable code coverage reporting you must have one of the following LCOV versions installed: $lcov_version_list"
AC_MSG_ERROR([$lcov_msg])
fi
case $php_cv_lcov_version in
""|invalid[)]
lcov_msg="You must have one of the following versions of LCOV: $lcov_version_list (found: $lcov_version)."
AC_MSG_ERROR([$lcov_msg])
LCOV="exit 0;"
;;
esac
if test -z "$GENHTML"; then
AC_MSG_ERROR([Could not find genhtml from the LCOV package])
fi
PHP_ADD_MAKEFILE_FRAGMENT
dnl Remove all optimization flags from CFLAGS
changequote({,})
CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9s]*//g'`
CXXFLAGS=`echo "$CXXFLAGS" | $SED -e 's/-O[0-9s]*//g'`
changequote([,])
dnl Add the special gcc flags
CFLAGS="$CFLAGS -O0 -ggdb -fprofile-arcs -ftest-coverage"
CXXFLAGS="$CXXFLAGS -ggdb -O0 -fprofile-arcs -ftest-coverage"
fi

@ -10,8 +10,8 @@
<email>grpc-packages@google.com</email> <email>grpc-packages@google.com</email>
<active>yes</active> <active>yes</active>
</lead> </lead>
<date>2015-12-16</date> <date>2016-01-13</date>
<time>12:56:11</time> <time>16:06:07</time>
<version> <version>
<release>0.7.0</release> <release>0.7.0</release>
<api>0.7.0</api> <api>0.7.0</api>
@ -29,6 +29,7 @@
</notes> </notes>
<contents> <contents>
<dir baseinstalldir="/" name="/"> <dir baseinstalldir="/" name="/">
<file baseinstalldir="/" md5sum="f201d644fdbd8228ffd1d4a69cc44f1f" name="tests/grpc-basic.phpt" role="test" />
<file baseinstalldir="/" md5sum="6f19828fb869b7b8a590cbb76b4f996d" name="byte_buffer.c" role="src" /> <file baseinstalldir="/" md5sum="6f19828fb869b7b8a590cbb76b4f996d" name="byte_buffer.c" role="src" />
<file baseinstalldir="/" md5sum="c8de0f819499c48adfc8d7f472c0196b" name="byte_buffer.h" role="src" /> <file baseinstalldir="/" md5sum="c8de0f819499c48adfc8d7f472c0196b" name="byte_buffer.h" role="src" />
<file baseinstalldir="/" md5sum="ee7eb7757f9e6f0e36f8f616b6bd0af5" name="call.c" role="src" /> <file baseinstalldir="/" md5sum="ee7eb7757f9e6f0e36f8f616b6bd0af5" name="call.c" role="src" />
@ -41,9 +42,9 @@
<file baseinstalldir="/" md5sum="a86250e03f610ce6c2c7595a84e08821" name="channel_credentials.h" role="src" /> <file baseinstalldir="/" md5sum="a86250e03f610ce6c2c7595a84e08821" name="channel_credentials.h" role="src" />
<file baseinstalldir="/" md5sum="55ab7a42f9dd9bfc7e28a61cfc5fca63" name="completion_queue.c" role="src" /> <file baseinstalldir="/" md5sum="55ab7a42f9dd9bfc7e28a61cfc5fca63" name="completion_queue.c" role="src" />
<file baseinstalldir="/" md5sum="f10b5bb232d74a6878e829e2e76cdaa2" name="completion_queue.h" role="src" /> <file baseinstalldir="/" md5sum="f10b5bb232d74a6878e829e2e76cdaa2" name="completion_queue.h" role="src" />
<file baseinstalldir="/" md5sum="c7bba7f0f00d1b1483de457d55311382" name="config.m4" role="src" /> <file baseinstalldir="/" md5sum="cafed254127007ff2271dad7d56a06c8" name="config.m4" role="src" />
<file baseinstalldir="/" md5sum="38a1bc979d810c36ebc2a52d4b7b5319" name="CREDITS" role="doc" /> <file baseinstalldir="/" md5sum="38a1bc979d810c36ebc2a52d4b7b5319" name="CREDITS" role="doc" />
<file baseinstalldir="/" md5sum="3f35b472bbdef5a788cd90617d7d0847" name="LICENSE" role="doc" /> <file baseinstalldir="/" md5sum="8847cf67b1b54c981d47ecbb0d139a0c" name="LICENSE" role="doc" />
<file baseinstalldir="/" md5sum="3131a8af38fe5918e5409016b89d6cdb" name="php_grpc.c" role="src" /> <file baseinstalldir="/" md5sum="3131a8af38fe5918e5409016b89d6cdb" name="php_grpc.c" role="src" />
<file baseinstalldir="/" md5sum="673b07859d9f69232f8a754c56780686" name="php_grpc.h" role="src" /> <file baseinstalldir="/" md5sum="673b07859d9f69232f8a754c56780686" name="php_grpc.h" role="src" />
<file baseinstalldir="/" md5sum="7533a6d3ea02c78cad23a9651de0825d" name="README.md" role="doc" /> <file baseinstalldir="/" md5sum="7533a6d3ea02c78cad23a9651de0825d" name="README.md" role="doc" />
@ -142,7 +143,7 @@ Update to wrap gRPC C Core version 0.10.0
<release>beta</release> <release>beta</release>
<api>beta</api> <api>beta</api>
</stability> </stability>
<date>2015-12-16</date> <date>2016-01-13</date>
<license>BSD</license> <license>BSD</license>
<notes> <notes>
- Breaking change to Credentials class (removed) #3765 - Breaking change to Credentials class (removed) #3765

@ -0,0 +1,10 @@
--TEST--
Check for grpc presence
--SKIPIF--
<?php if (!extension_loaded("grpc")) print "skip"; ?>
--FILE--
<?php
echo "grpc extension is available";
?>
--EXPECT--
grpc extension is available

@ -1,5 +1,5 @@
#!/usr/bin/env python2.7 #!/usr/bin/env python2.7
# Copyright 2015, Google Inc. # Copyright 2015-2016, Google Inc.
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -257,7 +257,7 @@ def main():
for t in sorted(END2END_TESTS.keys()) if compatible(f, t) for t in sorted(END2END_TESTS.keys()) if compatible(f, t)
] + [ ] + [
{ {
'name': '%s_test' % f, 'name': '%s_nosec_test' % f,
'args': [t], 'args': [t],
'exclude_configs': [], 'exclude_configs': [],
'platforms': END2END_FIXTURES[f].platforms, 'platforms': END2END_FIXTURES[f].platforms,

@ -112,7 +112,7 @@ class ClientRequestCreator<ByteBuffer> {
public: public:
ClientRequestCreator(ByteBuffer* req, const PayloadConfig& payload_config) { ClientRequestCreator(ByteBuffer* req, const PayloadConfig& payload_config) {
if (payload_config.has_bytebuf_params()) { if (payload_config.has_bytebuf_params()) {
std::unique_ptr<char> buf( std::unique_ptr<char[]> buf(
new char[payload_config.bytebuf_params().req_size()]); new char[payload_config.bytebuf_params().req_size()]);
gpr_slice s = gpr_slice_from_copied_buffer( gpr_slice s = gpr_slice_from_copied_buffer(
buf.get(), payload_config.bytebuf_params().req_size()); buf.get(), payload_config.bytebuf_params().req_size());

@ -1,6 +1,6 @@
#!/usr/bin/env python2.7 #!/usr/bin/env python2.7
# Copyright 2015, Google Inc. # Copyright 2015-2016, Google Inc.
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -85,7 +85,7 @@ for template in templates:
os.close(tf[0]) os.close(tf[0])
cmd.append(test[out]) cmd.append(test[out])
cmd.append(root + '/' + f) cmd.append(root + '/' + f)
jobs.append(jobset.JobSpec(cmd, shortname=out)) jobs.append(jobset.JobSpec(cmd, shortname=out, timeout_seconds=None))
jobset.run(jobs, maxjobs=multiprocessing.cpu_count()) jobset.run(jobs, maxjobs=multiprocessing.cpu_count())

@ -0,0 +1,79 @@
#!/bin/bash
# Copyright 2016, 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.
#
# Builds docker image and runs a command under it.
# You should never need to call this script on your own.
set -ex
cd $(dirname $0)/../..
git_root=$(pwd)
cd -
# Create a local branch so the child Docker script won't complain
git branch -f jenkins-docker
# Inputs
# DOCKERFILE_DIR - Directory in which Dockerfile file is located.
# DOCKER_RUN_SCRIPT - Script to run under docker (relative to grpc repo root)
# $@ - Extra args to pass to docker run
# Use image name based on Dockerfile location checksum
DOCKER_IMAGE_NAME=$(basename $DOCKERFILE_DIR)_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ )
# Make sure docker image has been built. Should be instantaneous if so.
docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR
# Choose random name for docker container
CONTAINER_NAME="build_and_run_docker_$(uuidgen)"
# Run command inside docker
docker run \
"$@" \
-e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \
-v "$git_root:/var/local/jenkins/grpc:ro" \
-w /var/local/git/grpc \
--name=$CONTAINER_NAME \
$DOCKER_IMAGE_NAME \
bash -l "/var/local/jenkins/grpc/$DOCKER_RUN_SCRIPT" || FAILED="true"
# Copy output artifacts
if [ "$OUTPUT_DIR" != "" ]
then
docker cp "$CONTAINER_NAME:/var/local/git/grpc/$OUTPUT_DIR" "$git_root" || FAILED="true"
fi
# remove the container, possibly killing it first
docker rm -f $CONTAINER_NAME || true
if [ "$FAILED" != "" ]
then
exit 1
fi

@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# This script is invoked by Jenkins and triggers build of artifacts.
#
# To prevent cygwin bash complaining about empty lines ending with \r
# we set the igncr option. The option doesn't exist on Linux, so we fallback
# to just 'set -ex' there.
# NOTE: No empty lines should appear in this file before igncr is set!
set -ex -o igncr || set -ex
python tools/run_tests/build_artifacts.py $@

@ -0,0 +1,41 @@
#!/bin/bash
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# This script is invoked by build_docker_* inside a docker
# container. You should never need to call this script on your own.
set -e
mkdir -p /var/local/git
git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
cd /var/local/git/grpc
$RUN_COMMAND

@ -0,0 +1,64 @@
# Copyright 2016, 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.
# Docker file for building gRPC artifacts.
FROM debian:jessie
# Install Git and basic packages.
RUN apt-get update && apt-get install -y \
autoconf \
autotools-dev \
build-essential \
bzip2 \
curl \
gcc \
gcc-multilib \
git \
golang \
libc6 \
libc6-dbg \
libc6-dev \
libgtest-dev \
libtool \
make \
perl \
strace \
python-dev \
python-setuptools \
python-yaml \
telnet \
unzip \
wget \
zip && apt-get clean
RUN mkdir /var/local/jenkins
# Define the default command.
CMD ["bash"]

@ -0,0 +1,64 @@
# Copyright 2016, 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.
# Docker file for building gRPC artifacts.
FROM 32bit/debian:jessie
# Install Git and basic packages.
RUN apt-get update && apt-get install -y \
autoconf \
autotools-dev \
build-essential \
bzip2 \
curl \
gcc \
gcc-multilib \
git \
golang \
libc6 \
libc6-dbg \
libc6-dev \
libgtest-dev \
libtool \
make \
perl \
strace \
python-dev \
python-setuptools \
python-yaml \
telnet \
unzip \
wget \
zip && apt-get clean
RUN mkdir /var/local/jenkins
# Define the default command.
CMD ["bash"]

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# Copyright 2015, Google Inc. # Copyright 2015-2016, Google Inc.
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -42,6 +42,6 @@ cd /var/local/git/grpc
make install-certs make install-certs
# build C# interop client & server # build C# interop client & server
make install_grpc_csharp_ext make CONFIG=dbg grpc_csharp_ext
(cd src/csharp && mono /var/local/NuGet.exe restore Grpc.sln) (cd src/csharp && mono /var/local/NuGet.exe restore Grpc.sln)
(cd src/csharp && xbuild Grpc.sln) (cd src/csharp && xbuild Grpc.sln)

@ -38,6 +38,7 @@ RUN apt-get update && apt-get install -y \
autotools-dev \ autotools-dev \
build-essential \ build-essential \
bzip2 \ bzip2 \
ccache \
curl \ curl \
gcc \ gcc \
gcc-multilib \ gcc-multilib \
@ -61,6 +62,14 @@ RUN apt-get update && apt-get install -y \
wget \ wget \
zip && apt-get clean zip && apt-get clean
# Prepare ccache
RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
RUN ln -s /usr/bin/ccache /usr/local/bin/g++
RUN ln -s /usr/bin/ccache /usr/local/bin/cc
RUN ln -s /usr/bin/ccache /usr/local/bin/c++
RUN ln -s /usr/bin/ccache /usr/local/bin/clang
RUN ln -s /usr/bin/ccache /usr/local/bin/clang++
################## ##################
# C++ dependencies # C++ dependencies
RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang

@ -38,6 +38,7 @@ RUN apt-get update && apt-get install -y \
autotools-dev \ autotools-dev \
build-essential \ build-essential \
bzip2 \ bzip2 \
ccache \
curl \ curl \
gcc \ gcc \
gcc-multilib \ gcc-multilib \
@ -61,6 +62,14 @@ RUN apt-get update && apt-get install -y \
wget \ wget \
zip && apt-get clean zip && apt-get clean
# Prepare ccache
RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
RUN ln -s /usr/bin/ccache /usr/local/bin/g++
RUN ln -s /usr/bin/ccache /usr/local/bin/cc
RUN ln -s /usr/bin/ccache /usr/local/bin/c++
RUN ln -s /usr/bin/ccache /usr/local/bin/clang
RUN ln -s /usr/bin/ccache /usr/local/bin/clang++
################## ##################
# C++ dependencies # C++ dependencies
RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang

@ -0,0 +1,38 @@
#!/bin/bash
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -ex
cd $(dirname $0)/../..
make grpc_csharp_ext
mkdir -p artifacts
cp libs/opt/libgrpc_csharp_ext.so artifacts || cp libs/opt/libgrpc_csharp_ext.dylib artifacts

@ -0,0 +1,236 @@
#!/usr/bin/env python
# Copyright 2016, 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.
"""Builds gRPC distribution artifacts."""
import argparse
import atexit
import dockerjob
import itertools
import jobset
import json
import multiprocessing
import os
import re
import subprocess
import sys
import time
import uuid
# Docker doesn't clean up after itself, so we do it on exit.
atexit.register(lambda: subprocess.call(['stty', 'echo']))
ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
os.chdir(ROOT)
def create_docker_jobspec(name, dockerfile_dir, shell_command, environ={},
flake_retries=0, timeout_retries=0):
"""Creates jobspec for a task running under docker."""
environ = environ.copy()
environ['RUN_COMMAND'] = shell_command
#docker_args = ['-v', '%s/artifacts:/var/local/jenkins/grpc/artifacts' % ROOT]
docker_args=[]
for k,v in environ.iteritems():
docker_args += ['-e', '%s=%s' % (k, v)]
docker_env = {'DOCKERFILE_DIR': dockerfile_dir,
'DOCKER_RUN_SCRIPT': 'tools/jenkins/docker_run.sh',
'OUTPUT_DIR': 'artifacts'}
jobspec = jobset.JobSpec(
cmdline=['tools/jenkins/build_and_run_docker.sh'] + docker_args,
environ=docker_env,
shortname='build_artifact.%s' % (name),
timeout_seconds=30*60,
flake_retries=flake_retries,
timeout_retries=timeout_retries)
return jobspec
def create_jobspec(name, cmdline, environ=None, shell=False,
flake_retries=0, timeout_retries=0):
"""Creates jobspec."""
jobspec = jobset.JobSpec(
cmdline=cmdline,
environ=environ,
shortname='build_artifact.%s' % (name),
timeout_seconds=5*60,
flake_retries=flake_retries,
timeout_retries=timeout_retries,
shell=shell)
return jobspec
def macos_arch_env(arch):
"""Returns environ specifying -arch arguments for make."""
if arch == 'x86':
arch_arg = '-arch i386'
elif arch == 'x64':
arch_arg = '-arch x86_64'
else:
raise Exception('Unsupported arch')
return {'CFLAGS': arch_arg, 'LDFLAGS': arch_arg}
class CSharpExtArtifact:
"""Builds C# native extension library"""
def __init__(self, platform, arch):
self.name = 'csharp_ext_%s_%s' % (platform, arch)
self.platform = platform
self.arch = arch
self.labels = ['csharp', platform, arch]
def pre_build_jobspecs(self):
if self.platform == 'windows':
return [create_jobspec('prebuild_%s' % self.name,
['tools\\run_tests\\pre_build_c.bat'],
shell=True,
flake_retries=5,
timeout_retries=2)]
else:
return []
def build_jobspec(self):
if self.platform == 'windows':
msbuild_platform = 'Win32' if self.arch == 'x86' else self.arch
return create_jobspec(self.name,
['vsprojects\\build_vs2013.bat',
'vsprojects\\grpc_csharp_ext.sln',
'/p:Configuration=Release',
'/p:PlatformToolset=v120',
'/p:Platform=%s' % msbuild_platform],
shell=True)
if self.platform == 'linux':
environ = {'CONFIG': 'opt'}
return create_docker_jobspec(self.name,
'tools/jenkins/grpc_artifact_linux_%s' % self.arch,
'tools/run_tests/build_artifact_csharp.sh')
else:
environ = {'CONFIG': 'opt'}
if self.platform == 'macos':
environ.update(macos_arch_env(self.arch))
return create_jobspec(self.name,
['tools/run_tests/build_artifact_csharp.sh'],
environ=environ)
def __str__(self):
return self.name
_ARTIFACTS = [
CSharpExtArtifact('linux', 'x86'),
CSharpExtArtifact('linux', 'x64'),
CSharpExtArtifact('macos', 'x86'),
CSharpExtArtifact('macos', 'x64'),
CSharpExtArtifact('windows', 'x86'),
CSharpExtArtifact('windows', 'x64')
]
def _create_build_map():
"""Maps artifact names and labels to list of artifacts to be built."""
artifact_build_map = dict([(artifact.name, [artifact])
for artifact in _ARTIFACTS])
if len(_ARTIFACTS) > len(artifact_build_map.keys()):
raise Exception('Artifact names need to be unique')
label_build_map = {}
label_build_map['all'] = [a for a in _ARTIFACTS] # to build all artifacts
for artifact in _ARTIFACTS:
for label in artifact.labels:
if label in label_build_map:
label_build_map[label].append(artifact)
else:
label_build_map[label] = [artifact]
if set(artifact_build_map.keys()).intersection(label_build_map.keys()):
raise Exception('Artifact names need to be distinct from label names')
return dict( artifact_build_map.items() + label_build_map.items())
_BUILD_MAP = _create_build_map()
argp = argparse.ArgumentParser(description='Builds distribution artifacts.')
argp.add_argument('-b', '--build',
choices=sorted(_BUILD_MAP.keys()),
nargs='+',
default=['all'],
help='Artifact name or artifact label to build.')
argp.add_argument('-f', '--filter',
choices=sorted(_BUILD_MAP.keys()),
nargs='+',
default=[],
help='Filter artifacts to build with AND semantics.')
argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int)
argp.add_argument('-t', '--travis',
default=False,
action='store_const',
const=True)
args = argp.parse_args()
# Figure out which artifacts to build
artifacts = []
for label in args.build:
artifacts += _BUILD_MAP[label]
# Among target selected by -b, filter out those that don't match the filter
artifacts = [a for a in artifacts if all(f in a.labels for f in args.filter)]
artifacts = sorted(set(artifacts))
# Execute pre-build phase
prebuild_jobs = []
for artifact in artifacts:
prebuild_jobs += artifact.pre_build_jobspecs()
if prebuild_jobs:
num_failures, _ = jobset.run(
prebuild_jobs, newline_on_success=True, maxjobs=args.jobs)
if num_failures != 0:
jobset.message('FAILED', 'Pre-build phase failed.', do_newline=True)
sys.exit(1)
build_jobs = []
for artifact in artifacts:
build_jobs.append(artifact.build_jobspec())
if not build_jobs:
print 'Nothing to build.'
sys.exit(1)
jobset.message('START', 'Building artifacts.', do_newline=True)
num_failures, _ = jobset.run(
build_jobs, newline_on_success=True, maxjobs=args.jobs)
if num_failures == 0:
jobset.message('SUCCESS', 'All artifacts built successfully.',
do_newline=True)
else:
jobset.message('FAILED', 'Failed to build artifacts.',
do_newline=True)
sys.exit(1)

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# Copyright 2015, Google Inc. # Copyright 2015-2016, Google Inc.
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -32,4 +32,5 @@ set -ex
cd $(dirname $0)/../../src/csharp cd $(dirname $0)/../../src/csharp
xbuild /p:Configuration=$MSBUILD_CONFIG Grpc.sln # overriding NativeDependenciesConfigurationUnix is needed to make gcov code coverage work.
xbuild /p:Configuration=$MSBUILD_CONFIG /p:NativeDependenciesConfigurationUnix=$CONFIG Grpc.sln

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# Copyright 2015, Google Inc. # Copyright 2015-2016, Google Inc.
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -44,5 +44,9 @@ cd src/php
cd ext/grpc cd ext/grpc
phpize phpize
./configure --enable-grpc=$root if [ "$CONFIG" != "gcov" ] ; then
./configure --enable-grpc=$root
else
./configure --enable-grpc=$root --enable-coverage
fi
make make

@ -273,7 +273,9 @@ class Job(object):
self.result.state = 'PASSED' self.result.state = 'PASSED'
if self._bin_hash: if self._bin_hash:
update_cache.finished(self._spec.identity(), self._bin_hash) update_cache.finished(self._spec.identity(), self._bin_hash)
elif self._state == _RUNNING and time.time() - self._start > self._spec.timeout_seconds: elif (self._state == _RUNNING and
self._spec.timeout_seconds is not None and
time.time() - self._start > self._spec.timeout_seconds):
if self._timeout_retries < self._spec.timeout_retries: if self._timeout_retries < self._spec.timeout_retries:
message('TIMEOUT_FLAKE', '%s [pid=%d]' % (self._spec.shortname, self._process.pid), stdout(), do_newline=True) message('TIMEOUT_FLAKE', '%s [pid=%d]' % (self._spec.shortname, self._process.pid), stdout(), do_newline=True)
self._timeout_retries += 1 self._timeout_retries += 1

@ -0,0 +1,46 @@
#!/bin/bash
# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -ex
if [ "$CONFIG" != "gcov" ] ; then exit ; fi
root=$(readlink -f $(dirname $0)/../..)
out=$root/reports/php_ext_coverage
tmp1=$(mktemp)
tmp2=$(mktemp)
cd $root
lcov --capture --directory . --output-file $tmp1
lcov --extract $tmp1 "$root/src/php/ext/grpc/*" --output-file $tmp2
genhtml $tmp2 --output-directory $out
rm $tmp2
rm $tmp1
cp -rv $root/src/php/coverage $root/reports/php

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# Copyright 2015, Google Inc. # Copyright 2015-2016, Google Inc.
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -36,9 +36,6 @@ NUNIT_CONSOLE="mono packages/NUnit.Runners.2.6.4/tools/nunit-console.exe"
# change to gRPC repo root # change to gRPC repo root
cd $(dirname $0)/../.. cd $(dirname $0)/../..
# path needs to be absolute
export LD_LIBRARY_PATH=$(pwd)/libs/$CONFIG
(cd src/csharp; $NUNIT_CONSOLE $@) (cd src/csharp; $NUNIT_CONSOLE $@)
if [ "$CONFIG" = "gcov" ] if [ "$CONFIG" = "gcov" ]

@ -245,7 +245,7 @@ class PhpLanguage(object):
return [['tools/run_tests/build_php.sh']] return [['tools/run_tests/build_php.sh']]
def post_tests_steps(self): def post_tests_steps(self):
return [] return [['tools/run_tests/post_tests_php.sh']]
def makefile_name(self): def makefile_name(self):
return 'Makefile' return 'Makefile'
@ -764,7 +764,7 @@ if platform_string() == 'windows':
_windows_toolset_option(args.compiler), _windows_toolset_option(args.compiler),
_windows_arch_option(args.arch)] + _windows_arch_option(args.arch)] +
extra_args, extra_args,
shell=True, timeout_seconds=90*60) shell=True, timeout_seconds=None)
for target in targets] for target in targets]
else: else:
def make_jobspec(cfg, targets, makefile='Makefile'): def make_jobspec(cfg, targets, makefile='Makefile'):
@ -776,7 +776,7 @@ else:
'CONFIG=%s' % cfg] + 'CONFIG=%s' % cfg] +
([] if not args.travis else ['JENKINS_BUILD=1']) + ([] if not args.travis else ['JENKINS_BUILD=1']) +
targets, targets,
timeout_seconds=30*60)] timeout_seconds=None)]
else: else:
return [] return []
make_targets = {} make_targets = {}
@ -801,7 +801,7 @@ if make_targets:
make_commands = itertools.chain.from_iterable(make_jobspec(cfg, list(targets), makefile) for cfg in build_configs for (makefile, targets) in make_targets.iteritems()) make_commands = itertools.chain.from_iterable(make_jobspec(cfg, list(targets), makefile) for cfg in build_configs for (makefile, targets) in make_targets.iteritems())
build_steps.extend(set(make_commands)) build_steps.extend(set(make_commands))
build_steps.extend(set( build_steps.extend(set(
jobset.JobSpec(cmdline, environ=build_step_environ(cfg), timeout_seconds=10*60) jobset.JobSpec(cmdline, environ=build_step_environ(cfg), timeout_seconds=None)
for cfg in build_configs for cfg in build_configs
for l in languages for l in languages
for cmdline in l.build_steps())) for cmdline in l.build_steps()))
@ -1093,4 +1093,3 @@ else:
if BuildAndRunError.POST_TEST in errors: if BuildAndRunError.POST_TEST in errors:
exit_code |= 4 exit_code |= 4
sys.exit(exit_code) sys.exit(exit_code)

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save