Browse Source

Fixed several potential deadlocks

tags/docs-0.9
RogueException 9 years ago
parent
commit
a2c9373ed6
10 changed files with 35 additions and 34 deletions
  1. +1
    -1
      src/Discord.Net.Commands/CommandService.cs
  2. +10
    -9
      src/Discord.Net/DiscordClient.cs
  3. +1
    -1
      src/Discord.Net/MessageQueue.cs
  4. +1
    -1
      src/Discord.Net/Models/Channel.cs
  5. +4
    -4
      src/Discord.Net/Net/Rest/BuiltInEngine.cs
  6. +1
    -1
      src/Discord.Net/Net/Rest/RestClient.cs
  7. +1
    -1
      src/Discord.Net/Net/Rest/SharpRestEngine.cs
  8. +2
    -2
      src/Discord.Net/Net/WebSockets/WS4NetEngine.cs
  9. +3
    -3
      src/Discord.Net/Net/WebSockets/WebSocket.cs
  10. +11
    -11
      src/Discord.Net/TaskManager.cs

+ 1
- 1
src/Discord.Net.Commands/CommandService.cs View File

@@ -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);
}); });
} }




+ 10
- 9
src/Discord.Net/DiscordClient.cs View File

@@ -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()
{
if (State == ConnectionState.Connected)
await ClientAPI.Send(new LogoutRequest()).ConfigureAwait(false);
await _taskManager.Stop(true).ConfigureAwait(false);
}
public Task Disconnect() => _taskManager.Stop(true);
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;


+ 1
- 1
src/Discord.Net/MessageQueue.cs View File

@@ -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);
} }


+ 1
- 1
src/Discord.Net/Models/Channel.cs View File

@@ -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)
{ {


+ 4
- 4
src/Discord.Net/Net/Rest/BuiltInEngine.cs View File

@@ -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);
} }
} }




+ 1
- 1
src/Discord.Net/Net/Rest/RestClient.cs View File

@@ -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);
} }




+ 1
- 1
src/Discord.Net/Net/Rest/SharpRestEngine.cs View File

@@ -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)
{ {


+ 2
- 2
src/Discord.Net/Net/WebSockets/WS4NetEngine.cs View File

@@ -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();
} }


+ 3
- 3
src/Discord.Net/Net/WebSockets/WebSocket.cs View File

@@ -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);
} }
} }




+ 11
- 11
src/Discord.Net/TaskManager.cs View File

@@ -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 (Exception ex) { await SignalError(ex); }
catch (AggregateException ex) { await SignalError(ex.InnerExceptions.First()).ConfigureAwait(false); }
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>


Loading…
Cancel
Save