public async Task GetLockAsync_WithCancellationToken_Cancels() { // Arrange var mutex = new AsyncMutex(); await mutex.GetLockAsync(); using var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(100)); // Act/Assert var ex = await Assert.ThrowsAsync <TaskCanceledException>(() => mutex.GetLockAsync(cts.Token).AsTask()); Assert.Equal(cts.Token, ex.CancellationToken); }
public void GetLockAsync_TwoLocksWithReleases_ReturnsCompletedTasks() { // Arrange var mutex = new AsyncMutex(); // Act/Assert var task = mutex.GetLockAsync(); Assert.True(task.IsCompleted); mutex.ReleaseLock(); var task2 = mutex.GetLockAsync(); Assert.True(task2.IsCompleted); }
public async Task GetLockAsync_TwoLocks_TriggersSecondWhenReleased() { // Arrange var mutex = new AsyncMutex(); // Act/Assert var task = mutex.GetLockAsync(); Assert.True(task.IsCompleted); var task2 = mutex.GetLockAsync(); Assert.False(task2.IsCompleted); mutex.ReleaseLock(); await task2; }
public void GetLockAsync_NoLock_ReturnsCompletedTask() { // Arrange var mutex = new AsyncMutex(); // Act var task = mutex.GetLockAsync(); // Assert Assert.True(task.IsCompleted); }
public async Task SendAsync(ReadOnlyMemory <byte> request, Action <IMemoryOwner <byte>, ResponseStatus> callback, ErrorMap?errorMap = null) { if (request.Length >= MaxDocSize) { throw new ValueToolargeException("Encoded document exceeds the 20MB document size limit."); } if (_disposed) { throw new ObjectDisposedException(nameof(MultiplexingConnection)); } var opaque = ByteConverter.ToUInt32(request.Span.Slice(HeaderOffsets.Opaque)); var state = new AsyncState(callback, opaque) { EndPoint = (IPEndPoint)EndPoint, ConnectionId = ConnectionId, ErrorMap = errorMap, LocalEndpoint = LocalEndPoint.ToString() }; _statesInFlight.Add(state, 75000); await _writeMutex.GetLockAsync().ConfigureAwait(false); try { #if NETCOREAPP2_1 || NETCOREAPP3_0 || NETSTANDARD2_1 await _stream.WriteAsync(request).ConfigureAwait(false); #else if (!MemoryMarshal.TryGetArray <byte>(request, out var arraySegment)) { // Fallback in case we can't use the more efficient TryGetArray method arraySegment = new ArraySegment <byte>(request.ToArray()); } await _stream.WriteAsync(arraySegment.Array, arraySegment.Offset, arraySegment.Count) .ConfigureAwait(false); #endif } catch (Exception e) { HandleDisconnect(e); } finally { _writeMutex.ReleaseLock(); } }
public async Task SendAsync(ReadOnlyMemory <byte> request, IOperation operation, ErrorMap?errorMap = null) { if (request.Length >= MaxDocSize) { throw new ValueToolargeException("Encoded document exceeds the 20MB document size limit."); } if (_disposed) { throw new ObjectDisposedException(nameof(MultiplexingConnection)); } var state = new AsyncState(operation) { EndPoint = (IPEndPoint)EndPoint, ConnectionId = ConnectionId, ErrorMap = errorMap, LocalEndpoint = _localEndPointString }; _statesInFlight.Add(state, 75000); await _writeMutex.GetLockAsync().ConfigureAwait(false); try { #if SPAN_SUPPORT await _stream.WriteAsync(request).ConfigureAwait(false); #else if (!MemoryMarshal.TryGetArray <byte>(request, out var arraySegment)) { // Fallback in case we can't use the more efficient TryGetArray method arraySegment = new ArraySegment <byte>(request.ToArray()); } await _stream.WriteAsync(arraySegment.Array, arraySegment.Offset, arraySegment.Count) .ConfigureAwait(false); #endif } catch (Exception e) { HandleDisconnect(e); } finally { _writeMutex.ReleaseLock(); } }