internal async Task <MessageRpc> LockInstanceAsync(MessageRpc rpc) { if (concurrencyMode != ConcurrencyMode.Multiple) { ConcurrencyInstanceContextFacet resource = rpc.InstanceContext.Concurrency; bool needToWait = false; lock (rpc.InstanceContext.ThisLock) { if (!resource.Locked) { resource.Locked = true; } else { needToWait = true; } } if (needToWait) { await resource.EnqueueNewMessage(); } if (concurrencyMode == ConcurrencyMode.Reentrant) { rpc.OperationContext.IsServiceReentrant = true; } } return(rpc); }
// TODO: Make async to remove blocking Wait call internal static Task LockInstanceAfterCalloutAsync(OperationContext operationContext) { if (operationContext != null) { InstanceContext instanceContext = operationContext.InstanceContext; if (operationContext.IsServiceReentrant) { ConcurrencyInstanceContextFacet resource = instanceContext.Concurrency; bool needToWait = false; lock (instanceContext.ThisLock) { if (!resource.Locked) { resource.Locked = true; } } if (needToWait) { return(resource.EnqueueCalloutMessage()); } } } return(Task.CompletedTask); }
internal async Task LockInstanceAsync(MessageRpc rpc) { if (concurrencyMode != ConcurrencyMode.Multiple) { ConcurrencyInstanceContextFacet resource = rpc.InstanceContext.Concurrency; Task waiter = null; lock (rpc.InstanceContext.ThisLock) { if (!resource.Locked) { resource.Locked = true; } else { waiter = resource.EnqueueNewMessage(); } } if (waiter != null) { await waiter; } // TODO: Throw this on setup if (concurrencyMode == ConcurrencyMode.Reentrant) { throw new NotSupportedException(nameof(ConcurrencyMode.Reentrant)); } } }
static void UnlockInstance(InstanceContext instanceContext) { ConcurrencyInstanceContextFacet resource = instanceContext.Concurrency; lock (instanceContext.ThisLock) { if (resource.HasWaiters) { resource.DequeueWaiter(); } else { //We have no pending Callouts and no new Messages to process resource.Locked = false; } } }