1 #region Copyright notice and license 2 // Copyright 2015 gRPC authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 #endregion 16 using System; 17 using System.Runtime.InteropServices; 18 using System.Threading; 19 using System.Threading.Tasks; 20 using Grpc.Core.Profiling; 21 22 namespace Grpc.Core.Internal 23 { 24 /// <summary> 25 /// grpc_channel from <c>grpc/grpc.h</c> 26 /// </summary> 27 internal class ChannelSafeHandle : SafeHandleZeroIsInvalid 28 { 29 static readonly NativeMethods Native = NativeMethods.Get(); 30 ChannelSafeHandle()31 private ChannelSafeHandle() 32 { 33 } 34 CreateInsecure(string target, ChannelArgsSafeHandle channelArgs)35 public static ChannelSafeHandle CreateInsecure(string target, ChannelArgsSafeHandle channelArgs) 36 { 37 // Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle. 38 // Doing so would make object finalizer crash if we end up abandoning the handle. 39 GrpcEnvironment.GrpcNativeInit(); 40 return Native.grpcsharp_insecure_channel_create(target, channelArgs); 41 } 42 CreateSecure(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs)43 public static ChannelSafeHandle CreateSecure(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs) 44 { 45 // Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle. 46 // Doing so would make object finalizer crash if we end up abandoning the handle. 47 GrpcEnvironment.GrpcNativeInit(); 48 return Native.grpcsharp_secure_channel_create(credentials, target, channelArgs); 49 } 50 CreateCall(CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline, CallCredentialsSafeHandle credentials)51 public CallSafeHandle CreateCall(CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline, CallCredentialsSafeHandle credentials) 52 { 53 var result = Native.grpcsharp_channel_create_call(this, parentCall, propagationMask, cq, method, host, deadline); 54 if (credentials != null) 55 { 56 result.SetCredentials(credentials); 57 } 58 result.Initialize(cq); 59 return result; 60 } 61 CheckConnectivityState(bool tryToConnect)62 public ChannelState CheckConnectivityState(bool tryToConnect) 63 { 64 return Native.grpcsharp_channel_check_connectivity_state(this, tryToConnect ? 1 : 0); 65 } 66 WatchConnectivityState(ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, BatchCompletionDelegate callback, object callbackState)67 public void WatchConnectivityState(ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, BatchCompletionDelegate callback, object callbackState) 68 { 69 var ctx = cq.CompletionRegistry.RegisterBatchCompletion(callback, callbackState); 70 Native.grpcsharp_channel_watch_connectivity_state(this, lastObservedState, deadline, cq, ctx); 71 } 72 GetTarget()73 public string GetTarget() 74 { 75 using (var cstring = Native.grpcsharp_channel_get_target(this)) 76 { 77 return cstring.GetValue(); 78 } 79 } 80 ReleaseHandle()81 protected override bool ReleaseHandle() 82 { 83 Native.grpcsharp_channel_destroy(handle); 84 GrpcEnvironment.GrpcNativeShutdown(); 85 return true; 86 } 87 } 88 } 89