Exemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="fileToLock"></param>
        /// <param name="lockKind"></param>
        /// <returns></returns>
        /// <exception cref="CannotAcquireLockException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public Guid AcquireLock(NodeWithSurroundingsResolvingResult <FileNode> fileToLock, LockKind lockKind)
        {
            if (fileToLock == null)
            {
                throw new ArgumentNullException("fileToLock");
            }

            lock (_operationExecutionCriticalSection)
            {
                var          idOfFileToLock = fileToLock.ResolvedNode.Id;
                FileLockable fileLockable;
                Guid         newLockId;

                if (_fileIdsToLocks.ContainsKey(idOfFileToLock))
                {
                    fileLockable = _fileIdsToLocks[idOfFileToLock];
                }
                else
                {
                    fileLockable = new FileLockable(fileToLock.ResolvedNode, fileToLock.FoldersPassedWhileResolving);
                    _fileIdsToLocks[idOfFileToLock] = fileLockable;
                }

                newLockId = LockTheFile(fileLockable, lockKind);

                ReportToAllFolderNodesLockableThatTheyHaveANewLock(fileToLock, fileLockable, newLockId);

                _lockIdsToLocks[newLockId] = fileLockable;

                return(newLockId);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="fileLockable"></param>
        /// <param name="lockKind"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="CannotAcquireLockException"></exception>
        private static Guid LockTheFile(FileLockable fileLockable, LockKind lockKind)
        {
            Guid newLockId;

            if (lockKind == LockKind.Read)
            {
                newLockId = fileLockable.LockForReading();
            }
            else if (lockKind == LockKind.Write)
            {
                newLockId = fileLockable.LockForWriting();
            }
            else
            {
                throw new ArgumentException("Вид блокировки {0} не поддерживается.".FormatWith(lockKind.ToString()));
            }

            return(newLockId);
        }
Exemplo n.º 3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="associatedFileLock"></param>
        /// <param name="lockId"></param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="LockAlreadyHeldException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public void AddLock(FileLockable associatedFileLock, Guid lockId)
        {
            if (associatedFileLock == null)
            {
                throw new ArgumentNullException("associatedFileLock");
            }
            MethodArgumentValidator.ThrowIfIsDefault <Guid>(lockId, "lockId");

            if (_idsOfAssociatedFileLocks.Contains(lockId))
            {
                throw new LockAlreadyHeldException("Блокировка с идентификатором {0} уже привязана к блокировке папки.".FormatWith(associatedFileLock.FileId));
            }

            if (!associatedFileLock.IdsOfParentFoldersUpToRoot.Contains(_idOfLockedNode))
            {
                throw new ArgumentException("Папка (идентификатор - {0}) не содержится в списке зависимых для файловой блокировки, которую вы хотите связать с блокировкой этой папки.".FormatWith(_idOfLockedNode));
            }

            _idsOfAssociatedFileLocks.Add(lockId);
        }
Exemplo n.º 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="lockId"></param>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="LockNotFoundException"></exception>
        public void ReleaseLock(Guid lockId)
        {
            MethodArgumentValidator.ThrowIfIsDefault <Guid>(lockId, "lockId");

            lock (_operationExecutionCriticalSection)
            {
                if (_lockIdsToLocks.ContainsKey(lockId))
                {
                    FileLockable fileLockable = _lockIdsToLocks[lockId];

                    fileLockable.ReleaseLock(lockId);

                    if (fileLockable.IsFreeForTaking)
                    {
                        _fileIdsToLocks.Remove(fileLockable.FileId); // все: файл разблокирован
                    }

                    // еще и все ветки отпускаем - если их больше ничто не держит.
                    foreach (Guid nodeId in fileLockable.IdsOfParentFoldersUpToRoot)
                    {
                        FolderNodeLockable folderNodeLockable = _nodeIdsToLocks[nodeId];

                        folderNodeLockable.ReleaseLock(lockId);

                        if (!folderNodeLockable.IsLocked)
                        {
                            _nodeIdsToLocks.Remove(folderNodeLockable.IdOfLockedNode);
                        }
                    }

                    _lockIdsToLocks.Remove(lockId);
                }
                else
                {
                    throw new LockNotFoundException("Не найдена блокировка с идентификатором {0}".FormatWith(lockId));
                }
            }
        }
Exemplo n.º 5
0
        private void ReportToAllFolderNodesLockableThatTheyHaveANewLock(NodeWithSurroundingsResolvingResult <FileNode> fileToLock, FileLockable fileLockable, Guid newLockId)
        {
            foreach (FolderNode node in fileToLock.FoldersPassedWhileResolving)
            {
                FolderNodeLockable folderNodeLockableToAdjust;

                if (_nodeIdsToLocks.ContainsKey(node.Id))
                {
                    folderNodeLockableToAdjust = _nodeIdsToLocks[node.Id];
                }
                else
                {
                    folderNodeLockableToAdjust = new FolderNodeLockable(node);
                    _nodeIdsToLocks[node.Id]   = folderNodeLockableToAdjust;
                }

                folderNodeLockableToAdjust.AddLock(fileLockable, newLockId);
            }
        }