diff --git a/src/GameServiceWarden.Core/Games/ServiceDescriptor.cs b/src/GameServiceWarden.Core/Games/ServiceDescriptor.cs index 6db6b44..a3336df 100644 --- a/src/GameServiceWarden.Core/Games/ServiceDescriptor.cs +++ b/src/GameServiceWarden.Core/Games/ServiceDescriptor.cs @@ -130,7 +130,7 @@ namespace GameServiceWarden.Core.Games } catch (AggregateException e) { - e.Handle((exception) => exception is TaskCanceledException || exception is SocketException); //Task cancel for Windows, Socket for operation cancellation. + e.Handle((exception) => exception is TaskCanceledException || (exception is SocketException && exception.Message.Equals("Operation canceled"))); //Task cancel for Windows, Socket for operation cancellation. } try { @@ -140,7 +140,7 @@ namespace GameServiceWarden.Core.Games } catch (AggregateException e) { - e.Handle((exception) => exception is TaskCanceledException || exception is SocketException); //Same as above. + e.Handle((exception) => exception is TaskCanceledException || (exception is SocketException && exception.Message.Equals("Operation canceled"))); //Same as above. } stopToken.Dispose(); } diff --git a/src/GameServiceWarden.Core/UI/IPCMediator.cs b/src/GameServiceWarden.Core/UI/IPCMediator.cs index 5efb1de..9e9eee0 100644 --- a/src/GameServiceWarden.Core/UI/IPCMediator.cs +++ b/src/GameServiceWarden.Core/UI/IPCMediator.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.IO.Pipes; +using System.Net.Sockets; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -22,8 +23,10 @@ namespace GameServiceWarden.Core.UI public BlockingCollection<(string, CommunicableType, byte[])> RequestQueue { get; private set; } private volatile bool active; public bool IsRunning { get => active; } - private Task acceptTask; + private Task connectionTask; private CancellationTokenSource stopAcceptingToken; + private volatile NamedPipeServerStream connectingPipe; + public IPCMediator(string name) { this.name = name; @@ -37,7 +40,7 @@ namespace GameServiceWarden.Core.UI Logger.Log($"IPCMediator with name \"{name}\" opened."); active = true; stopAcceptingToken = new CancellationTokenSource(); - acceptTask = AcceptConnections(); + connectionTask = AcceptConnections(); Logger.Log($"IPCMediator \"{name}\" has begun asynchronously accepting interfaces.", LogLevel.DEBUG); } @@ -47,15 +50,16 @@ namespace GameServiceWarden.Core.UI Logger.Log("Closing IPC mediator."); active = false; stopAcceptingToken.Cancel(); + connectingPipe.Dispose(); + InitiateDisconnectAll("Closing GameServiceWarden.").Wait(); try { - if (!acceptTask.Wait(TIMEOUT)) throw new TimeoutException($"IPCMediator \"{name}\" was unable to stop accepting task within {TIMEOUT}ms."); + if (!connectionTask.Wait(TIMEOUT)) throw new TimeoutException($"IPCMediator \"{name}\" was unable to stop accepting task within {TIMEOUT}ms."); } catch (AggregateException e) { - e.Handle((exception) => exception is TaskCanceledException); + e.Handle((exception) => exception is TaskCanceledException || (exception is SocketException && exception.Message.Equals("Operation canceled"))); } - InitiateDisconnectAll("Closing IPC system.").Wait(); RequestQueue.CompleteAdding(); stopAcceptingToken.Dispose(); } @@ -110,10 +114,10 @@ namespace GameServiceWarden.Core.UI Logger.Log("Accepting Interface connections."); while (active) { - NamedPipeServerStream pipe = new NamedPipeServerStream(PipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); + connectingPipe = new NamedPipeServerStream(PipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); Logger.Log("Waiting for connection.", LogLevel.DEBUG); - await pipe.WaitForConnectionAsync(stopAcceptingToken.Token); - connectionTasks.Add(OnConnection(pipe)); + await connectingPipe.WaitForConnectionAsync(stopAcceptingToken.Token); + connectionTasks.Add(OnConnection(connectingPipe)); for (int i = 0; i < connectionTasks.Count; i++) { if (connectionTasks[i].IsCompleted) { diff --git a/tests/GameServiceWarden.Core.Tests/UI/IPCMediatorTest.cs b/tests/GameServiceWarden.Core.Tests/UI/IPCMediatorTest.cs index 0aeba6b..d6d5692 100644 --- a/tests/GameServiceWarden.Core.Tests/UI/IPCMediatorTest.cs +++ b/tests/GameServiceWarden.Core.Tests/UI/IPCMediatorTest.cs @@ -17,7 +17,7 @@ namespace GameServiceWarden.Core.Tests.UI public void Open_Closed_Opened() { //Given - const string NAME = "MEDIATOR"; + const string NAME = "Open_Closed_Opened"; IPCMediator mediator = new IPCMediator(NAME); //When mediator.Open(); @@ -29,7 +29,7 @@ namespace GameServiceWarden.Core.Tests.UI public void Open_AlreadyOpened_Exception() { //Given - const string NAME = "MEDIATOR"; + const string NAME = "Open_AlreadyOpened_Exception"; IPCMediator mediator = new IPCMediator(NAME); //When mediator.Open(); @@ -41,7 +41,7 @@ namespace GameServiceWarden.Core.Tests.UI public void Close_Opened_Closed() { //Given - const string NAME = "MEDIATOR"; + const string NAME = "Close_Opened_Closed"; IPCMediator mediator = new IPCMediator(NAME); //When mediator.Open();