1 #region Copyright notice and license 2 3 // Copyright 2019 The gRPC Authors 4 // 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 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 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. 16 17 #endregion 18 19 20 using System; 21 using System.Threading.Tasks; 22 23 namespace Grpc.Core 24 { 25 /// <summary> 26 /// Provides an abstraction over the callback providers 27 /// used by AsyncUnaryCall, AsyncDuplexStreamingCall, etc 28 /// </summary> 29 internal struct AsyncCallState 30 { 31 readonly object responseHeadersAsync; // Task<Metadata> or Func<object, Task<Metadata>> 32 readonly object getStatusFunc; // Func<Status> or Func<object, Status> 33 readonly object getTrailersFunc; // Func<Metadata> or Func<object, Metadata> 34 readonly object disposeAction; // Action or Action<object> 35 readonly object callbackState; // arg0 for the callbacks above, if needed 36 AsyncCallStateGrpc.Core.AsyncCallState37 internal AsyncCallState( 38 Func<object, Task<Metadata>> responseHeadersAsync, 39 Func<object, Status> getStatusFunc, 40 Func<object, Metadata> getTrailersFunc, 41 Action<object> disposeAction, 42 object callbackState) 43 { 44 this.responseHeadersAsync = responseHeadersAsync; 45 this.getStatusFunc = getStatusFunc; 46 this.getTrailersFunc = getTrailersFunc; 47 this.disposeAction = disposeAction; 48 this.callbackState = callbackState; 49 } 50 AsyncCallStateGrpc.Core.AsyncCallState51 internal AsyncCallState( 52 Task<Metadata> responseHeadersAsync, 53 Func<Status> getStatusFunc, 54 Func<Metadata> getTrailersFunc, 55 Action disposeAction) 56 { 57 this.responseHeadersAsync = responseHeadersAsync; 58 this.getStatusFunc = getStatusFunc; 59 this.getTrailersFunc = getTrailersFunc; 60 this.disposeAction = disposeAction; 61 this.callbackState = null; 62 } 63 ResponseHeadersAsyncGrpc.Core.AsyncCallState64 internal Task<Metadata> ResponseHeadersAsync() 65 { 66 var withState = responseHeadersAsync as Func<object, Task<Metadata>>; 67 return withState != null ? withState(callbackState) 68 : (Task<Metadata>)responseHeadersAsync; 69 } 70 GetStatusGrpc.Core.AsyncCallState71 internal Status GetStatus() 72 { 73 var withState = getStatusFunc as Func<object, Status>; 74 return withState != null ? withState(callbackState) 75 : ((Func<Status>)getStatusFunc)(); 76 } 77 GetTrailersGrpc.Core.AsyncCallState78 internal Metadata GetTrailers() 79 { 80 var withState = getTrailersFunc as Func<object, Metadata>; 81 return withState != null ? withState(callbackState) 82 : ((Func<Metadata>)getTrailersFunc)(); 83 } 84 DisposeGrpc.Core.AsyncCallState85 internal void Dispose() 86 { 87 var withState = disposeAction as Action<object>; 88 if (withState != null) 89 { 90 withState(callbackState); 91 } 92 else 93 { 94 ((Action)disposeAction)(); 95 } 96 } 97 } 98 } 99