1 #region Copyright notice and license
3 // Copyright 2015 gRPC authors.
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
20 using System.Runtime.InteropServices;
23 using Grpc.Core.Logging;
24 using Grpc.Core.Utils;
26 namespace Grpc.Core.Internal
28 internal interface IOpCompletionCallback
30 void OnComplete(bool success);
34 /// grpcsharp_batch_context
36 internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback, IPooledObject<BatchContextSafeHandle>
38 static readonly NativeMethods Native = NativeMethods.Get();
39 static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<BatchContextSafeHandle>();
41 Action<BatchContextSafeHandle> returnToPoolAction;
42 CompletionCallbackData completionCallbackData;
44 private BatchContextSafeHandle()
48 public static BatchContextSafeHandle Create()
50 var ctx = Native.grpcsharp_batch_context_create();
62 public void SetReturnToPoolAction(Action<BatchContextSafeHandle> returnAction)
64 GrpcPreconditions.CheckState(returnToPoolAction == null);
65 returnToPoolAction = returnAction;
68 public void SetCompletionCallback(BatchCompletionDelegate callback, object state)
70 GrpcPreconditions.CheckState(completionCallbackData.Callback == null);
71 GrpcPreconditions.CheckNotNull(callback, nameof(callback));
72 completionCallbackData = new CompletionCallbackData(callback, state);
75 // Gets data of recv_initial_metadata completion.
76 public Metadata GetReceivedInitialMetadata()
78 IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_initial_metadata(this);
79 return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
82 // Gets data of recv_status_on_client completion.
83 public ClientSideStatus GetReceivedStatusOnClient()
85 UIntPtr detailsLength;
86 IntPtr detailsPtr = Native.grpcsharp_batch_context_recv_status_on_client_details(this, out detailsLength);
87 string details = MarshalUtils.PtrToStringUTF8(detailsPtr, (int)detailsLength.ToUInt32());
88 var status = new Status(Native.grpcsharp_batch_context_recv_status_on_client_status(this), details);
90 IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this);
91 var metadata = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
93 return new ClientSideStatus(status, metadata);
96 // Gets data of recv_message completion.
97 public byte[] GetReceivedMessage()
99 IntPtr len = Native.grpcsharp_batch_context_recv_message_length(this);
100 if (len == new IntPtr(-1))
104 byte[] data = new byte[(int)len];
105 Native.grpcsharp_batch_context_recv_message_to_buffer(this, data, new UIntPtr((ulong)data.Length));
109 // Gets data of receive_close_on_server completion.
110 public bool GetReceivedCloseOnServerCancelled()
112 return Native.grpcsharp_batch_context_recv_close_on_server_cancelled(this) != 0;
115 public void Recycle()
117 if (returnToPoolAction != null)
119 Native.grpcsharp_batch_context_reset(this);
121 var origReturnAction = returnToPoolAction;
122 // Not clearing all the references to the pool could prevent garbage collection of the pool object
123 // and thus cause memory leaks.
124 returnToPoolAction = null;
125 origReturnAction(this);
133 protected override bool ReleaseHandle()
135 Native.grpcsharp_batch_context_destroy(handle);
139 void IOpCompletionCallback.OnComplete(bool success)
143 completionCallbackData.Callback(success, this, completionCallbackData.State);
147 Logger.Error(e, "Exception occurred while invoking batch completion delegate.");
151 completionCallbackData = default(CompletionCallbackData);
156 struct CompletionCallbackData
158 public CompletionCallbackData(BatchCompletionDelegate callback, object state)
160 this.Callback = callback;
164 public BatchCompletionDelegate Callback { get; }
165 public object State { get; }