Exemplo n.º 1
0
        static async void A2(ILockManager manager)
        {
            // wait one second
            await Task.Delay(1000);

            // check if it's locked
            LockToken existingLock = await manager.QueryAsync("tandem://devices/Wow");

            if (existingLock.IsValid)
            {
                Console.WriteLine($"It's locked by '{existingLock.Owner}'");
            }

            // now try and obtain a lock
            await Task.Delay(2000);

            using (var h = await manager.LockAsync("tandem://devices/wow")) {
                if (h == null)
                {
                    Console.WriteLine("Couldn't get a lock!");
                }
                else
                {
                    Console.WriteLine("Got a lock!");
                    ProceedSemaphore.Release();
                }
            }
        }
        private async Task TestSingleLockAsync(ISet <string> releasedLocks, ILockManager lockManager, CancellationToken ct)
        {
            var l = new Lock(
                "/",
                "/",
                false,
                new XElement("test"),
                LockAccessType.Write,
                LockShareMode.Exclusive,
                TimeSpan.FromMilliseconds(100));
            var sem = new SemaphoreSlim(0, 1);
            var evt = new EventHandler <LockEventArgs>((s, e) =>
            {
                Assert.True(releasedLocks.Add(e.Lock.StateToken));
                sem.Release();
            });

            lockManager.LockReleased += evt;
            try
            {
                var stopwatch = new Stopwatch();
                stopwatch.Start();
                await lockManager.LockAsync(l, ct);

                Assert.True(await sem.WaitAsync(5000, ct));
                stopwatch.Stop();
                Assert.True(
                    stopwatch.ElapsedMilliseconds >= 90,
                    $"Duration should be at least 100ms, but was {stopwatch.ElapsedMilliseconds}");
            }
            finally
            {
                lockManager.LockReleased -= evt;
            }
        }
Exemplo n.º 3
0
        /// <inheritdoc />
        public async Task <IWebDavResult> LockAsync(string path, lockinfo info, CancellationToken cancellationToken)
        {
            if (_lockManager == null)
            {
                throw new NotSupportedException();
            }

            var owner      = info.owner;
            var recursive  = (_context.RequestHeaders.Depth ?? DepthHeader.Infinity) == DepthHeader.Infinity;
            var accessType = LockAccessType.Write;
            var shareType  = info.lockscope.ItemElementName == ItemChoiceType.exclusive
                ? LockShareMode.Exclusive
                : LockShareMode.Shared;
            var timeout = _timeoutPolicy?.SelectTimeout(
                _context.RequestHeaders.Timeout?.Values ?? new[] { TimeoutHeader.Infinite })
                          ?? TimeoutHeader.Infinite;

            var href = GetHref(path);
            var l    = new Lock(
                path,
                href,
                recursive,
                owner,
                accessType,
                shareType,
                timeout);

            Debug.Assert(_lockManager != null, "_lockManager != null");
            var lockResult = await _lockManager.LockAsync(l, cancellationToken);

            if (lockResult.ConflictingLocks != null)
            {
                // Lock cannot be acquired
                if (lockResult.ConflictingLocks.ChildLocks.Count == 0)
                {
                    return(new WebDavResult <error>(WebDavStatusCode.Locked, CreateError(lockResult.ConflictingLocks.GetLocks())));
                }

                var errorResponses = new List <response>();
                if (lockResult.ConflictingLocks.ChildLocks.Count != 0 ||
                    lockResult.ConflictingLocks.ReferenceLocks.Count != 0)
                {
                    errorResponses.Add(CreateErrorResponse(
                                           WebDavStatusCode.Forbidden,
                                           lockResult.ConflictingLocks.ChildLocks.Concat(lockResult.ConflictingLocks.ReferenceLocks)));
                }

                if (lockResult.ConflictingLocks.ParentLocks.Count != 0)
                {
                    var errorResponse = CreateErrorResponse(
                        WebDavStatusCode.Forbidden,
                        lockResult.ConflictingLocks.ChildLocks);
                    errorResponse.error = CreateError(new IActiveLock[0]);
                    errorResponses.Add(errorResponse);
                }

                errorResponses.Add(new response()
                {
                    href             = GetHref(l.Path),
                    ItemsElementName = new[] { ItemsChoiceType2.status, },
                    Items            = new object[]
                    {
                        new Status(_context.RequestProtocol, WebDavStatusCode.FailedDependency).ToString(),
                    },
                });

                var multistatus = new multistatus()
                {
                    response = errorResponses.ToArray(),
                };

                return(new WebDavResult <multistatus>(WebDavStatusCode.MultiStatus, multistatus));
            }

            var activeLock = lockResult.Lock;

            Debug.Assert(activeLock != null, "activeLock != null");
            try
            {
                var selectionResult = await _rootFileSystem.SelectAsync(path, cancellationToken);

                WebDavStatusCode statusCode;
                if (selectionResult.IsMissing)
                {
                    if (_context.RequestHeaders.IfNoneMatch != null)
                    {
                        throw new WebDavException(WebDavStatusCode.PreconditionFailed);
                    }

                    if (selectionResult.MissingNames.Count > 1)
                    {
                        return(new WebDavResult(WebDavStatusCode.Conflict));
                    }

                    var current = selectionResult.Collection;
                    var docName = selectionResult.MissingNames.Single();
                    await current.CreateDocumentAsync(docName, cancellationToken);

                    statusCode = WebDavStatusCode.Created;
                }
                else
                {
                    await _context
                    .RequestHeaders.ValidateAsync(selectionResult.TargetEntry, cancellationToken)
                    ;

                    statusCode = WebDavStatusCode.OK;
                }

                var activeLockXml = activeLock.ToXElement();
                var result        = new prop()
                {
                    Any = new[] { new XElement(WebDavXml.Dav + "lockdiscovery", activeLockXml) },
                };
                var webDavResult = new WebDavResult <prop>(statusCode, result);
                webDavResult.Headers["Lock-Token"] = new[] { new LockTokenHeader(new Uri(activeLock.StateToken)).ToString() };
                return(webDavResult);
            }
            catch
            {
                await _lockManager
                .ReleaseAsync(activeLock.Path, new Uri(activeLock.StateToken, UriKind.RelativeOrAbsolute), cancellationToken)
                ;

                throw;
            }
        }
Exemplo n.º 4
0
 static async void A1(ILockManager manager)
 {
     using (var h = await manager.LockAsync("tandem://devices/wow")) {
         await Task.Delay(2000);
     }
 }