Fixed several potential deadlocks
This commit is contained in:
@@ -62,7 +62,7 @@ namespace Discord.Commands
|
|||||||
await replyChannel.SendMessage("Unable to display help: Unknown command.").ConfigureAwait(false);
|
await replyChannel.SendMessage("Unable to display help: Unknown command.").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else //Show general help
|
else //Show general help
|
||||||
await ShowGeneralHelp(e.User, e.Channel, replyChannel);
|
await ShowGeneralHelp(e.User, e.Channel, replyChannel).ConfigureAwait(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (await _connectionLock.LockAsync())
|
using (await _connectionLock.LockAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
if (State != ConnectionState.Disconnected)
|
if (State != ConnectionState.Disconnected)
|
||||||
await Disconnect().ConfigureAwait(false);
|
await Disconnect().ConfigureAwait(false);
|
||||||
@@ -218,7 +218,7 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await _taskManager.SignalError(ex);
|
await _taskManager.SignalError(ex).ConfigureAwait(false);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,19 +268,20 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Disconnects from the Discord server, canceling any pending requests. </summary>
|
/// <summary> Disconnects from the Discord server, canceling any pending requests. </summary>
|
||||||
public async Task Disconnect()
|
public Task Disconnect() => _taskManager.Stop(true);
|
||||||
{
|
|
||||||
if (State == ConnectionState.Connected)
|
|
||||||
await ClientAPI.Send(new LogoutRequest()).ConfigureAwait(false);
|
|
||||||
await _taskManager.Stop(true).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
private async Task Cleanup()
|
private async Task Cleanup()
|
||||||
{
|
{
|
||||||
|
var oldState = State;
|
||||||
State = ConnectionState.Disconnecting;
|
State = ConnectionState.Disconnecting;
|
||||||
|
|
||||||
|
if (oldState == ConnectionState.Connected)
|
||||||
|
await ClientAPI.Send(new LogoutRequest()).ConfigureAwait(false);
|
||||||
|
|
||||||
if (Config.UseMessageQueue)
|
if (Config.UseMessageQueue)
|
||||||
MessageQueue.Clear();
|
MessageQueue.Clear();
|
||||||
|
|
||||||
await GatewaySocket.Disconnect();
|
|
||||||
|
await GatewaySocket.Disconnect().ConfigureAwait(false);
|
||||||
ClientAPI.Token = null;
|
ClientAPI.Token = null;
|
||||||
GatewaySocket.Token = null;
|
GatewaySocket.Token = null;
|
||||||
GatewaySocket.SessionId = null;
|
GatewaySocket.SessionId = null;
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ namespace Discord.Net
|
|||||||
|
|
||||||
IQueuedAction queuedAction;
|
IQueuedAction queuedAction;
|
||||||
while (_pendingActions.TryDequeue(out queuedAction))
|
while (_pendingActions.TryDequeue(out queuedAction))
|
||||||
await queuedAction.Do(this);
|
await queuedAction.Do(this).ConfigureAwait(false);
|
||||||
|
|
||||||
await Task.Delay(interval).ConfigureAwait(false);
|
await Task.Delay(interval).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ namespace Discord
|
|||||||
public async Task<Message> SendFile(string filePath)
|
public async Task<Message> SendFile(string filePath)
|
||||||
{
|
{
|
||||||
using (var stream = File.OpenRead(filePath))
|
using (var stream = File.OpenRead(filePath))
|
||||||
return await SendFile(Path.GetFileName(filePath), stream);
|
return await SendFile(Path.GetFileName(filePath), stream).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
public async Task<Message> SendFile(string filename, Stream stream)
|
public async Task<Message> SendFile(string filename, Stream stream)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace Discord.Net.Rest
|
|||||||
{
|
{
|
||||||
if (json != null)
|
if (json != null)
|
||||||
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
|
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||||
return await Send(request, cancelToken);
|
return await Send(request, cancelToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async Task<string> SendFile(string method, string path, string filename, Stream stream, CancellationToken cancelToken)
|
public async Task<string> SendFile(string method, string path, string filename, Stream stream, CancellationToken cancelToken)
|
||||||
@@ -68,7 +68,7 @@ namespace Discord.Net.Rest
|
|||||||
var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture));
|
var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture));
|
||||||
content.Add(new StreamContent(File.OpenRead(path)), "file", filename);
|
content.Add(new StreamContent(File.OpenRead(path)), "file", filename);
|
||||||
request.Content = content;
|
request.Content = content;
|
||||||
return await Send(request, cancelToken);
|
return await Send(request, cancelToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private async Task<string> Send(HttpRequestMessage request, CancellationToken cancelToken)
|
private async Task<string> Send(HttpRequestMessage request, CancellationToken cancelToken)
|
||||||
@@ -103,7 +103,7 @@ namespace Discord.Net.Rest
|
|||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
if (now >= _rateLimitTime)
|
if (now >= _rateLimitTime)
|
||||||
{
|
{
|
||||||
using (await _rateLimitLock.LockAsync())
|
using (await _rateLimitLock.LockAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
if (now >= _rateLimitTime)
|
if (now >= _rateLimitTime)
|
||||||
{
|
{
|
||||||
@@ -120,7 +120,7 @@ namespace Discord.Net.Rest
|
|||||||
else if (statusCode < 200 || statusCode >= 300) //2xx = Success
|
else if (statusCode < 200 || statusCode >= 300) //2xx = Success
|
||||||
throw new HttpException(response.StatusCode);
|
throw new HttpException(response.StatusCode);
|
||||||
else
|
else
|
||||||
return await response.Content.ReadAsStringAsync();
|
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ namespace Discord.Net.Rest
|
|||||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
OnSendingRequest(request);
|
OnSendingRequest(request);
|
||||||
var results = await SendFile(request, false);
|
var results = await SendFile(request, false).ConfigureAwait(false);
|
||||||
OnSentRequest(request, null, null, results.Milliseconds);
|
OnSentRequest(request, null, null, results.Milliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ namespace Discord.Net.Rest
|
|||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
if (now >= _rateLimitTime)
|
if (now >= _rateLimitTime)
|
||||||
{
|
{
|
||||||
using (await _rateLimitLock.LockAsync())
|
using (await _rateLimitLock.LockAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
if (now >= _rateLimitTime)
|
if (now >= _rateLimitTime)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ namespace Discord.Net.WebSockets
|
|||||||
|
|
||||||
private async void OnWebSocketError(object sender, ErrorEventArgs e)
|
private async void OnWebSocketError(object sender, ErrorEventArgs e)
|
||||||
{
|
{
|
||||||
await _taskManager.SignalError(e.Exception);
|
await _taskManager.SignalError(e.Exception).ConfigureAwait(false);
|
||||||
_waitUntilConnect.Set();
|
_waitUntilConnect.Set();
|
||||||
_waitUntilDisconnect.Set();
|
_waitUntilDisconnect.Set();
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ namespace Discord.Net.WebSockets
|
|||||||
ex = new WebSocketException((e as ClosedEventArgs).Code, (e as ClosedEventArgs).Reason);
|
ex = new WebSocketException((e as ClosedEventArgs).Code, (e as ClosedEventArgs).Reason);
|
||||||
else
|
else
|
||||||
ex = new Exception("Connection lost");
|
ex = new Exception("Connection lost");
|
||||||
await _taskManager.SignalError(ex);
|
await _taskManager.SignalError(ex).ConfigureAwait(false);
|
||||||
_waitUntilConnect.Set();
|
_waitUntilConnect.Set();
|
||||||
_waitUntilDisconnect.Set();
|
_waitUntilDisconnect.Set();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ namespace Discord.Net.WebSockets
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (await _lock.LockAsync())
|
using (await _lock.LockAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
await _taskManager.Stop().ConfigureAwait(false);
|
await _taskManager.Stop().ConfigureAwait(false);
|
||||||
_taskManager.ClearException();
|
_taskManager.ClearException();
|
||||||
@@ -90,7 +90,7 @@ namespace Discord.Net.WebSockets
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
//TODO: Should this be inside the lock?
|
//TODO: Should this be inside the lock?
|
||||||
await _taskManager.SignalError(ex);
|
await _taskManager.SignalError(ex).ConfigureAwait(false);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ namespace Discord.Net.WebSockets
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await _taskManager.SignalError(ex);
|
await _taskManager.SignalError(ex).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace Discord
|
|||||||
if (task != null)
|
if (task != null)
|
||||||
await Stop().ConfigureAwait(false);
|
await Stop().ConfigureAwait(false);
|
||||||
|
|
||||||
using (await _lock.LockAsync())
|
using (await _lock.LockAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
_cancelSource = cancelSource;
|
_cancelSource = cancelSource;
|
||||||
|
|
||||||
@@ -67,14 +67,14 @@ namespace Discord
|
|||||||
|
|
||||||
//Signal the rest of the tasks to stop
|
//Signal the rest of the tasks to stop
|
||||||
if (firstTask.Exception != null)
|
if (firstTask.Exception != null)
|
||||||
await SignalError(firstTask.Exception);
|
await SignalError(firstTask.Exception).ConfigureAwait(false);
|
||||||
else
|
else
|
||||||
await SignalStop();
|
await SignalStop().ConfigureAwait(false);
|
||||||
|
|
||||||
//Wait for the other tasks, and signal their errors too just in case
|
//Wait for the other tasks, and signal their errors too just in case
|
||||||
try { await allTasks.ConfigureAwait(false); }
|
try { await allTasks.ConfigureAwait(false); }
|
||||||
catch (AggregateException ex) { await SignalError(ex.InnerExceptions.First()); }
|
catch (AggregateException ex) { await SignalError(ex.InnerExceptions.First()).ConfigureAwait(false); }
|
||||||
catch (Exception ex) { await SignalError(ex); }
|
catch (Exception ex) { await SignalError(ex).ConfigureAwait(false); }
|
||||||
|
|
||||||
//Run the cleanup function within our lock
|
//Run the cleanup function within our lock
|
||||||
if (_stopAction != null)
|
if (_stopAction != null)
|
||||||
@@ -89,7 +89,7 @@ namespace Discord
|
|||||||
|
|
||||||
public async Task SignalStop(bool isExpected = false)
|
public async Task SignalStop(bool isExpected = false)
|
||||||
{
|
{
|
||||||
using (await _lock.LockAsync())
|
using (await _lock.LockAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
if (isExpected)
|
if (isExpected)
|
||||||
_wasStopExpected = true;
|
_wasStopExpected = true;
|
||||||
@@ -104,7 +104,7 @@ namespace Discord
|
|||||||
public async Task Stop(bool isExpected = false)
|
public async Task Stop(bool isExpected = false)
|
||||||
{
|
{
|
||||||
Task task;
|
Task task;
|
||||||
using (await _lock.LockAsync())
|
using (await _lock.LockAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
if (isExpected)
|
if (isExpected)
|
||||||
_wasStopExpected = true;
|
_wasStopExpected = true;
|
||||||
@@ -116,12 +116,12 @@ namespace Discord
|
|||||||
if (!_cancelSource.IsCancellationRequested && _cancelSource != null)
|
if (!_cancelSource.IsCancellationRequested && _cancelSource != null)
|
||||||
_cancelSource.Cancel();
|
_cancelSource.Cancel();
|
||||||
}
|
}
|
||||||
await task;
|
await task.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SignalError(Exception ex)
|
public async Task SignalError(Exception ex)
|
||||||
{
|
{
|
||||||
using (await _lock.LockAsync())
|
using (await _lock.LockAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
if (_stopReason != null) return;
|
if (_stopReason != null) return;
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ namespace Discord
|
|||||||
public async Task Error(Exception ex)
|
public async Task Error(Exception ex)
|
||||||
{
|
{
|
||||||
Task task;
|
Task task;
|
||||||
using (await _lock.LockAsync())
|
using (await _lock.LockAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
if (_stopReason != null) return;
|
if (_stopReason != null) return;
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ namespace Discord
|
|||||||
_cancelSource.Cancel();
|
_cancelSource.Cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await task;
|
await task.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Throws an exception if one was captured. </summary>
|
/// <summary> Throws an exception if one was captured. </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user