revert accidental change

pull/1369/head
Craig Tiller 10 years ago
parent 1a727fde47
commit 6f7030b9d7
  1. 238
      src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
  2. 107
      src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
  3. 257
      src/csharp/Grpc.Core/Server.cs
  4. 12
      src/csharp/Grpc.Examples.MathServer/MathServer.cs
  5. 7
      src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj

@ -33,203 +33,159 @@ using System;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Grpc.Core; using Grpc.Core;
using Grpc.Core.Utils;
namespace Grpc.Core.Internal { namespace Grpc.Core.Internal
internal delegate void CompletionCallbackDelegate(GRPCOpError error, {
IntPtr batchContextPtr); internal delegate void CompletionCallbackDelegate(GRPCOpError error, IntPtr batchContextPtr);
/// <summary> /// <summary>
/// grpc_call from <grpc/grpc.h> /// grpc_call from <grpc/grpc.h>
/// </summary> /// </summary>
internal class CallSafeHandle : SafeHandleZeroIsInvalid { internal class CallSafeHandle : SafeHandleZeroIsInvalid
{
const uint GRPC_WRITE_BUFFER_HINT = 1; const uint GRPC_WRITE_BUFFER_HINT = 1;
[DllImport("grpc_csharp_ext.dll")] static extern CallSafeHandle [DllImport("grpc_csharp_ext.dll")]
grpcsharp_channel_create_call(ChannelSafeHandle channel, static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
CompletionQueueSafeHandle cq, string method,
string host, Timespec deadline);
[DllImport("grpc_csharp_ext.dll")] static extern GRPCCallError [DllImport("grpc_csharp_ext.dll")]
grpcsharp_call_cancel(CallSafeHandle call); static extern GRPCCallError grpcsharp_call_cancel(CallSafeHandle call);
[DllImport("grpc_csharp_ext.dll")] static extern GRPCCallError [DllImport("grpc_csharp_ext.dll")]
grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, static extern GRPCCallError grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description);
string description);
[DllImport("grpc_csharp_ext.dll")] static extern GRPCCallError [DllImport("grpc_csharp_ext.dll")]
grpcsharp_call_start_unary( static extern GRPCCallError grpcsharp_call_start_unary(CallSafeHandle call,
CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback,
[MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate byte[] send_buffer, UIntPtr send_buffer_len, MetadataArraySafeHandle metadataArray);
callback,
byte[] send_buffer, UIntPtr send_buffer_len,
MetadataArraySafeHandle metadataArray);
[DllImport("grpc_csharp_ext.dll")] static extern void [DllImport("grpc_csharp_ext.dll")]
grpcsharp_call_blocking_unary( static extern void grpcsharp_call_blocking_unary(CallSafeHandle call, CompletionQueueSafeHandle dedicatedCq,
CallSafeHandle call, CompletionQueueSafeHandle dedicatedCq, [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback,
[MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate byte[] send_buffer, UIntPtr send_buffer_len, MetadataArraySafeHandle metadataArray);
callback,
byte[] send_buffer, UIntPtr send_buffer_len,
MetadataArraySafeHandle metadataArray);
[DllImport("grpc_csharp_ext.dll")] static extern GRPCCallError [DllImport("grpc_csharp_ext.dll")]
grpcsharp_call_start_client_streaming( static extern GRPCCallError grpcsharp_call_start_client_streaming(CallSafeHandle call,
CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback,
[MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate
callback,
MetadataArraySafeHandle metadataArray); MetadataArraySafeHandle metadataArray);
[DllImport("grpc_csharp_ext.dll")] static extern GRPCCallError [DllImport("grpc_csharp_ext.dll")]
grpcsharp_call_start_server_streaming( static extern GRPCCallError grpcsharp_call_start_server_streaming(CallSafeHandle call,
CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback,
[MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate
callback,
byte[] send_buffer, UIntPtr send_buffer_len, byte[] send_buffer, UIntPtr send_buffer_len,
MetadataArraySafeHandle metadataArray); MetadataArraySafeHandle metadataArray);
[DllImport("grpc_csharp_ext.dll")] static extern GRPCCallError [DllImport("grpc_csharp_ext.dll")]
grpcsharp_call_start_duplex_streaming( static extern GRPCCallError grpcsharp_call_start_duplex_streaming(CallSafeHandle call,
CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback,
[MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate
callback,
MetadataArraySafeHandle metadataArray); MetadataArraySafeHandle metadataArray);
[DllImport("grpc_csharp_ext.dll")] static extern GRPCCallError [DllImport("grpc_csharp_ext.dll")]
grpcsharp_call_send_message( static extern GRPCCallError grpcsharp_call_send_message(CallSafeHandle call,
CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback,
[MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate
callback,
byte[] send_buffer, UIntPtr send_buffer_len); byte[] send_buffer, UIntPtr send_buffer_len);
[DllImport("grpc_csharp_ext.dll")] static extern GRPCCallError [DllImport("grpc_csharp_ext.dll")]
grpcsharp_call_send_close_from_client( static extern GRPCCallError grpcsharp_call_send_close_from_client(CallSafeHandle call,
CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback);
[MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate
callback); [DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_send_status_from_server(CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback, StatusCode statusCode, string statusMessage);
[DllImport("grpc_csharp_ext.dll")] static extern GRPCCallError
grpcsharp_call_send_status_from_server( [DllImport("grpc_csharp_ext.dll")]
CallSafeHandle call, static extern GRPCCallError grpcsharp_call_recv_message(CallSafeHandle call,
[MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback);
callback,
StatusCode statusCode, string statusMessage); [DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_start_serverside(CallSafeHandle call,
[DllImport("grpc_csharp_ext.dll")] static extern GRPCCallError [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback);
grpcsharp_call_recv_message(
CallSafeHandle call, [DllImport("grpc_csharp_ext.dll")]
[MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate static extern void grpcsharp_call_destroy(IntPtr call);
callback);
private CallSafeHandle()
[DllImport("grpc_csharp_ext.dll")] static extern GRPCCallError {
grpcsharp_call_start_serverside( }
CallSafeHandle call,
[MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate public static CallSafeHandle Create(ChannelSafeHandle channel, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline)
callback); {
[DllImport("grpc_csharp_ext.dll")] static extern void
grpcsharp_call_destroy(IntPtr call);
private
CallSafeHandle() {}
public
static CallSafeHandle Create(ChannelSafeHandle channel,
CompletionQueueSafeHandle cq, string method,
string host, Timespec deadline) {
return grpcsharp_channel_create_call(channel, cq, method, host, deadline); return grpcsharp_channel_create_call(channel, cq, method, host, deadline);
} }
public public void StartUnary(byte[] payload, CompletionCallbackDelegate callback, MetadataArraySafeHandle metadataArray)
void StartUnary(byte[] payload, CompletionCallbackDelegate callback, {
MetadataArraySafeHandle metadataArray) { AssertCallOk(grpcsharp_call_start_unary(this, callback, payload, new UIntPtr((ulong)payload.Length), metadataArray));
AssertCallOk(grpcsharp_call_start_unary(
this, callback, payload, new UIntPtr((ulong)payload.Length),
metadataArray));
} }
public public void BlockingUnary(CompletionQueueSafeHandle dedicatedCq, byte[] payload, CompletionCallbackDelegate callback, MetadataArraySafeHandle metadataArray)
void BlockingUnary(CompletionQueueSafeHandle dedicatedCq, byte[] payload, {
CompletionCallbackDelegate callback, grpcsharp_call_blocking_unary(this, dedicatedCq, callback, payload, new UIntPtr((ulong)payload.Length), metadataArray);
MetadataArraySafeHandle metadataArray) {
grpcsharp_call_blocking_unary(this, dedicatedCq, callback, payload,
new UIntPtr((ulong)payload.Length),
metadataArray);
} }
public public void StartClientStreaming(CompletionCallbackDelegate callback, MetadataArraySafeHandle metadataArray)
void StartClientStreaming(CompletionCallbackDelegate callback, {
MetadataArraySafeHandle metadataArray) { AssertCallOk(grpcsharp_call_start_client_streaming(this, callback, metadataArray));
AssertCallOk(
grpcsharp_call_start_client_streaming(this, callback, metadataArray));
} }
public public void StartServerStreaming(byte[] payload, CompletionCallbackDelegate callback, MetadataArraySafeHandle metadataArray)
void StartServerStreaming(byte[] payload, {
CompletionCallbackDelegate callback, AssertCallOk(grpcsharp_call_start_server_streaming(this, callback, payload, new UIntPtr((ulong)payload.Length), metadataArray));
MetadataArraySafeHandle metadataArray) {
AssertCallOk(grpcsharp_call_start_server_streaming(
this, callback, payload, new UIntPtr((ulong)payload.Length),
metadataArray));
} }
public public void StartDuplexStreaming(CompletionCallbackDelegate callback, MetadataArraySafeHandle metadataArray)
void StartDuplexStreaming(CompletionCallbackDelegate callback, {
MetadataArraySafeHandle metadataArray) { AssertCallOk(grpcsharp_call_start_duplex_streaming(this, callback, metadataArray));
AssertCallOk(
grpcsharp_call_start_duplex_streaming(this, callback, metadataArray));
} }
public public void StartSendMessage(byte[] payload, CompletionCallbackDelegate callback)
void StartSendMessage(byte[] payload, CompletionCallbackDelegate callback) { {
AssertCallOk(grpcsharp_call_send_message( AssertCallOk(grpcsharp_call_send_message(this, callback, payload, new UIntPtr((ulong)payload.Length)));
this, callback, payload, new UIntPtr((ulong)payload.Length)));
} }
public public void StartSendCloseFromClient(CompletionCallbackDelegate callback)
void StartSendCloseFromClient(CompletionCallbackDelegate callback) { {
AssertCallOk(grpcsharp_call_send_close_from_client(this, callback)); AssertCallOk(grpcsharp_call_send_close_from_client(this, callback));
} }
public public void StartSendStatusFromServer(Status status, CompletionCallbackDelegate callback)
void StartSendStatusFromServer(Status status, {
CompletionCallbackDelegate callback) { AssertCallOk(grpcsharp_call_send_status_from_server(this, callback, status.StatusCode, status.Detail));
AssertCallOk(grpcsharp_call_send_status_from_server(
this, callback, status.StatusCode, status.Detail));
} }
public public void StartReceiveMessage(CompletionCallbackDelegate callback)
void StartReceiveMessage(CompletionCallbackDelegate callback) { {
AssertCallOk(grpcsharp_call_recv_message(this, callback)); AssertCallOk(grpcsharp_call_recv_message(this, callback));
} }
public public void StartServerSide(CompletionCallbackDelegate callback)
void StartServerSide(CompletionCallbackDelegate callback) { {
AssertCallOk(grpcsharp_call_start_serverside(this, callback)); AssertCallOk(grpcsharp_call_start_serverside(this, callback));
} }
public public void Cancel()
void Cancel() { AssertCallOk(grpcsharp_call_cancel(this)); } {
AssertCallOk(grpcsharp_call_cancel(this));
}
public public void CancelWithStatus(Status status)
void CancelWithStatus(Status status) { {
AssertCallOk(grpcsharp_call_cancel_with_status(this, status.StatusCode, AssertCallOk(grpcsharp_call_cancel_with_status(this, status.StatusCode, status.Detail));
status.Detail));
} }
protected protected override bool ReleaseHandle()
override bool ReleaseHandle() { {
grpcsharp_call_destroy(handle); grpcsharp_call_destroy(handle);
return true; return true;
} }
private private static void AssertCallOk(GRPCCallError callError)
static void AssertCallOk(GRPCCallError callError) { {
Trace.Assert(callError == GRPCCallError.GRPC_CALL_OK, Preconditions.CheckState(callError == GRPCCallError.GRPC_CALL_OK, "Status not GRPC_CALL_OK");
"Status not GRPC_CALL_OK");
} }
private private static uint GetFlags(bool buffered)
static uint GetFlags(bool buffered) { {
return buffered ? 0 : GRPC_WRITE_BUFFER_HINT; return buffered ? 0 : GRPC_WRITE_BUFFER_HINT;
} }
} }

@ -35,90 +35,91 @@ using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Grpc.Core.Utils;
namespace Grpc.Core.Internal { namespace Grpc.Core.Internal
// TODO: we need to make sure that the delegates are not collected before {
// invoked. // TODO: we need to make sure that the delegates are not collected before invoked.
internal delegate void ServerShutdownCallbackDelegate(IntPtr eventPtr); internal delegate void ServerShutdownCallbackDelegate(IntPtr eventPtr);
/// <summary> /// <summary>
/// grpc_server from grpc/grpc.h /// grpc_server from grpc/grpc.h
/// </summary> /// </summary>
internal sealed class ServerSafeHandle : SafeHandleZeroIsInvalid { internal sealed class ServerSafeHandle : SafeHandleZeroIsInvalid
[DllImport("grpc_csharp_ext.dll")] static extern GRPCCallError {
grpcsharp_server_request_call( [DllImport("grpc_csharp_ext.dll")]
ServerSafeHandle server, CompletionQueueSafeHandle cq, static extern GRPCCallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback);
[MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate
callback);
[DllImport("grpc_csharp_ext.dll")] static extern ServerSafeHandle [DllImport("grpc_csharp_ext.dll")]
grpcsharp_server_create(CompletionQueueSafeHandle cq, IntPtr args); static extern ServerSafeHandle grpcsharp_server_create(CompletionQueueSafeHandle cq, IntPtr args);
[DllImport("grpc_csharp_ext.dll")] static extern int [DllImport("grpc_csharp_ext.dll")]
grpcsharp_server_add_http2_port(ServerSafeHandle server, string addr); static extern int grpcsharp_server_add_http2_port(ServerSafeHandle server, string addr);
[DllImport("grpc_csharp_ext.dll")] static extern int [DllImport("grpc_csharp_ext.dll")]
grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr, static extern int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds);
ServerCredentialsSafeHandle creds);
[DllImport("grpc_csharp_ext.dll")] static extern void [DllImport("grpc_csharp_ext.dll")]
grpcsharp_server_start(ServerSafeHandle server); static extern void grpcsharp_server_start(ServerSafeHandle server);
[DllImport("grpc_csharp_ext.dll")] static extern void [DllImport("grpc_csharp_ext.dll")]
grpcsharp_server_shutdown(ServerSafeHandle server); static extern void grpcsharp_server_shutdown(ServerSafeHandle server);
// TODO: get rid of the old callback style // TODO: get rid of the old callback style
[DllImport( [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_server_shutdown_and_notify")]
"grpc_csharp_ext.dll", static extern void grpcsharp_server_shutdown_and_notify_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] ServerShutdownCallbackDelegate callback);
EntryPoint = "grpcsharp_server_shutdown_and_notify")] static extern void
grpcsharp_server_shutdown_and_notify_CALLBACK( [DllImport("grpc_csharp_ext.dll")]
ServerSafeHandle server, static extern void grpcsharp_server_destroy(IntPtr server);
[MarshalAs(UnmanagedType.FunctionPtr)] ServerShutdownCallbackDelegate
callback); private ServerSafeHandle()
{
[DllImport("grpc_csharp_ext.dll")] static extern void }
grpcsharp_server_destroy(IntPtr server);
public static ServerSafeHandle NewServer(CompletionQueueSafeHandle cq, IntPtr args)
private {
ServerSafeHandle() {}
public
static ServerSafeHandle NewServer(CompletionQueueSafeHandle cq,
IntPtr args) {
return grpcsharp_server_create(cq, args); return grpcsharp_server_create(cq, args);
} }
public public int AddListeningPort(string addr)
int AddListeningPort(string addr) { {
return grpcsharp_server_add_http2_port(this, addr); return grpcsharp_server_add_http2_port(this, addr);
} }
public public int AddListeningPort(string addr, ServerCredentialsSafeHandle credentials)
int AddListeningPort(string addr, ServerCredentialsSafeHandle credentials) { {
return grpcsharp_server_add_secure_http2_port(this, addr, credentials); return grpcsharp_server_add_secure_http2_port(this, addr, credentials);
} }
public public void Start()
void Start() { grpcsharp_server_start(this); } {
grpcsharp_server_start(this);
}
public public void Shutdown()
void Shutdown() { grpcsharp_server_shutdown(this); } {
grpcsharp_server_shutdown(this);
}
public public void ShutdownAndNotify(ServerShutdownCallbackDelegate callback)
void ShutdownAndNotify(ServerShutdownCallbackDelegate callback) { {
grpcsharp_server_shutdown_and_notify_CALLBACK(this, callback); grpcsharp_server_shutdown_and_notify_CALLBACK(this, callback);
} }
public public void RequestCall(CompletionQueueSafeHandle cq, CompletionCallbackDelegate callback)
GRPCCallError RequestCall(CompletionQueueSafeHandle cq, {
CompletionCallbackDelegate callback) { AssertCallOk(grpcsharp_server_request_call(this, cq, callback));
return grpcsharp_server_request_call(this, cq, callback);
} }
protected protected override bool ReleaseHandle()
override bool ReleaseHandle() { {
grpcsharp_server_destroy(handle); grpcsharp_server_destroy(handle);
return true; return true;
} }
private static void AssertCallOk(GRPCCallError callError)
{
Preconditions.CheckState(callError == GRPCCallError.GRPC_CALL_OK, "Status not GRPC_CALL_OK");
}
} }
} }

@ -38,95 +38,111 @@ using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using Grpc.Core.Internal; using Grpc.Core.Internal;
using Grpc.Core.Utils;
namespace Grpc.Core { namespace Grpc.Core
{
/// <summary> /// <summary>
/// Server is implemented only to be able to do /// A gRPC server.
/// in-process testing.
/// </summary> /// </summary>
public public class Server
class Server { {
// TODO: make sure the delegate doesn't get garbage collected while // TODO(jtattermusch) : make sure the delegate doesn't get garbage collected while
// native callbacks are in the completion queue. // native callbacks are in the completion queue.
readonly ServerShutdownCallbackDelegate serverShutdownHandler; readonly ServerShutdownCallbackDelegate serverShutdownHandler;
readonly CompletionCallbackDelegate newServerRpcHandler; readonly CompletionCallbackDelegate newServerRpcHandler;
readonly BlockingCollection<NewRpcInfo> newRpcQueue =
new BlockingCollection<NewRpcInfo>();
readonly ServerSafeHandle handle; readonly ServerSafeHandle handle;
readonly object myLock = new object();
readonly Dictionary<string, IServerCallHandler> callHandlers = readonly Dictionary<string, IServerCallHandler> callHandlers = new Dictionary<string, IServerCallHandler>();
new Dictionary<string, IServerCallHandler>(); readonly TaskCompletionSource<object> shutdownTcs = new TaskCompletionSource<object>();
readonly TaskCompletionSource<object> shutdownTcs = bool startRequested;
new TaskCompletionSource<object>(); bool shutdownRequested;
public public Server()
Server() { {
this.handle = this.handle = ServerSafeHandle.NewServer(GetCompletionQueue(), IntPtr.Zero);
ServerSafeHandle.NewServer(GetCompletionQueue(), IntPtr.Zero);
this.newServerRpcHandler = HandleNewServerRpc; this.newServerRpcHandler = HandleNewServerRpc;
this.serverShutdownHandler = HandleServerShutdown; this.serverShutdownHandler = HandleServerShutdown;
} }
// only call this before Start() /// <summary>
public /// Adds a service definition to the server. This is how you register
void AddServiceDefinition(ServerServiceDefinition serviceDefinition) { /// handlers for a service with the server.
foreach (var entry in serviceDefinition.CallHandlers) { /// Only call this before Start().
/// </summary>
public void AddServiceDefinition(ServerServiceDefinition serviceDefinition)
{
lock (myLock)
{
Preconditions.CheckState(!startRequested);
foreach (var entry in serviceDefinition.CallHandlers)
{
callHandlers.Add(entry.Key, entry.Value); callHandlers.Add(entry.Key, entry.Value);
} }
} }
}
// only call before Start() /// <summary>
public /// Add a non-secure port on which server should listen.
int AddListeningPort(string addr) { return handle.AddListeningPort(addr); } /// Only call this before Start().
/// </summary>
public int AddListeningPort(string addr)
{
lock (myLock)
{
Preconditions.CheckState(!startRequested);
return handle.AddListeningPort(addr);
}
}
// only call before Start() /// <summary>
public /// Add a secure port on which server should listen.
int AddListeningPort(string addr, ServerCredentials credentials) { /// Only call this before Start().
using(var nativeCredentials = credentials.ToNativeCredentials()) { /// </summary>
public int AddListeningPort(string addr, ServerCredentials credentials)
{
lock (myLock)
{
Preconditions.CheckState(!startRequested);
using (var nativeCredentials = credentials.ToNativeCredentials())
{
return handle.AddListeningPort(addr, nativeCredentials); return handle.AddListeningPort(addr, nativeCredentials);
} }
} }
public
void Start() {
handle.Start();
// TODO: this basically means the server is single threaded....
StartHandlingRpcs();
} }
/// <summary> /// <summary>
/// Requests and handles single RPC call. /// Starts the server.
/// </summary> /// </summary>
internal void RunRpc() { public void Start()
AllowOneRpc(); {
lock (myLock)
try { {
var rpcInfo = newRpcQueue.Take(); Preconditions.CheckState(!startRequested);
startRequested = true;
// Console.WriteLine("Server received RPC " + rpcInfo.Method); handle.Start();
AllowOneRpc();
IServerCallHandler callHandler;
if (!callHandlers.TryGetValue(rpcInfo.Method, out callHandler)) {
callHandler = new NoSuchMethodCallHandler();
}
callHandler.StartCall(rpcInfo.Method, rpcInfo.Call,
GetCompletionQueue());
} catch (Exception e) {
Console.WriteLine("Exception while handling RPC: " + e);
} }
} }
/// <summary> /// <summary>
/// Requests server shutdown and when there are no more calls being /// Requests server shutdown and when there are no more calls being serviced,
/// serviced, /// cleans up used resources. The returned task finishes when shutdown procedure
/// cleans up used resources. /// is complete.
/// </summary> /// </summary>
/// <returns>The async.</returns> public async Task ShutdownAsync()
public {
async Task ShutdownAsync() { lock (myLock)
{
Preconditions.CheckState(startRequested);
Preconditions.CheckState(!shutdownRequested);
shutdownRequested = true;
}
handle.ShutdownAndNotify(serverShutdownHandler); handle.ShutdownAndNotify(serverShutdownHandler);
await shutdownTcs.Task; await shutdownTcs.Task;
handle.Dispose(); handle.Dispose();
@ -135,90 +151,103 @@ namespace Grpc.Core {
/// <summary> /// <summary>
/// To allow awaiting termination of the server. /// To allow awaiting termination of the server.
/// </summary> /// </summary>
public public Task ShutdownTask
Task ShutdownTask { {
get { return shutdownTcs.Task; } get
{
return shutdownTcs.Task;
}
} }
public public void Kill()
void Kill() { handle.Dispose(); } {
handle.Dispose();
}
private /// <summary>
async Task StartHandlingRpcs() { /// Allows one new RPC call to be received by server.
while (true) { /// </summary>
await Task.Factory.StartNew(RunRpc); private void AllowOneRpc()
{
lock (myLock)
{
if (!shutdownRequested)
{
handle.RequestCall(GetCompletionQueue(), newServerRpcHandler);
}
} }
} }
private /// <summary>
void AllowOneRpc() { /// Selects corresponding handler for given call and handles the call.
AssertCallOk( /// </summary>
handle.RequestCall(GetCompletionQueue(), newServerRpcHandler)); private void InvokeCallHandler(CallSafeHandle call, string method)
{
try
{
IServerCallHandler callHandler;
if (!callHandlers.TryGetValue(method, out callHandler))
{
callHandler = new NoSuchMethodCallHandler();
}
callHandler.StartCall(method, call, GetCompletionQueue());
}
catch (Exception e)
{
Console.WriteLine("Exception while handling RPC: " + e);
}
} }
private /// <summary>
void HandleNewServerRpc(GRPCOpError error, IntPtr batchContextPtr) { /// Handles the native callback.
try { /// </summary>
private void HandleNewServerRpc(GRPCOpError error, IntPtr batchContextPtr)
{
try
{
var ctx = new BatchContextSafeHandleNotOwned(batchContextPtr); var ctx = new BatchContextSafeHandleNotOwned(batchContextPtr);
if (error != GRPCOpError.GRPC_OP_OK) { if (error != GRPCOpError.GRPC_OP_OK)
{
// TODO: handle error // TODO: handle error
} }
var rpcInfo = new NewRpcInfo(ctx.GetServerRpcNewCall(), CallSafeHandle call = ctx.GetServerRpcNewCall();
ctx.GetServerRpcNewMethod()); string method = ctx.GetServerRpcNewMethod();
// after server shutdown, the callback returns with null call // after server shutdown, the callback returns with null call
if (!rpcInfo.Call.IsInvalid) { if (!call.IsInvalid)
newRpcQueue.Add(rpcInfo); {
Task.Run(() => InvokeCallHandler(call, method));
}
AllowOneRpc();
} }
} catch (Exception e) { catch (Exception e)
{
Console.WriteLine("Caught exception in a native handler: " + e); Console.WriteLine("Caught exception in a native handler: " + e);
} }
} }
private /// <summary>
void HandleServerShutdown(IntPtr eventPtr) { /// Handles native callback.
try { /// </summary>
/// <param name="eventPtr"></param>
private void HandleServerShutdown(IntPtr eventPtr)
{
try
{
shutdownTcs.SetResult(null); shutdownTcs.SetResult(null);
} catch (Exception e) { }
catch (Exception e)
{
Console.WriteLine("Caught exception in a native handler: " + e); Console.WriteLine("Caught exception in a native handler: " + e);
} }
} }
private private static CompletionQueueSafeHandle GetCompletionQueue()
static void AssertCallOk(GRPCCallError callError) { {
Trace.Assert(callError == GRPCCallError.GRPC_CALL_OK,
"Status not GRPC_CALL_OK");
}
private
static CompletionQueueSafeHandle GetCompletionQueue() {
return GrpcEnvironment.ThreadPool.CompletionQueue; return GrpcEnvironment.ThreadPool.CompletionQueue;
} }
private
struct NewRpcInfo {
private
CallSafeHandle call;
private
string method;
public
NewRpcInfo(CallSafeHandle call, string method) {
this.call = call;
this.method = method;
}
public
CallSafeHandle Call {
get { return this.call; }
}
public
string Method {
get { return this.method; }
}
}
} }
} }

@ -34,11 +34,13 @@ using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using Grpc.Core; using Grpc.Core;
namespace math { namespace math
class MainClass { {
public class MainClass
static void Main(string[] args) { {
String host = "0.0.0.0"; public static void Main(string[] args)
{
string host = "0.0.0.0";
GrpcEnvironment.Initialize(); GrpcEnvironment.Initialize();

@ -16,8 +16,7 @@
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath> <OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG; <DefineConstants>DEBUG;</DefineConstants>
</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole> <Externalconsole>true</Externalconsole>
@ -81,5 +80,7 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
</Project> </Project>
Loading…
Cancel
Save