public void AsyncLock_Locked_PreventsLockUntilUnlocked() { Test.Async(async () => { var mutex = new AsyncLock(); var task1HasLock = new TaskCompletionSource(); var task1Continue = new TaskCompletionSource(); var task1 = TaskShim.Run(async () => { using (await mutex.LockAsync()) { task1HasLock.SetResult(); await task1Continue.Task; } }); await task1HasLock.Task; var task2Start = Task.Factory.StartNew(async () => { await mutex.LockAsync(); }); var task2 = await task2Start; Assert.IsFalse(task2.IsCompleted); task1Continue.SetResult(); await task2; }); }
public void AsyncLock_Locked_PreventsLockUntilUnlocked() { AsyncContext.Run(async () => { var mutex = new AsyncLock(); var task1HasLock = new TaskCompletionSource(); var task1Continue = new TaskCompletionSource(); Task<IDisposable> task1LockTask = null; var task1 = Task.Run(async () => { task1LockTask = mutex.LockAsync(); using (await task1LockTask) { task1HasLock.SetResult(); await task1Continue.Task; } }); await task1HasLock.Task; Task<IDisposable> task2LockTask = null; var task2Start = Task.Factory.StartNew(async () => { task2LockTask = mutex.LockAsync(); await task2LockTask; }); var task2 = await task2Start; Assert.IsFalse(task2.IsCompleted); task1Continue.SetResult(); await task2; }); }
public WebSocket(DiscordClient client, JsonSerializer serializer, Logger logger) { _client = client; Logger = logger; _serializer = serializer; _lock = new AsyncLock(); _taskManager = new TaskManager(Cleanup); CancelToken = new CancellationToken(true); _connectedEvent = new ManualResetEventSlim(false); #if !DOTNET5_4 _engine = new WS4NetEngine(client.Config, _taskManager); #else _engine = new BuiltInEngine(client.Config); #endif _engine.BinaryMessage += (s, e) => { using (var compressed = new MemoryStream(e.Data, 2, e.Data.Length - 2)) using (var decompressed = new MemoryStream()) { using (var zlib = new DeflateStream(compressed, CompressionMode.Decompress)) zlib.CopyTo(decompressed); decompressed.Position = 0; using (var reader = new StreamReader(decompressed)) ProcessMessage(reader.ReadToEnd()).GetAwaiter().GetResult(); } }; _engine.TextMessage += (s, e) => ProcessMessage(e.Message).Wait(); }
public AudioClient(DiscordClient client, Server server, int id) { Id = id; _config = client.Config; Service = client.Services.Get<AudioService>(); Config = Service.Config; Serializer = client.Serializer; _gatewayState = (int)ConnectionState.Disconnected; //Logging Logger = client.Log.CreateLogger($"AudioClient #{id}"); //Async _taskManager = new TaskManager(Cleanup, false); _connectionLock = new AsyncLock(); CancelToken = new CancellationToken(true); //Networking if (Config.EnableMultiserver) { ClientAPI = new JsonRestClient(_config, DiscordConfig.ClientAPIUrl, client.Log.CreateLogger($"ClientAPI #{id}")); GatewaySocket = new GatewaySocket(_config, client.Serializer, client.Log.CreateLogger($"Gateway #{id}")); GatewaySocket.Connected += (s, e) => { if (_gatewayState == ConnectionState.Connecting) EndGatewayConnect(); }; } else GatewaySocket = client.GatewaySocket; GatewaySocket.ReceivedDispatch += (s, e) => OnReceivedEvent(e); VoiceSocket = new VoiceSocket(_config, Config, client.Serializer, client.Log.CreateLogger($"Voice #{id}")); VoiceSocket.Server = server; OutputStream = new OutStream(this); }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="endpoint"></param> /// <param name="holdUri"></param> /// <param name="conferenceId"></param> public QueueHoldConference(LocalEndpoint endpoint, string holdUri, string conferenceId = null) { this.sync = new AsyncLock(); this.endpoint = endpoint; this.holdUri = holdUri; this.conferenceId = conferenceId; }
public void MultipleWaits_NotifyAll_AllAreCompleted() { AsyncContext.Run(async () => { var mutex = new AsyncLock(); var cv = new AsyncConditionVariable(mutex); var key1 = await mutex.LockAsync(); var task1 = cv.WaitAsync(); var __ = task1.ContinueWith(_ => key1.Dispose()); var key2 = await mutex.LockAsync(); var task2 = cv.WaitAsync(); var ___ = task2.ContinueWith(_ => key2.Dispose()); await Task.Run(async () => { using (await mutex.LockAsync()) { cv.NotifyAll(); } }); await task1; await task2; }); }
private void Button_Click(object sender, RoutedEventArgs e) { var a = 1; var b = 1 + 1; var c = new StringBuilder(); var al = new AsyncLock(); }
public AudioClient(AudioService service, int clientId, Server server, GatewaySocket gatewaySocket, Logger logger) { Service = service; Id = clientId; GatewaySocket = gatewaySocket; Logger = logger; _connectionLock = new AsyncLock(); _serializer = new JsonSerializer(); _serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc; _serializer.Error += (s, e) => { e.ErrorContext.Handled = true; Logger.Error("Serialization Failed", e.ErrorContext.Error); }; GatewaySocket.ReceivedDispatch += OnReceivedDispatch; VoiceSocket = new VoiceWebSocket(service.Client, this, _serializer, logger); VoiceSocket.Server = server; /*_voiceSocket.Connected += (s, e) => RaiseVoiceConnected(); _voiceSocket.Disconnected += async (s, e) => { _voiceSocket.CurrentServerId; if (voiceServerId != null) _gatewaySocket.SendLeaveVoice(voiceServerId.Value); await _voiceSocket.Disconnect().ConfigureAwait(false); RaiseVoiceDisconnected(socket.CurrentServerId.Value, e); if (e.WasUnexpected) await socket.Reconnect().ConfigureAwait(false); };*/ /*_voiceSocket.IsSpeaking += (s, e) => { if (_voiceSocket.State == WebSocketState.Connected) { var user = _users[e.UserId, socket.CurrentServerId]; bool value = e.IsSpeaking; if (user.IsSpeaking != value) { user.IsSpeaking = value; var channel = _channels[_voiceSocket.CurrentChannelId]; RaiseUserIsSpeaking(user, channel, value); if (Config.TrackActivity) user.UpdateActivity(); } } };*/ /*this.Connected += (s, e) => { _voiceSocket.ParentCancelToken = _cancelToken; };*/ }
public void AsyncLock_Unlocked_SynchronouslyPermitsLock() { var mutex = new AsyncLock(); var lockTask = mutex.LockAsync(); Assert.IsTrue(lockTask.IsCompleted); Assert.IsFalse(lockTask.IsFaulted); Assert.IsFalse(lockTask.IsCanceled); }
public VoiceBuffer(int frameCount, int frameSize) { _frameSize = frameSize; _frameCount = frameCount; _bufferSize = _frameSize * _frameCount; _readCursor = 0; _writeCursor = 0; _buffer = new byte[_bufferSize]; _blankFrame = new byte[_frameSize]; _notOverflowEvent = new ManualResetEventSlim(); //Notifies when an overflow is solved _lock = new AsyncLock(); }
internal ModuleManager(DiscordClient client, IModule instance, string name, ModuleFilter filterType) { Client = client; Instance = instance; Name = name; FilterType = filterType; Id = name.ToLowerInvariant(); _lock = new AsyncLock(); _allowAll = filterType == ModuleFilter.None; _useServerWhitelist = filterType.HasFlag(ModuleFilter.ServerWhitelist); _useChannelWhitelist = filterType.HasFlag(ModuleFilter.ChannelWhitelist); _allowPrivate = filterType.HasFlag(ModuleFilter.AlwaysAllowPrivate); _enabledServers = new ConcurrentDictionary<ulong, Server>(); _enabledChannels = new ConcurrentDictionary<ulong, Channel>(); _indirectServers = new ConcurrentDictionary<ulong, int>(); if (_allowAll || _useServerWhitelist) //Server-only events { client.ChannelCreated += (s, e) => { if (e.Server != null && HasServer(e.Server)) ChannelCreated(s, e); }; client.UserVoiceStateUpdated += (s, e) => { if (HasServer(e.Server)) UserVoiceStateUpdated(s, e); }; } client.ChannelDestroyed += (s, e) => { if (HasChannel(e.Channel)) ChannelDestroyed(s, e); }; client.ChannelUpdated += (s, e) => { if (HasChannel(e.Channel)) ChannelUpdated(s, e); }; client.MessageReceived += (s, e) => { if (HasChannel(e.Channel)) MessageReceived(s, e); }; client.MessageSent += (s, e) => { if (HasChannel(e.Channel)) MessageSent(s, e); }; client.MessageDeleted += (s, e) => { if (HasChannel(e.Channel)) MessageDeleted(s, e); }; client.MessageUpdated += (s, e) => { if (HasChannel(e.Channel)) MessageUpdated(s, e); }; client.MessageAcknowledged += (s, e) => { if (HasChannel(e.Channel)) MessageReadRemotely(s, e); }; client.RoleCreated += (s, e) => { if (HasIndirectServer(e.Server)) RoleCreated(s, e); }; client.RoleUpdated += (s, e) => { if (HasIndirectServer(e.Server)) RoleUpdated(s, e); }; client.RoleDeleted += (s, e) => { if (HasIndirectServer(e.Server)) RoleDeleted(s, e); }; client.LeftServer += (s, e) => { if (HasIndirectServer(e.Server)) { DisableServer(e.Server); LeftServer(s, e); } }; client.ServerUpdated += (s, e) => { if (HasIndirectServer(e.Server)) ServerUpdated(s, e); }; client.ServerUnavailable += (s, e) => { if (HasIndirectServer(e.Server)) ServerUnavailable(s, e); }; client.ServerAvailable += (s, e) => { if (HasIndirectServer(e.Server)) ServerAvailable(s, e); }; client.UserJoined += (s, e) => { if (HasIndirectServer(e.Server)) UserJoined(s, e); }; client.UserLeft += (s, e) => { if (HasIndirectServer(e.Server)) UserLeft(s, e); }; client.UserUpdated += (s, e) => { if (HasIndirectServer(e.Server)) UserUpdated(s, e); }; client.UserIsTypingUpdated += (s, e) => { if (HasChannel(e.Channel)) UserIsTypingUpdated(s, e); }; //TODO: We aren't getting events from UserPresence if AllowPrivate is enabled, but the server we know that user through isn't on the whitelist client.UserPresenceUpdated += (s, e) => { if (HasIndirectServer(e.Server)) UserPresenceUpdated(s, e); }; client.UserBanned += (s, e) => { if (HasIndirectServer(e.Server)) UserBanned(s, e); }; client.UserUnbanned += (s, e) => { if (HasIndirectServer(e.Server)) UserUnbanned(s, e); }; }
public void WaitAsync_WithoutNotify_IsNotCompleted() { Test.Async(async () => { var mutex = new AsyncLock(); var cv = new AsyncConditionVariable(mutex); await mutex.LockAsync(); var task = cv.WaitAsync(); await AssertEx.NeverCompletesAsync(task); }); }
public BuiltInEngine(DiscordConfig config, string baseUrl, ILogger logger) { _config = config; _baseUrl = baseUrl; _logger = logger; _rateLimitLock = new AsyncLock(); _client = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip, UseCookies = false, UseProxy = false }); _client.DefaultRequestHeaders.Add("accept", "*/*"); _client.DefaultRequestHeaders.Add("accept-encoding", "gzip,deflate"); _client.DefaultRequestHeaders.Add("user-agent", config.UserAgent); }
public RestSharpEngine(DiscordConfig config, string baseUrl, Logger logger) { _config = config; Logger = logger; _rateLimitLock = new AsyncLock(); _client = new RestSharpClient(baseUrl) { PreAuthenticate = false, ReadWriteTimeout = _config.RestTimeout, UserAgent = config.UserAgent }; _client.Proxy = null; _client.RemoveDefaultParameter("Accept"); _client.AddDefaultHeader("accept", "*/*"); _client.AddDefaultHeader("accept-encoding", "gzip,deflate"); }
public void WaitAsync_Notified_IsCompleted() { Test.Async(async () => { var mutex = new AsyncLock(); var cv = new AsyncConditionVariable(mutex); await mutex.LockAsync(); var task = cv.WaitAsync(); await TaskShim.Run(async () => { using (await mutex.LockAsync()) { cv.Notify(); } }); await task; }); }
public void AsyncLock_DoubleDispose_OnlyPermitsOneTask() { AsyncContext.Run(async () => { var mutex = new AsyncLock(); var task1HasLock = new TaskCompletionSource(); var task1Continue = new TaskCompletionSource(); Task<IDisposable> lockTask = null; await Task.Run(async () => { lockTask = mutex.LockAsync(); var key = await lockTask; key.Dispose(); key.Dispose(); }); Task<IDisposable> task1LockTask = null; var task1 = Task.Run(async () => { task1LockTask = mutex.LockAsync(); using (await task1LockTask) { task1HasLock.SetResult(); await task1Continue.Task; } }); await task1HasLock.Task; Task<IDisposable> task2LockTask = null; var task2Start = Task.Factory.StartNew(async () => { task2LockTask = mutex.LockAsync(); await task2LockTask; }); var task2 = await task2Start; Assert.IsFalse(task2.IsCompleted); task1Continue.SetResult(); await task2; }); }
public void WaitAsync_AfterNotify_IsNotCompleted() { Test.Async(async () => { var mutex = new AsyncLock(); var cv = new AsyncConditionVariable(mutex); await TaskShim.Run(async () => { using (await mutex.LockAsync()) { cv.Notify(); } }); await mutex.LockAsync(); var task = cv.WaitAsync(); await AssertEx.NeverCompletesAsync(task); }); }
public AudioClient(DiscordClient client, Server server, int id) { Id = id; Service = client.GetService<AudioService>(); Config = Service.Config; Serializer = client.Serializer; _gatewayState = (int)ConnectionState.Disconnected; //Logging Logger = client.Log.CreateLogger($"AudioClient #{id}"); //Async _taskManager = new TaskManager(Cleanup, false); _connectionLock = new AsyncLock(); CancelToken = new CancellationToken(true); //Networking _config = client.Config; GatewaySocket = client.GatewaySocket; GatewaySocket.ReceivedDispatch += (s, e) => OnReceivedEvent(e); VoiceSocket = new VoiceSocket(_config, Config, client.Serializer, client.Log.CreateLogger($"Voice #{id}")); VoiceSocket.Server = server; OutputStream = new OutStream(this); }
public void AsyncLock_DoubleDispose_OnlyPermitsOneTask() { Test.Async(async () => { var mutex = new AsyncLock(); var task1HasLock = new TaskCompletionSource(); var task1Continue = new TaskCompletionSource(); await TaskShim.Run(async () => { var key = await mutex.LockAsync(); key.Dispose(); key.Dispose(); }); var task1 = TaskShim.Run(async () => { using (await mutex.LockAsync()) { task1HasLock.SetResult(); await task1Continue.Task; } }); await task1HasLock.Task; var task2Start = Task.Factory.StartNew(async () => { await mutex.LockAsync(); }); var task2 = await task2Start; Assert.IsFalse(task2.IsCompleted); task1Continue.SetResult(); await task2; }); }
public DebugView(AsyncLock mutex) { _mutex = mutex; }
/// <summary> /// Creates the key for a lock. /// </summary> /// <param name="asyncLock">The lock to release. May not be <c>null</c>.</param> public Key(AsyncLock asyncLock) { _asyncLock = asyncLock; }
public void Id_IsNotZero() { var mutex = new AsyncLock(); Assert.AreNotEqual(0, mutex.Id); }
public RecursiveAsyncLock() { mutex = new AsyncLock(); }
/// <summary> /// Creates an async-compatible condition variable associated with an async-compatible lock. /// </summary> /// <param name="asyncLock">The lock associated with this condition variable.</param> public AsyncConditionVariable(AsyncLock asyncLock) : this(asyncLock, new DefaultAsyncWaitQueue<object>()) { }
/// <summary> /// Constructs a new monitor. /// </summary> public AsyncMonitor(IAsyncWaitQueue <IDisposable> lockQueue, IAsyncWaitQueue <object> conditionVariableQueue) { _asyncLock = new AsyncLock(lockQueue); _conditionVariable = new AsyncConditionVariable(_asyncLock, conditionVariableQueue); }
/// <summary> /// Creates an async-compatible condition variable associated with an async-compatible lock. /// </summary> /// <param name="asyncLock">The lock associated with this condition variable.</param> public AsyncConditionVariable(AsyncLock asyncLock) : this(asyncLock, new DefaultAsyncWaitQueue <object>()) { }
/// <summary> Initializes a new instance of the DiscordClient class. </summary> public DiscordClient(DiscordConfig config = null) { Config = config ?? new DiscordConfig(); Config.Lock(); State = (int)ConnectionState.Disconnected; Status = UserStatus.Online; //Logging Log = new LogManager(this); Logger = Log.CreateLogger("Discord"); //Async _taskManager = new TaskManager(Cleanup); _connectionLock = new AsyncLock(); _disconnectedEvent = new ManualResetEvent(true); _connectedEvent = new ManualResetEventSlim(false); CancelToken = new CancellationToken(true); //Cache _servers = new ConcurrentDictionary<ulong, Server>(); _channels = new ConcurrentDictionary<ulong, Channel>(); _privateChannels = new ConcurrentDictionary<ulong, Channel>(); //Serialization _serializer = new JsonSerializer(); _serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc; #if TEST_RESPONSES _serializer.CheckAdditionalContent = true; _serializer.MissingMemberHandling = MissingMemberHandling.Error; #else _serializer.Error += (s, e) => { e.ErrorContext.Handled = true; Logger.Error("Serialization Failed", e.ErrorContext.Error); }; #endif //Networking ClientAPI = new RestClient(Config, DiscordConfig.ClientAPIUrl, Log.CreateLogger("ClientAPI")); StatusAPI = new RestClient(Config, DiscordConfig.StatusAPIUrl, Log.CreateLogger("StatusAPI")); GatewaySocket = new GatewaySocket(this, _serializer, Log.CreateLogger("Gateway")); GatewaySocket.Connected += (s, e) => { if (State == ConnectionState.Connecting) EndConnect(); }; GatewaySocket.Disconnected += (s, e) => OnDisconnected(e.WasUnexpected, e.Exception); GatewaySocket.ReceivedDispatch += (s, e) => OnReceivedEvent(e); if (Config.UseMessageQueue) MessageQueue = new MessageQueue(this, Log.CreateLogger("MessageQueue")); //Extensibility Services = new ServiceManager(this); //Import/Export //_messageImporter = new JsonSerializer(); //_messageImporter.ContractResolver = new Message.ImportResolver(); }
/// <summary> /// Constructs a new monitor. /// </summary> public AsyncMonitor(IAsyncWaitQueue <IDisposable> lockQueue, IAsyncWaitQueue <object> conditionVariableQueue) { _asyncLock = new AsyncLock(lockQueue); _conditionVariable = new AsyncConditionVariable(_asyncLock, conditionVariableQueue); //Enlightenment.Trace.AsyncMonitor_Created(_asyncLock, _conditionVariable); }
/// <summary> /// Creates an async-compatible condition variable associated with an async-compatible lock. /// </summary> /// <param name="asyncLock">The lock associated with this condition variable.</param> /// <param name="queue">The wait queue used to manage waiters. This may be <c>null</c> to use a default (FIFO) queue.</param> internal AsyncConditionVariable(AsyncLock asyncLock, IAsyncWaitQueue <object> queue) { _asyncLock = asyncLock; _queue = queue ?? new DefaultAsyncWaitQueue <object>(); _mutex = new object(); }
/// <summary> /// Constructs a new monitor. /// </summary> public AsyncMonitor(IAsyncWaitQueue<IDisposable> lockQueue, IAsyncWaitQueue<object> conditionVariableQueue) { _asyncLock = new AsyncLock(lockQueue); _conditionVariable = new AsyncConditionVariable(_asyncLock, conditionVariableQueue); //Enlightenment.Trace.AsyncMonitor_Created(_asyncLock, _conditionVariable); }
internal TaskManager(bool stopOnCompletion) { _lock = new AsyncLock(); StopOnCompletion = stopOnCompletion; }
/// <summary> /// Creates an async-compatible condition variable associated with an async-compatible lock. /// </summary> /// <param name="asyncLock">The lock associated with this condition variable.</param> /// <param name="queue">The wait queue used to manage waiters.</param> public AsyncConditionVariable(AsyncLock asyncLock, IAsyncWaitQueue<object> queue) { _asyncLock = asyncLock; _queue = queue; _mutex = new object(); }
/// <summary> /// Creates an async-compatible condition variable associated with an async-compatible lock. /// </summary> /// <param name="asyncLock">The lock associated with this condition variable.</param> /// <param name="queue">The wait queue used to manage waiters.</param> public AsyncConditionVariable(AsyncLock asyncLock, IAsyncWaitQueue <object> queue) { _asyncLock = asyncLock; _queue = queue; _mutex = new object(); }
public async Task AsyncLock_DoesNotPermitRecursiveWaits() { var mutex = new AsyncLock(); var key = await mutex.LockAsync(); var waiter = mutex.LockAsync().AsTask(); Assert.IsFalse(waiter.Wait(1000)); key.Dispose(); }
/// <summary> /// The Lock mechanism designed for standard using blocks. This lock is thread and interprocess safe. /// You can create and use it from anywhere. /// </summary> /// <param name="pollInterval">The frequency of polling the termination of the mutex-thread.</param> /// <returns>The IDisposable await-able Task.</returns> public async Task <IDisposable> LockAsync(CancellationToken cancellationToken = default, int pollInterval = 100) { Exception inner = null; try { if (IsQuitPending) { throw new OperationCanceledException($"{nameof(AsyncMutex)}.{nameof(AsyncMutex.LockAsync)} failed because quit is pending on: {ShortName}."); } // Local lock for thread safety. await AsyncLock.LockAsync(cancellationToken).ConfigureAwait(false); if (IsAlive) { throw new InvalidOperationException("Thread should not be alive."); } MutexThread = new Thread(new ParameterizedThreadStart(HoldLock)) { Name = $"{nameof(MutexThread)}" }; MutexThread.Start(cancellationToken); ChangeStatus(AsyncLockStatus.StatusAcquiring, AsyncLockStatus.StatusReady); // Thread is running from now. try { // Create the mutex and acquire it. await SetCommandAsync(1, cancellationToken, pollInterval).ConfigureAwait(false); } catch (Exception ex) { Logger.LogWarning(ex); // If the thread is still alive we must stop it StopThread(); ChangeStatus(AsyncLockStatus.StatusReady, AsyncLockStatus.StatusAcquiring); throw ex; } ChangeStatus(AsyncLockStatus.StatusAcquired, AsyncLockStatus.StatusAcquiring); return(new Key(this)); } catch (TaskCanceledException) { // Let it go. } catch (AbandonedMutexException) { // abandoned mutexes are still acquired, we just need // to handle the exception and treat it as acquisition Logger.LogWarning($"{nameof(AbandonedMutexException)} in {ShortName}."); return(new Key(this)); } catch (Exception ex) { Logger.LogError($"{ex.ToTypeMessageString()} in {ShortName}."); inner = ex; // Let it go. } // Release the local lock. AsyncLock.ReleaseLock(); throw new IOException($"Could not acquire system wide mutex on {ShortName}.", inner); }
public RecursiveAsyncLock(IAsyncWaitQueue<IDisposable> queue) { mutex = new AsyncLock(queue); }
/// <summary> /// Creates an async-compatible condition variable associated with an async-compatible lock. /// </summary> /// <param name="asyncLock">The lock associated with this condition variable.</param> public AsyncConditionVariable(AsyncLock asyncLock) : this(asyncLock, null) { }