Ejemplo n.º 1
0
        /// <summary>
        /// Tries to acquire an exclusive write
        /// for the resource, and specifies a timeout for the lock. If this operation
        /// succeeds, the lock must be released as soon
        /// as possible through the <see cref="ReleaseWriteLock"/>
        /// method.
        /// </summary>
        /// <param name="timeout">The timeout of the lock.
        /// A value of null requests a lock that doesn't time out.</param>
        /// <returns>A lock that corresponds to the request. If the lock was denied, the
        /// returned item's <see cref="LockItem.LockType"/>
        /// is <see cref="ResourceLockType.Denied"/>.</returns>
        /// <exception cref="ArgumentOutOfRangeException">In case of a negative
        /// timeout.</exception>
        public LockItem TryGetWriteLock(TimeSpan?timeout)
        {
            lock (this)
            {
                if (HasWriteLock || HasReadLocks)
                {
                    return(LockItem.CreateDenied(ResourceId));
                }

                activeWriteLock = LockItem.CreateWrite(ResourceId, timeout);
                return(activeWriteLock);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Tries to acquire a shared read lock
        /// for the resource, and specifies a timeout for the lock. If this operation
        /// succeeds, the lock must be released as soon
        /// as possible through the <see cref="ReleaseReadLock"/>
        /// method.
        /// </summary>
        /// <returns>A lock that corresponds to the request. If the lock was denied, the
        /// returned item's <see cref="LockItem.LockType"/>
        /// is <see cref="ResourceLockType.Denied"/>.</returns>
        /// <param name="timeout">The timeout of the lock.
        /// A null value requests a lock that doesn't time out.</param>
        /// <returns>True if the lock was granted.</returns>
        /// <exception cref="ArgumentOutOfRangeException">In case of a negative
        /// timeout.</exception>
        public LockItem TryGetReadLock(TimeSpan?timeout)
        {
            lock (this)
            {
                if (HasWriteLock)
                {
                    return(LockItem.CreateDenied(ResourceId));
                }

                //clean up inactive locks from time to time
                Cleanup();

                var item = LockItem.CreateRead(ResourceId, timeout);
                readLocks.Add(item);
                return(item);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets a read lock on all parent folders of a given resource, and rolls back the resources
        /// if the locking fails.
        /// </summary>
        /// <param name="repository">The repository that manages locked resources.</param>
        /// <param name="resourceId">The resource to be locked.</param>
        /// <param name="isWriteLock">Whether to acquire a read or write lock for the resource itself.</param>
        /// <param name="parentFolderIds">Ids of the resource's parent folders, which are being locked one
        /// by one. The list should be ordered, with the first item being the immediate parent of the locked
        /// resource, and the last one the topmost folder to be locked.</param>
        /// <returns>A guard which releases the resource and all folders once it is being disposed.</returns>
        public static ResourceLockGuard GetResourceChainLock(this IResourceLockRepository repository, string resourceId,
                                                             bool isWriteLock, List <string> parentFolderIds)
        {
            LockItem lockItem = isWriteLock ? repository.TryGetWriteLock(resourceId) : repository.TryGetReadLock(resourceId);

            //we couldn't get a lock on the resource itself
            if (!lockItem.IsEnabled)
            {
                return(new ResourceLockGuard(lockItem, repository));
            }

            //get read locks for all parent folders
            List <LockItem> folderLocks = new List <LockItem>();
            LockItem        folderLock  = null;

            foreach (string folderId in parentFolderIds)
            {
                //lock parent folders, one by one for read access (prevents deletion)
                folderLock = repository.TryGetReadLock(folderId);
                if (!folderLock.IsEnabled)
                {
                    break;
                }
                folderLocks.Add(folderLock);
            }

            if (folderLock != null && !folderLock.IsEnabled)
            {
                //roll back all locks...
                repository.ReleaseLock(lockItem);
                folderLocks.ForEach(li => repository.ReleaseLock(li));
                //...and return a dummy lock
                return(new ResourceLockGuard(LockItem.CreateDenied(resourceId), repository));
            }

            return(new ResourceLockGuard(lockItem, repository)
            {
                SecondaryLocks = folderLocks
            });
        }