|
|
|
@ -25,8 +25,6 @@ using Grpc.Core.Utils; |
|
|
|
|
|
|
|
|
|
namespace Grpc.Core.Internal |
|
|
|
|
{ |
|
|
|
|
internal delegate void OpCompletionDelegate(bool success); |
|
|
|
|
|
|
|
|
|
internal delegate void BatchCompletionDelegate(bool success, BatchContextSafeHandle ctx); |
|
|
|
|
|
|
|
|
|
internal delegate void RequestCallCompletionDelegate(bool success, RequestCallContextSafeHandle ctx); |
|
|
|
@ -36,7 +34,7 @@ namespace Grpc.Core.Internal |
|
|
|
|
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<CompletionRegistry>(); |
|
|
|
|
|
|
|
|
|
readonly GrpcEnvironment environment; |
|
|
|
|
readonly Dictionary<IntPtr, OpCompletionDelegate> dict = new Dictionary<IntPtr, OpCompletionDelegate>(new IntPtrComparer()); |
|
|
|
|
readonly Dictionary<IntPtr, IOpCompletionCallback> dict = new Dictionary<IntPtr, IOpCompletionCallback>(new IntPtrComparer()); |
|
|
|
|
readonly object myLock = new object(); |
|
|
|
|
IntPtr lastRegisteredKey; // only for testing |
|
|
|
|
|
|
|
|
@ -45,7 +43,7 @@ namespace Grpc.Core.Internal |
|
|
|
|
this.environment = environment; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void Register(IntPtr key, OpCompletionDelegate callback) |
|
|
|
|
public void Register(IntPtr key, IOpCompletionCallback callback) |
|
|
|
|
{ |
|
|
|
|
environment.DebugStats.PendingBatchCompletions.Increment(); |
|
|
|
|
lock (myLock) |
|
|
|
@ -57,21 +55,19 @@ namespace Grpc.Core.Internal |
|
|
|
|
|
|
|
|
|
public void RegisterBatchCompletion(BatchContextSafeHandle ctx, BatchCompletionDelegate callback) |
|
|
|
|
{ |
|
|
|
|
// TODO(jtattermusch): get rid of new delegate creation here |
|
|
|
|
OpCompletionDelegate opCallback = ((success) => HandleBatchCompletion(success, ctx, callback)); |
|
|
|
|
Register(ctx.Handle, opCallback); |
|
|
|
|
ctx.CompletionCallback = callback; |
|
|
|
|
Register(ctx.Handle, ctx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void RegisterRequestCallCompletion(RequestCallContextSafeHandle ctx, RequestCallCompletionDelegate callback) |
|
|
|
|
{ |
|
|
|
|
// TODO(jtattermusch): get rid of new delegate creation here |
|
|
|
|
OpCompletionDelegate opCallback = ((success) => HandleRequestCallCompletion(success, ctx, callback)); |
|
|
|
|
Register(ctx.Handle, opCallback); |
|
|
|
|
ctx.CompletionCallback = callback; |
|
|
|
|
Register(ctx.Handle, ctx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public OpCompletionDelegate Extract(IntPtr key) |
|
|
|
|
public IOpCompletionCallback Extract(IntPtr key) |
|
|
|
|
{ |
|
|
|
|
OpCompletionDelegate value = null; |
|
|
|
|
IOpCompletionCallback value = null; |
|
|
|
|
lock (myLock) |
|
|
|
|
{ |
|
|
|
|
value = dict[key]; |
|
|
|
@ -89,44 +85,6 @@ namespace Grpc.Core.Internal |
|
|
|
|
get { return this.lastRegisteredKey; } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static void HandleBatchCompletion(bool success, BatchContextSafeHandle ctx, BatchCompletionDelegate callback) |
|
|
|
|
{ |
|
|
|
|
try |
|
|
|
|
{ |
|
|
|
|
callback(success, ctx); |
|
|
|
|
} |
|
|
|
|
catch (Exception e) |
|
|
|
|
{ |
|
|
|
|
Logger.Error(e, "Exception occured while invoking batch completion delegate."); |
|
|
|
|
} |
|
|
|
|
finally |
|
|
|
|
{ |
|
|
|
|
if (ctx != null) |
|
|
|
|
{ |
|
|
|
|
ctx.Dispose(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static void HandleRequestCallCompletion(bool success, RequestCallContextSafeHandle ctx, RequestCallCompletionDelegate callback) |
|
|
|
|
{ |
|
|
|
|
try |
|
|
|
|
{ |
|
|
|
|
callback(success, ctx); |
|
|
|
|
} |
|
|
|
|
catch (Exception e) |
|
|
|
|
{ |
|
|
|
|
Logger.Error(e, "Exception occured while invoking request call completion delegate."); |
|
|
|
|
} |
|
|
|
|
finally |
|
|
|
|
{ |
|
|
|
|
if (ctx != null) |
|
|
|
|
{ |
|
|
|
|
ctx.Dispose(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
|
/// IntPtr doesn't implement <c>IEquatable{IntPtr}</c> so we need to use custom comparer to avoid boxing. |
|
|
|
|
/// </summary> |
|
|
|
|