diff options
author | 2015-02-13 10:46:02 -0800 | |
---|---|---|
committer | 2015-02-13 10:46:02 -0800 | |
commit | 23821ceb690a71ef307c8878d352c534c27d838b (patch) | |
tree | bf02f5d6c757469858d238538ef0b4ad401b3072 /src/csharp/GrpcCore | |
parent | 07fadea2ff9f0ca3925e82fa84fb8e38131ce656 (diff) |
Reworked GrpcEnvironment initialization and shutdown to allow running all tests at once.
Diffstat (limited to 'src/csharp/GrpcCore')
-rw-r--r-- | src/csharp/GrpcCore/Channel.cs | 7 | ||||
-rw-r--r-- | src/csharp/GrpcCore/GrpcEnvironment.cs | 67 | ||||
-rw-r--r-- | src/csharp/GrpcCore/Server.cs | 4 | ||||
-rw-r--r-- | src/csharp/GrpcCore/Utils/RecordingQueue.cs | 1 |
4 files changed, 40 insertions, 39 deletions
diff --git a/src/csharp/GrpcCore/Channel.cs b/src/csharp/GrpcCore/Channel.cs index b0d8beeb7b..36ebef777f 100644 --- a/src/csharp/GrpcCore/Channel.cs +++ b/src/csharp/GrpcCore/Channel.cs @@ -8,13 +8,6 @@ namespace Google.GRPC.Core { public class Channel : IDisposable { - /// <summary> - /// Make sure GPRC environment is initialized before any channels get used. - /// </summary> - static Channel() { - GrpcEnvironment.EnsureInitialized(); - } - readonly ChannelSafeHandle handle; readonly String target; diff --git a/src/csharp/GrpcCore/GrpcEnvironment.cs b/src/csharp/GrpcCore/GrpcEnvironment.cs index 7a7ff39179..dcd3bc672b 100644 --- a/src/csharp/GrpcCore/GrpcEnvironment.cs +++ b/src/csharp/GrpcCore/GrpcEnvironment.cs @@ -5,11 +5,9 @@ using System.Runtime.InteropServices; namespace Google.GRPC.Core { /// <summary> - /// Encapsulates initialization and shutdown of GRPC C core library. - /// You should not need to initialize it manually, as static constructors - /// should load the library when needed. + /// Encapsulates initialization and shutdown of gRPC library. /// </summary> - public static class GrpcEnvironment + public class GrpcEnvironment { const int THREAD_POOL_SIZE = 1; @@ -20,21 +18,24 @@ namespace Google.GRPC.Core static extern void grpcsharp_shutdown(); static object staticLock = new object(); - static bool initCalled = false; - static bool shutdownCalled = false; - - static GrpcThreadPool threadPool = new GrpcThreadPool(THREAD_POOL_SIZE); + static volatile GrpcEnvironment instance; + + readonly GrpcThreadPool threadPool; + bool isClosed; /// <summary> - /// Makes sure GRPC environment is initialized. + /// Makes sure GRPC environment is initialized. Subsequent invocations don't have any + /// effect unless you call Shutdown first. + /// Although normal use cases assume you will call this just once in your application's + /// lifetime (and call Shutdown once you're done), for the sake of easier testing it's + /// allowed to initialize the environment again after it has been successfully shutdown. /// </summary> - public static void EnsureInitialized() { + public static void Initialize() { lock(staticLock) { - if (!initCalled) + if (instance == null) { - initCalled = true; - GrpcInit(); + instance = new GrpcEnvironment(); } } } @@ -47,45 +48,55 @@ namespace Google.GRPC.Core { lock(staticLock) { - if (initCalled && !shutdownCalled) + if (instance != null) { - shutdownCalled = true; - GrpcShutdown(); + instance.Close(); + instance = null; } } + } + internal static GrpcThreadPool ThreadPool + { + get + { + var inst = instance; + if (inst == null) + { + throw new InvalidOperationException("GRPC environment not initialized"); + } + return inst.threadPool; + } } /// <summary> - /// Initializes GRPC C Core library. + /// Creates gRPC environment. /// </summary> - private static void GrpcInit() + private GrpcEnvironment() { grpcsharp_init(); + threadPool = new GrpcThreadPool(THREAD_POOL_SIZE); threadPool.Start(); // TODO: use proper logging here Console.WriteLine("GRPC initialized."); } /// <summary> - /// Shutdown GRPC C Core library. + /// Shuts down this environment. /// </summary> - private static void GrpcShutdown() + private void Close() { + if (isClosed) + { + throw new InvalidOperationException("Close has already been called"); + } threadPool.Stop(); grpcsharp_shutdown(); + isClosed = true; // TODO: use proper logging here Console.WriteLine("GRPC shutdown."); } - - internal static GrpcThreadPool ThreadPool - { - get - { - return threadPool; - } - } } } diff --git a/src/csharp/GrpcCore/Server.cs b/src/csharp/GrpcCore/Server.cs index d3bc81e574..3c4a73aa7a 100644 --- a/src/csharp/GrpcCore/Server.cs +++ b/src/csharp/GrpcCore/Server.cs @@ -26,10 +26,6 @@ namespace Google.GRPC.Core readonly TaskCompletionSource<object> shutdownTcs = new TaskCompletionSource<object>(); - static Server() { - GrpcEnvironment.EnsureInitialized(); - } - public Server() { // TODO: what is the tag for server shutdown? diff --git a/src/csharp/GrpcCore/Utils/RecordingQueue.cs b/src/csharp/GrpcCore/Utils/RecordingQueue.cs index 0726f00af7..81e1a8298f 100644 --- a/src/csharp/GrpcCore/Utils/RecordingQueue.cs +++ b/src/csharp/GrpcCore/Utils/RecordingQueue.cs @@ -5,6 +5,7 @@ using System.Collections.Concurrent; namespace Google.GRPC.Core.Utils { + // TODO: replace this by something that implements IAsyncEnumerator. /// <summary> /// Observer that allows us to await incoming messages one-by-one. /// The implementation is not ideal and class will be probably replaced |