Exemplo n.º 1
0
        private void GrantLocks()
        {
            bool        lockGranted = false;
            LockRequest request     = null;

            // Lock the list of active locks to be sure no other thread grants a lock request.
            lock (_activeLocks)
            {
                // If there are locks available...
                if (_activeLocks.Count < _maxConcurrent)
                {
                    // Keep pulling from the queue until we find a pending request (or it is empty).
                    while (!lockGranted && _pendingRequests.TryDequeue(out request))
                    {
                        lockGranted = AttemptToGrantLock(request);
                    }
                }
            }

            // If we found a request to grant, do so.
            if (lockGranted)
            {
                LockGranted?.Invoke(this, new LockGrantedEventArgs(request, this));
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Releases the lock held by the specified <see cref="LockRequest" />.
        /// </summary>
        /// <param name="request">The lock request.</param>
        /// <exception cref="ArgumentNullException"><paramref name="request" /> is null.</exception>
        public void ReleaseLock(LockRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            bool released = false;

            lock (request)
            {
                // Check the active locks to see if the specified request is one of them.
                released = _activeLocks.TryRemove(request.RequestId, out LockRequest removed);
                if (released)
                {
                    request.State = LockRequestState.Released;
                    _logger.LogTrace($"Request '{request.Name}' released lock for resource '{ResourceId}'.");
                }
                else
                {
                    _logger.LogError($"Request '{request.Name}' attempted to release lock for resource '{ResourceId}', but did not have a lock.");
                }
            }

            if (released)
            {
                GrantLocks();
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Enqueues a lock request for the specified resource.
        /// </summary>
        /// <param name="requestId">The unique identifier for the request.</param>
        /// <param name="resourceId">The resource identifier.</param>
        /// <param name="requestName">The name to use for identifying the request.</param>
        protected void RequestLock(Guid requestId, string resourceId, string requestName)
        {
            // Create a new lock request and add it to the list of all requests.
            LockRequest request = new LockRequest(requestId, requestName);

            _allRequests.TryAdd(request.RequestId, request);

            // Find (or create) the resource and enqueue the request.
            LockResource resource = GetResource(resourceId);

            resource.AddRequest(request);
        }
Exemplo n.º 4
0
 private bool AttemptToGrantLock(LockRequest request)
 {
     lock (request)
     {
         if (request.State == LockRequestState.Pending)
         {
             // Move the lock request from the "pending" queue to the "active" list.
             _activeLocks.TryAdd(request.RequestId, request);
             request.State = LockRequestState.Granted;
             _logger.LogTrace($"Request '{request.Name}' granted lock for resource '{ResourceId}'.");
             return(true);
         }
         else
         {
             _logger.LogTrace($"Request '{request.Name}' for resource '{ResourceId}' is no longer pending.");
             return(false);
         }
     }
 }
Exemplo n.º 5
0
        /// <summary>
        /// Enqueues a lock request for the specified resource.
        /// </summary>
        /// <param name="requestId">The unique identifier for the request.</param>
        /// <param name="resourceIds">The list of resource identifiers.</param>
        /// <param name="requestName">The name to use for identifying the request.</param>
        /// <exception cref="ArgumentNullException"><paramref name="resourceIds" /> is null.</exception>
        protected void RequestLock(Guid requestId, IEnumerable <string> resourceIds, string requestName)
        {
            if (resourceIds == null)
            {
                throw new ArgumentNullException(nameof(resourceIds));
            }

            // Create a new lock request and add it to the list of all requests.
            LockRequest request = new LockRequest(requestId, requestName);

            _allRequests.TryAdd(request.RequestId, request);

            // Find (or create) each resource and enqueue the request.
            foreach (string resourceId in resourceIds)
            {
                LockResource resource = GetResource(resourceId);
                resource.AddRequest(request);
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Adds the specified <see cref="LockRequest" /> to the queue of consumers waiting for a lock.
        /// </summary>
        /// <param name="request">The lock request.</param>
        /// <exception cref="ArgumentNullException"><paramref name="request" /> is null.</exception>
        public void AddRequest(LockRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            lock (request)
            {
                // Don't add the request if it has already been granted, canceled, etc.
                if (request.State == LockRequestState.New || request.State == LockRequestState.Pending)
                {
                    _pendingRequests.Enqueue(request);
                    request.State = LockRequestState.Pending;
                    _logger.LogTrace($"Request '{request.Name}' added to queue for resource '{ResourceId}'.");
                }
            }

            GrantLocks();
        }
Exemplo n.º 7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LockGrantedEventArgs" /> class.
 /// </summary>
 /// <param name="lockRequest">The <see cref="LockRequest" /> that has been granted.</param>
 /// <param name="resource">The <see cref="LockResource"/> that has been given to the requester.</param>
 /// <exception cref="ArgumentNullException">
 /// <paramref name="lockRequest" /> is null.
 /// <para>or</para>
 /// <paramref name="resource" /> is null.</exception>
 public LockGrantedEventArgs(LockRequest lockRequest, LockResource resource)
 {
     Request  = lockRequest ?? throw new ArgumentNullException(nameof(lockRequest));
     Resource = resource ?? throw new ArgumentNullException(nameof(resource));
 }