diff options
Diffstat (limited to 'src/csharp')
-rw-r--r-- | src/csharp/Grpc.Core/Internal/AsyncCallServer.cs | 1 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Internal/CallSafeHandle.cs | 2 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Internal/CompletionRegistry.cs | 3 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Internal/ServerCallHandler.cs | 2 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs | 21 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Server.cs | 19 | ||||
-rw-r--r-- | src/csharp/ext/grpc_csharp_ext.c | 11 |
7 files changed, 37 insertions, 22 deletions
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs index db1b86937f..4f510ba40a 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs @@ -107,6 +107,7 @@ namespace Grpc.Core.Internal call.StartSendStatusFromServer(status, HandleHalfclosed); halfcloseRequested = true; + readingDone = true; sendCompletionDelegate = completionDelegate; } } diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs index 0651498f0e..ef92b44402 100644 --- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs @@ -192,7 +192,5 @@ namespace Grpc.Core.Internal { return buffered ? 0 : GRPC_WRITE_BUFFER_HINT; } - - } }
\ No newline at end of file diff --git a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs index 118aa13c5a..80f006ae50 100644 --- a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs +++ b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs @@ -32,14 +32,15 @@ #endregion using System; -using System.Collections.Generic; using System.Collections.Concurrent; +using System.Collections.Generic; using System.Runtime.InteropServices; using Grpc.Core.Utils; namespace Grpc.Core.Internal { internal delegate void OpCompletionDelegate(bool success); + internal delegate void BatchCompletionDelegate(bool success, BatchContextSafeHandle ctx); internal class CompletionRegistry diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs index f494d9e0ff..c0e5bae13f 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs @@ -267,8 +267,6 @@ namespace Grpc.Core.Internal var responseStream = new ServerResponseStream<byte[], byte[]>(asyncCall); await responseStream.WriteStatusAsync(new Status(StatusCode.Unimplemented, "No such method.")); - // TODO(jtattermusch): if we don't read what client has sent, the server call never gets disposed. - await requestStream.ToList(); await finishedTask; } } diff --git a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs index 9fda1f6569..83dbb910aa 100644 --- a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs @@ -60,10 +60,10 @@ namespace Grpc.Core.Internal static extern GRPCCallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx); [DllImport("grpc_csharp_ext.dll")] - static extern void grpcsharp_server_shutdown(ServerSafeHandle server); + 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, BatchContextSafeHandle ctx); + 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); @@ -91,17 +91,12 @@ namespace Grpc.Core.Internal { grpcsharp_server_start(this); } - - public void Shutdown() - { - grpcsharp_server_shutdown(this); - } - - public void ShutdownAndNotify(BatchCompletionDelegate callback) + + public void ShutdownAndNotify(CompletionQueueSafeHandle cq, BatchCompletionDelegate callback) { var ctx = BatchContextSafeHandle.Create(); GrpcEnvironment.CompletionRegistry.RegisterBatchCompletion(ctx, callback); - grpcsharp_server_shutdown_and_notify_callback(this, ctx); + grpcsharp_server_shutdown_and_notify_callback(this, cq, ctx); } public void RequestCall(CompletionQueueSafeHandle cq, BatchCompletionDelegate callback) @@ -116,5 +111,11 @@ namespace Grpc.Core.Internal grpcsharp_server_destroy(handle); return true; } + + // Only to be called after ShutdownAndNotify. + public void CancelAllCalls() + { + grpcsharp_server_cancel_all_calls(this); + } } } diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs index de10be39ab..8e818885d1 100644 --- a/src/csharp/Grpc.Core/Server.cs +++ b/src/csharp/Grpc.Core/Server.cs @@ -143,7 +143,8 @@ namespace Grpc.Core Preconditions.CheckState(!shutdownRequested); shutdownRequested = true; } - handle.ShutdownAndNotify(HandleServerShutdown); + + handle.ShutdownAndNotify(GetCompletionQueue(), HandleServerShutdown); await shutdownTcs.Task; handle.Dispose(); } @@ -159,8 +160,22 @@ namespace Grpc.Core } } - public void Kill() + /// <summary> + /// Requests server shutdown while cancelling all the in-progress calls. + /// The returned task finishes when shutdown procedure is complete. + /// </summary> + public async Task KillAsync() { + lock (myLock) + { + Preconditions.CheckState(startRequested); + Preconditions.CheckState(!shutdownRequested); + shutdownRequested = true; + } + + handle.ShutdownAndNotify(GetCompletionQueue(), HandleServerShutdown); + handle.CancelAllCalls(); + await shutdownTcs.Task; handle.Dispose(); } diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 59b8993ad3..540f926744 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -626,14 +626,15 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_start(grpc_server *server) { grpc_server_start(server); } -GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_shutdown(grpc_server *server) { - grpc_server_shutdown(server); -} - GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_shutdown_and_notify_callback(grpc_server *server, + grpc_completion_queue *cq, grpcsharp_batch_context *ctx) { - grpc_server_shutdown_and_notify(server, ctx); + grpc_server_shutdown_and_notify(server, cq, ctx); +} + +GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_cancel_all_calls(grpc_server *server) { + grpc_server_cancel_all_calls(server); } GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_destroy(grpc_server *server) { |