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(); } } }
public void UT_LockToken_ToString_LockTokenHeaderWithSquaredBrackets() { var lockToken = new LockToken("<my-lock-token>"); var str = lockToken.ToString(LockTokenFormat.LockTokenHeader); Assert.AreEqual("<my-lock-token>", str); }
public Djin(LockToken token) : base(token) { rates = new Dictionary <Type, float>() { { typeof(Stats.DarkStat), 1.1f }, { typeof(Stats.LightStat), 1f }, { typeof(Stats.ChaosStat), 1.1f }, { typeof(Stats.Orderstat), 1f }, { typeof(Stats.FireStat), 1.2f }, { typeof(Stats.WaterStat), 1f }, { typeof(Stats.EarthStat), 1f }, { typeof(Stats.WindStat), 1f }, }; statBonuse = new Dictionary <Type, int>() { { typeof(Stats.DarkStat), 1 }, { typeof(Stats.LightStat), 0 }, { typeof(Stats.ChaosStat), 1 }, { typeof(Stats.Orderstat), 0 }, { typeof(Stats.FireStat), 2 }, { typeof(Stats.WaterStat), 0 }, { typeof(Stats.EarthStat), 0 }, { typeof(Stats.WindStat), 0 }, }; }
public async Task <Tuple <IEnumerable <Event>, bool> > TryScheduleAsync(DiagnosticsSource source) { // if Stop offset has been reached if (!string.IsNullOrEmpty(source.StopOffsetPoint) && source.LastOffsetPoint != null && source.LastOffsetPoint.CompareTo(source.StopOffsetPoint) >= 0) { return(new Tuple <IEnumerable <Event>, bool>(Enumerable.Empty <Event>(), false)); } var lockToken = new LockToken(source.ToTypeKey()); int seconds = Convert.ToInt32(_configurationValueProvider.GetValue(ConfigurationKeys.ClusterLockDurationSeconds)); if (!(await _lockStore.TryLockAsync(lockToken, 2, 1000, seconds * 1000))) { TheTrace.TraceInformation("I could NOT be master for {0}", source.ToTypeKey()); return(new Tuple <IEnumerable <Event>, bool>(Enumerable.Empty <Event>(), false)); } try { var events = await DoSchedule(source); return(new Tuple <IEnumerable <Event>, bool>(events, true)); } finally { Task.Run(() => _lockStore.ReleaseLockAsync(lockToken)).Wait(); } }
/// <summary> /// If the id is already locked and the token is already in use, this method returns true /// </summary> /// <param name="id"></param> /// <param name="waitStartTime"></param> /// <param name="attemptTimeout"></param> /// <param name="token"></param> /// <returns></returns> bool _tryLock(object id, float waitStartTime, float attemptTimeout, object token) { LockToken lockToken = new LockToken(token, TimeKeeper.MsSinceInitialization); while (TimeKeeper.MsSinceInitialization - waitStartTime < attemptTimeout) { if (_lockedIDs.ContainsKey(id) && _lockTokens.ContainsKey(token)) { return(true); } if (!_lockedIDs.TryAdd(id, TimeKeeper.MsSinceInitialization)) { Thread.Sleep(1); continue; } lockToken.LastUpdateTime = TimeKeeper.MsSinceInitialization; if (!_lockTokens.ContainsKey(token) && !_lockTokens.TryAdd(token, lockToken)) { throw new CorruptStateException("Succesfully locked an Id, but could not add the LockToken. This shouldn't be possible, probable concurrency bug."); } return(true); } return(false); }
public void UT_LockToken_ToString_LockTokenHeaderWithBothBracketsReversed() { var lockToken = new LockToken("<(my-lock-token)>"); var str = lockToken.ToString(LockTokenFormat.LockTokenHeader); Assert.AreEqual("<my-lock-token>", str); }
public void UIT_WebDavClient_LockRefreshLockUnlock() { var client = CreateWebDavClientWithDebugHttpMessageHandler(); // Lock. var lockInfo = new LockInfo(); lockInfo.LockScope = LockScope.CreateExclusiveLockScope(); lockInfo.LockType = LockType.CreateWriteLockType(); lockInfo.OwnerHref = "*****@*****.**"; var response = client.LockAsync(this.webDavRootFolder, WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(15)), WebDavDepthHeaderValue.Infinity, lockInfo).Result; var lockResponseSuccess = response.IsSuccessStatusCode; LockToken lockToken = WebDavHelper.GetLockTokenFromWebDavResponseMessage(response); // Refresh lock. response = client.RefreshLockAsync(this.webDavRootFolder, WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(10)), lockToken).Result; var refreshLockResponseSuccess = response.IsSuccessStatusCode; // Unlock. response = client.UnlockAsync(this.webDavRootFolder, lockToken).Result; var unlockResponseSuccess = response.IsSuccessStatusCode; Assert.IsTrue(lockResponseSuccess); Assert.IsNotNull(lockToken); Assert.IsTrue(refreshLockResponseSuccess); Assert.IsTrue(unlockResponseSuccess); }
public async Task <bool> TryLockAsync( LockToken token, int tries = 16, // this is NOT retry - it is try int retryTimeoutMilliseconds = 15000, int timeoutMilliseconds = 15000) { if (tries < 1) { tries = 1; } var blob = await GetBlobAsync(token.ResourceId); for (int i = 0; i < tries; i++) { try { await blob.AcquireLeaseAsync( TimeSpan.FromMilliseconds(timeoutMilliseconds), token.TokenId.ToString("N")); return(true); } catch (Exception e) { TheTrace.TraceInformation("Lock attempt - already locked: {0}", e); // ignore } await Task.Delay(TimeSpan.FromMilliseconds(retryTimeoutMilliseconds / tries)); } return(false); }
void DisposeToken(LockToken token) { HandleToken(); UpdateSocketState(); token = null; void HandleToken() { LockType tokenType = token.lockType; switch (tokenType) { case LockType.Common: Interlocked.Decrement(ref lockersCount); break; case LockType.Overall: Interlocked.Decrement(ref overallLockersCount); break; default: throw new Exception(); // TODO: исключение } } }
public void Stop() { // try to aquire lock, if fail then kill process anyways. var lockAquried = Monitor.TryEnter(_lockObject, 500); if (IsRunning) { CloseGameProcess(); if (Memory != null) { Memory.Dispose(); Memory = null; } IsRunning = false; StartupSequenceIsComplete = false; if (LockToken != null) { LockToken.Dispose(); LockToken = null; } } if (lockAquried) { Monitor.Exit(_lockObject); } Profile.Status = "Stopped"; }
public async Task ICanLockForMoreThan30Seconds() { var locker = new AzureLockStore( new BlobSource() { ContainerName = ContainerName, ConnectionString = ConnectionString, Path = "this/is/great/" }); var resource = Guid.NewGuid().ToString(); var token = new LockToken(resource); var canLock = await locker.TryLockAsync(token, 0, timeoutMilliseconds : 120 *1000); Assert.True(canLock); var newtoken = new LockToken(resource); Thread.Sleep(115 * 1000); var canDoubleLock = await locker.TryLockAsync(newtoken, 1, 100); await locker.ReleaseLockAsync(token); Assert.False(canDoubleLock); }
public void UT_LockToken_ToString_IfHeaderWithBothBrackets() { var lockToken = new LockToken("(<my-lock-token>)"); var str = lockToken.ToString(LockTokenFormat.IfHeader); Assert.AreEqual("(<my-lock-token>)", str); }
public void UIT_WebDavClient_LockAndPutWithToken() { var client = CreateWebDavClientWithDebugHttpMessageHandler(); // Lock. var lockInfo = new LockInfo(); lockInfo.LockScope = LockScope.CreateExclusiveLockScope(); lockInfo.LockType = LockType.CreateWriteLockType(); lockInfo.OwnerHref = "*****@*****.**"; var response = client.LockAsync(this.webDavRootFolder, WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(15)), WebDavDepthHeaderValue.Infinity, lockInfo).Result; var lockResponseSuccess = response.IsSuccessStatusCode; LockToken lockToken = WebDavHelper.GetLockTokenFromWebDavResponseMessage(response); // Put file. var content = new StreamContent(File.OpenRead(TestFile)); var requestUrl = UriHelper.CombineUrl(this.webDavRootFolder, TestFile, true); response = client.PutAsync(requestUrl, content, lockToken).Result; var putResponseSuccess = response.IsSuccessStatusCode; // Delete file. response = client.DeleteAsync(requestUrl, lockToken).Result; var deleteResponseSuccess = response.IsSuccessStatusCode; // Unlock. response = client.UnlockAsync(this.webDavRootFolder, lockToken).Result; var unlockResponseSuccess = response.IsSuccessStatusCode; Assert.IsTrue(lockResponseSuccess); Assert.IsNotNull(lockToken); Assert.IsTrue(putResponseSuccess); Assert.IsTrue(deleteResponseSuccess); Assert.IsTrue(unlockResponseSuccess); }
public async Task UT_WebDavClient_LockRefreshLock() { var lockResponseContent = "<?xml version=\"1.0\" encoding=\"utf-8\"?><D:prop xmlns:D=\"DAV:\"><D:lockdiscovery><D:activelock><D:locktype><D:write/></D:locktype><D:lockscope><D:exclusive/></D:lockscope><D:depth>infinity</D:depth><D:owner><D:href>[email protected]</D:href></D:owner><D:timeout>Second-10</D:timeout><D:locktoken><D:href>opaquelocktoken:0af5a3d3-2ccd-42fb-b8c7-9c59c9b90944.22bc01d2b2e0e947</D:href></D:locktoken><D:lockroot><D:href>http://127.0.0.1/webdav/</D:href></D:lockroot></D:activelock></D:lockdiscovery></D:prop>"; var oneMinuteTimeout = WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromMinutes(1)); var lockTokenString = "(<opaquelocktoken:0af5a3d3-2ccd-42fb-b8c7-9c59c9b90944.22bc01d2b2e0e947>)"; var parseResult = NoTagList.TryParse(lockTokenString, out NoTagList noTagList); Assert.IsTrue(parseResult); var lockToken = new LockToken(noTagList.CodedUrl.AbsoluteUri); var mockHandler = new MockHttpMessageHandler(); var requestHeaders = new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>(WebDavRequestHeader.Timeout, oneMinuteTimeout.ToString()), new KeyValuePair <string, string>(WebDavRequestHeader.If, lockTokenString) }; mockHandler.When(WebDavMethod.Lock, WebDavRootFolder).WithHeaders(requestHeaders).Respond(HttpStatusCode.OK, new StringContent(lockResponseContent)); using (var client = CreateWebDavClient(mockHandler)) { var response = await client.RefreshLockAsync(WebDavRootFolder, oneMinuteTimeout, lockToken); Assert.IsTrue(response.IsSuccessStatusCode); } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldAcceptOnlyFirstRequestWithSameId() public virtual void ShouldAcceptOnlyFirstRequestWithSameId() { // given ReplicatedLockTokenStateMachine stateMachine = new ReplicatedLockTokenStateMachine(new InMemoryStateStorage <ReplicatedLockTokenState>(new ReplicatedLockTokenState())); int firstCandidateId = LockToken.nextCandidateId(stateMachine.CurrentToken().id()); // when stateMachine.ApplyCommand(new ReplicatedLockTokenRequest(member(0), firstCandidateId), 1, r => { }); stateMachine.ApplyCommand(new ReplicatedLockTokenRequest(member(1), firstCandidateId), 2, r => { }); // then assertEquals(0, stateMachine.CurrentToken().id()); assertEquals(member(0), stateMachine.CurrentToken().owner()); // when stateMachine.ApplyCommand(new ReplicatedLockTokenRequest(member(1), firstCandidateId + 1), 3, r => { }); stateMachine.ApplyCommand(new ReplicatedLockTokenRequest(member(0), firstCandidateId + 1), 4, r => { }); // then assertEquals(1, stateMachine.CurrentToken().id()); assertEquals(member(1), stateMachine.CurrentToken().owner()); }
public void MonitorIsAcquired() { using (LockToken token = subject.Lock()) { Monitor.Pulse(subject.Monitor); } }
public async Task IncrementAsync(string counterName, string id, long value) { var key = string.Format("____COUNTER____{0}-{1}", counterName, id); var token = new LockToken(key); var result = await _lockStore.TryLockAsync(token); if (!result) { throw new TimeoutException("Could not lock the resource"); } var blob = await GetBlobAsync(key); var text = await blob.DownloadTextAsync(); var current = long.Parse(string.IsNullOrEmpty(text) ? "0" : text); var newValue = current + value; if (newValue < 0) { throw new InvalidOperationException("Value cannot get below zero: " + newValue); } await blob.UploadTextAsync(newValue.ToString()); await _lockStore.ReleaseLockAsync(token); }
private bool EnterIfPossible(T lockingObject, byte lockType, LockRuleset rules, out LockToken <T> token, LockHolder h) { var entrancePair = rules.LockMatrix.EntrancePair(lockType, h.LockInfo); //найден (или не найден) допустимый переход из текущего состояния блокировок в требуемый тип if (entrancePair.HasValue) //если найден { unchecked { var blockExit = (int)entrancePair.Value.BlockExit; Debug.Assert((entrancePair.Value.BlockEntrance & LockMatrix.SharenessCheckLock) == 0, "(entrancePair.Value.BlockEntrance & LockMatrix.SharenessCheckLock) == 0", "Не должно быть флага разделяемой блокировки в допустимом входном состоянии"); //делаем непосредственно переход if (Interlocked.CompareExchange(ref h.LockInfo, blockExit, (int)entrancePair.Value.BlockEntrance) == (int)entrancePair.Value.BlockEntrance) { int sharedLockCount = 0; //если взяли разделяемую блокировку с уже существующей if ((blockExit & LockMatrix.SharenessCheckLock) == LockMatrix.SharenessCheckLock) { sharedLockCount = h.IncrLock(rules.LockMatrix.SelfSharedLockShift(lockType));//добавляем счётчик к количеству этих блокировок на заданном типе Debug.Print($"sharedLockCount"); Debug.Assert(h.LockInfo == blockExit, "h.LockInfo == blockExit", "Состояние блокировок изменилось там, где не должно"); h.LockInfo = (int)((uint)h.LockInfo & LockMatrix.SharenessCheckLockDrop);//и сбрасываем этот флажок обратно. Никто не должен поменять LockInfo, т.к. с этим поднятым флажков не должно быть допустимых состояний. } token = new LockToken <T>(lockType, lockingObject, this, rules, sharedLockCount); return(true); } } } token = default(LockToken <T>); return(false); }
/// <summary> /// Selects a <see cref="LockToken" /> from the provided list, based on current /// availability of the associated resources, then mocks the critical section service /// by performing the action designated by <see cref="Behavior" />. /// </summary> /// <param name="tokens">The collection of tokens to choose from.</param> /// <param name="action">The action to execute; takes the acquired token as a parameter.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="tokens" /> is null. /// <para>or</para> /// <paramref name="action" /> is null. /// </exception> /// <exception cref="ArgumentException"><paramref name="tokens" /> contains no elements.</exception> /// <exception cref="AcquireLockTimeoutException">This instance is configured with <see cref="CriticalSectionMockBehavior.ThrowAcquireTimeoutException" />.</exception> /// <exception cref="HoldLockTimeoutException">This instance is configured with <see cref="CriticalSectionMockBehavior.ThrowHoldTimeoutException" />.</exception> public void Run(IEnumerable <LockToken> tokens, Action <LockToken> action) { if (tokens == null) { throw new ArgumentNullException(nameof(tokens)); } if (!tokens.Any()) { throw new ArgumentException("At least one token must be provided.", nameof(tokens)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } switch (Behavior) { case CriticalSectionMockBehavior.ThrowAcquireTimeoutException: throw new AcquireLockTimeoutException("The lock could not be acquired within the designated time."); case CriticalSectionMockBehavior.ThrowHoldTimeoutException: throw new HoldLockTimeoutException("The specified action did not complete within the designated time."); } List <LockToken> tokenList = tokens.ToList(); LockToken selectedToken = tokenList[_random.Next(tokenList.Count)]; action(selectedToken); }
/// <summary> /// Selects a <see cref="LockToken" /> from the provided list, based on current /// availability of the associated resources, then obtains an exlusive lock /// and executes the specified <see cref="Action{LockToken}" /> before releasing the lock. /// </summary> /// <param name="tokens">The collection of tokens to choose from.</param> /// <param name="action">The action to execute; takes the acquired token as a parameter.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="tokens" /> is null. /// <para>or</para> /// <paramref name="action" /> is null. /// </exception> /// <exception cref="ArgumentException"><paramref name="tokens" /> contains no elements.</exception> /// <exception cref="AcquireLockTimeoutException">The lock could not be obtained within the acquisition timeout specified by the selected token.</exception> /// <exception cref="HoldLockTimeoutException"><paramref name="action" /> did not complete within the hold timeout specified by the selected token.</exception> public void Run(IEnumerable <LockToken> tokens, Action <LockToken> action) { if (tokens == null) { throw new ArgumentNullException(nameof(tokens)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } if (!tokens.Any()) { throw new ArgumentException("No lock tokens were specified.", nameof(tokens)); } // Send the lock tokens in a random order to prevent picking the same one every time if they are all available Random random = new Random(); IEnumerable <string> tokenIds = tokens.Select(n => n.Key).OrderBy(n => random.Next()); LockTicket lockTicket = _lockManager.AcquireLock(tokenIds, tokens.First().AcquireTimeout, 1, _requestName); try { LockToken acquiredToken = tokens.First(n => n.Key == lockTicket.ResourceId); RunAction(acquiredToken, () => action(acquiredToken)); } finally { _lockManager.ReleaseLock(lockTicket); } }
public bool TryAcqureLock(T lockingObject, LockRuleset rules, byte lockType, out LockToken <T> token) { var h = _locks.GetOrAdd(lockingObject, _ => new LockHolder(rules.LockMatrix.SelfSharedLocks)); h.LastUsage = Stopwatch.GetTimestamp(); return(EnterIfPossible(lockingObject, lockType, rules, out token, h)); }
public async Task ReleaseLockAsync(LockToken token) { var blob = await GetBlobAsync(token.ResourceId); await blob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(token.TokenId.ToString("N"))); token.RenewCancellation.Cancel(); }
private static void RunAction(LockToken token, Action action) { bool finished = RunAction(action, token.HoldTimeout); if (!finished) { throw new HoldLockTimeoutException($"Action did not complete within {token.HoldTimeout}."); } }
private static void ReleaseLock(object key, LockToken @lock) { @lock.Release(); if (@lock.IsNotUsed) { Locks.TryRemove(key, out var tmp); } }
/// <summary> /// This writes a message to the output stream /// </summary> /// <param name="physical">The phsyical connection to write to.</param> /// <param name="message">The message to be written.</param> internal ValueTask <WriteResult> WriteMessageTakingWriteLockAsync(PhysicalConnection physical, Message message) { Trace("Writing: " + message); message.SetEnqueued(physical); // this also records the read/write stats at this point bool releaseLock = false; LockToken token = default; try { // try to acquire it synchronously // note: timeout is specified in mutex-constructor var pending = _singleWriterMutex.TryWaitAsync(options: MutexSlim.WaitOptions.DisableAsyncContext); if (!pending.IsCompletedSuccessfully) { return(WriteMessageTakingDelayedWriteLockAsync(pending, physical, message)); } releaseLock = true; token = pending.Result; // we can't use "using" for this, because we might not want to kill it yet if (!token.Success) // (in particular, me might hand the lifetime to CompleteWriteAndReleaseLockAsync) { message.Cancel(); Multiplexer?.OnMessageFaulted(message, null); this.CompleteSyncOrAsync(message); return(new ValueTask <WriteResult>(WriteResult.TimeoutBeforeWrite)); } var result = WriteMessageInsideLock(physical, message); if (result == WriteResult.Success) { var flush = physical.FlushAsync(false); if (!flush.IsCompletedSuccessfully) { releaseLock = false; // so we don't release prematurely return(CompleteWriteAndReleaseLockAsync(token, flush, message)); } result = flush.Result; // we know it was completed, this is fine } UnmarkActiveMessage(message); physical.SetIdle(); return(new ValueTask <WriteResult>(result)); } catch (Exception ex) { return(new ValueTask <WriteResult>(HandleWriteException(message, ex))); } finally { if (releaseLock) { token.Dispose(); } } }
internal WriteResult WriteMessageTakingWriteLockSync(PhysicalConnection physical, Message message) { Trace("Writing: " + message); message.SetEnqueued(physical); // this also records the read/write stats at this point LockToken token = default; try { token = _singleWriterMutex.TryWait(WaitOptions.NoDelay); if (!token.Success) { // we can't get it *instantaneously*; is there // perhaps a backlog and active backlog processor? bool haveBacklog; lock (_backlog) { haveBacklog = _backlog.Count != 0; } if (haveBacklog) { PushToBacklog(message); return(WriteResult.Success); // queued counts as success } // no backlog... try to wait with the timeout; // if we *still* can't get it: that counts as // an actual timeout token = _singleWriterMutex.TryWait(); if (!token.Success) { message.Cancel(); Multiplexer?.OnMessageFaulted(message, null); message.Complete(); return(WriteResult.TimeoutBeforeWrite); } } var result = WriteMessageInsideLock(physical, message); if (result == WriteResult.Success) { #pragma warning disable CS0618 result = physical.FlushSync(false, TimeoutMilliseconds); #pragma warning restore CS0618 } UnmarkActiveMessage(message); physical.SetIdle(); return(result); } catch (Exception ex) { return(HandleWriteException(message, ex)); } finally { token.Dispose(); } }
public async Task CanNotRenewIfSomeoneElse() { var m = new DynamoDBMutex(RegionEndpoint.EUWest1); var resId = Guid.NewGuid().ToString("N"); var t = await m.AcquireLockAsync(resId, TimeSpan.FromSeconds(10)); var other = new LockToken(t.ResourceId, "other", t.LeaseExpiry); var t2 = await m.RenewAsync(other, TimeSpan.FromSeconds(20)); Assert.Null(t2); }
public async Task <bool> TryLockAsync( LockToken token, int tries = 16, // this is NOT retry - it is try int retryTimeoutMilliseconds = 15000, int timeoutMilliseconds = 15000, int aquireTimeoutMilliseconds = 15000) { await EnsureExists(); if (tries < 1) { tries = 1; } var blob = await GetBlobAsync(token.ResourceId); for (var i = 0; i < tries; i++) { try { using (var cancellationTokenSource = new CancellationTokenSource(aquireTimeoutMilliseconds)) { await blob.AcquireLeaseAsync( TimeSpan.FromMilliseconds(Math.Min(MaxLockPossibleMilliseconds, timeoutMilliseconds)), token.TokenId.ToString("N"), null, null, null, cancellationTokenSource.Token); } if (timeoutMilliseconds > MaxLockPossibleMilliseconds) { KeepExtendingLeaseAsync(async() => { await blob.AcquireLeaseAsync( TimeSpan.FromMilliseconds(MaxLockPossibleMilliseconds), token.TokenId.ToString("N")); }, TimeSpan.FromMilliseconds(MaxLockPossibleMilliseconds), token.RenewCancellation.Token, token.ResourceId); // DO NOT WAIT THIS!!! } return(true); } catch (Exception e) { TheTrace.TraceInformation("Lock attempt - already locked: {0}", e); // ignore } if (i < tries - 1) { await Task.Delay(TimeSpan.FromMilliseconds(retryTimeoutMilliseconds / tries)); } } return(false); }
public async Task UIT_WebDavClient_LockAndPutWithToken() { // This won't work on ownCloud/Nextcloud because they do not support WebDAV locking. // These unit integration test are skipped for ownCloud/Nextcloud. if (webDavRootFolder.Contains("nextcloud") || webDavRootFolder.Contains("owncloud")) { return; } using (var client = CreateWebDavClientWithDebugHttpMessageHandler()) { // Lock. var lockInfo = new LockInfo() { LockScope = LockScope.CreateExclusiveLockScope(), LockType = LockType.CreateWriteLockType(), OwnerHref = "*****@*****.**" }; var response = await client.LockAsync(webDavRootFolder, WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(15)), WebDavDepthHeaderValue.Infinity, lockInfo); var lockResponseSuccess = response.IsSuccessStatusCode; LockToken lockToken = await WebDavHelper.GetLockTokenFromWebDavResponseMessage(response); var requestUrl = UriHelper.CombineUrl(webDavRootFolder, TestFile, true); // Put file. using (var fileStream = File.OpenRead(TestFile)) { var content = new StreamContent(fileStream); response = await client.PutAsync(requestUrl, content, lockToken); } var putResponseSuccess = response.IsSuccessStatusCode; // Delete file. response = await client.DeleteAsync(requestUrl, lockToken); var deleteResponseSuccess = response.IsSuccessStatusCode; // Unlock. response = await client.UnlockAsync(webDavRootFolder, lockToken); var unlockResponseSuccess = response.IsSuccessStatusCode; Assert.IsTrue(lockResponseSuccess); Assert.IsNotNull(lockToken); Assert.IsTrue(putResponseSuccess); Assert.IsTrue(deleteResponseSuccess); Assert.IsTrue(unlockResponseSuccess); } }
public void Dispose() { lock (_bigLock) { LockToken miniLock = _lockMap[_itemId]; miniLock.Count--; if (miniLock.Count == 0) { _lockMap.Remove(_itemId); } Monitor.Exit(miniLock); } }