|
|
|
@ -29,7 +29,7 @@ namespace Grpc.Core.Internal |
|
|
|
|
{ |
|
|
|
|
static readonly NativeMethods Native = NativeMethods.Get(); |
|
|
|
|
|
|
|
|
|
AtomicCounter shutdownRefcount = new AtomicCounter(1); |
|
|
|
|
AtomicCounter shutdownRefcount; |
|
|
|
|
CompletionRegistry completionRegistry; |
|
|
|
|
|
|
|
|
|
private CompletionQueueSafeHandle() |
|
|
|
@ -51,6 +51,7 @@ namespace Grpc.Core.Internal |
|
|
|
|
{ |
|
|
|
|
var cq = Native.grpcsharp_completion_queue_create_async(); |
|
|
|
|
cq.completionRegistry = completionRegistry; |
|
|
|
|
cq.shutdownRefcount = new AtomicCounter(1); |
|
|
|
|
return cq; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -95,7 +96,7 @@ namespace Grpc.Core.Internal |
|
|
|
|
|
|
|
|
|
private void DecrementShutdownRefcount() |
|
|
|
|
{ |
|
|
|
|
if (shutdownRefcount.Decrement() == 0) |
|
|
|
|
if (shutdownRefcount == null || shutdownRefcount.Decrement() == 0) |
|
|
|
|
{ |
|
|
|
|
Native.grpcsharp_completion_queue_shutdown(this); |
|
|
|
|
} |
|
|
|
@ -103,14 +104,20 @@ namespace Grpc.Core.Internal |
|
|
|
|
|
|
|
|
|
private void BeginOp() |
|
|
|
|
{ |
|
|
|
|
bool success = false; |
|
|
|
|
shutdownRefcount.IncrementIfNonzero(ref success); |
|
|
|
|
GrpcPreconditions.CheckState(success, "Shutdown has already been called"); |
|
|
|
|
if (shutdownRefcount != null) |
|
|
|
|
{ |
|
|
|
|
bool success = false; |
|
|
|
|
shutdownRefcount.IncrementIfNonzero(ref success); |
|
|
|
|
GrpcPreconditions.CheckState(success, "Shutdown has already been called"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void EndOp() |
|
|
|
|
{ |
|
|
|
|
DecrementShutdownRefcount(); |
|
|
|
|
if (shutdownRefcount != null) |
|
|
|
|
{ |
|
|
|
|
DecrementShutdownRefcount(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Allows declaring BeginOp and EndOp of a completion queue with a using statement. |
|
|
|
|