aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp
diff options
context:
space:
mode:
authorGravatar Jan Tattermusch <jtattermusch@google.com>2018-07-19 23:14:26 +0200
committerGravatar Jan Tattermusch <jtattermusch@google.com>2018-07-19 23:14:26 +0200
commit3511f45964808f3ed73109fa4086298422036665 (patch)
tree694110ca245a111169417a9d67af2c8eda506acb /src/csharp
parentc6970ad79dd77a75af5e26825abd4bcf8828cd2d (diff)
parentd52661af9ac0e8beedb105e69dc6eb7ca36aaa94 (diff)
Merge remote-tracking branch 'upstream/master' into support/xamarin
Diffstat (limited to 'src/csharp')
-rw-r--r--src/csharp/Grpc.Core/GrpcEnvironment.cs26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index 27a91c723a..a6a1d8af50 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -422,10 +422,32 @@ namespace Grpc.Core
{
if (!hooksRegistered)
{
+ // Under normal circumstances, the user is expected to shutdown all
+ // the gRPC channels and servers before the application exits. The following
+ // hooks provide some extra handling for cases when this is not the case,
+ // in the effort to achieve a reasonable behavior on shutdown.
#if NETSTANDARD1_5
- // FIXME couldn't get around a "cannot resolve type" runtime exception on Xamarin.Android
- //System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += (assemblyLoadContext) => { HandleShutdown(); };
+ // No action required at shutdown on .NET Core
+ // - In-progress P/Invoke calls (such as grpc_completion_queue_next) don't seem
+ // to prevent a .NET core application from terminating, so no special handling
+ // is needed.
+ // - .NET core doesn't run finalizers on shutdown, so there's no risk of getting
+ // a crash because grpc_*_destroy methods for native objects being invoked
+ // in wrong order.
+ // TODO(jtattermusch): Verify that the shutdown hooks are still not needed
+ // once we add support for new platforms using netstandard (e.g. Xamarin).
#else
+ // On desktop .NET framework and Mono, we need to register for a shutdown
+ // event to explicitly shutdown the GrpcEnvironment.
+ // - On Desktop .NET framework, we need to do a proper shutdown to prevent a crash
+ // when the framework attempts to run the finalizers for SafeHandle object representing the native
+ // grpc objects. The finalizers calls the native grpc_*_destroy methods (e.g. grpc_server_destroy)
+ // in a random order, which is not supported by gRPC.
+ // - On Mono, the process would hang as the GrpcThreadPool threads are sleeping
+ // in grpc_completion_queue_next P/Invoke invocation and mono won't let the
+ // process shutdown until the P/Invoke calls return. We achieve that by shutting down
+ // the completion queue(s) which associated with the GrpcThreadPool, which will
+ // cause the grpc_completion_queue_next calls to return immediately.
AppDomain.CurrentDomain.ProcessExit += (sender, eventArgs) => { HandleShutdown(); };
AppDomain.CurrentDomain.DomainUnload += (sender, eventArgs) => { HandleShutdown(); };
#endif