From 00ce9eea620652b97b4d3e8cd9218c6fccff8b1c Mon Sep 17 00:00:00 2001 From: Mary <me@thog.eu> Date: Tue, 29 Jun 2021 19:37:13 +0200 Subject: Fix disposing of IPC sessions server at emulation stop (#2334) --- Ryujinx.HLE/HOS/Services/ServerBase.cs | 41 ++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 7 deletions(-) (limited to 'Ryujinx.HLE/HOS/Services/ServerBase.cs') diff --git a/Ryujinx.HLE/HOS/Services/ServerBase.cs b/Ryujinx.HLE/HOS/Services/ServerBase.cs index c9d009a9..695394a5 100644 --- a/Ryujinx.HLE/HOS/Services/ServerBase.cs +++ b/Ryujinx.HLE/HOS/Services/ServerBase.cs @@ -4,6 +4,7 @@ using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Ipc; using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.HLE.HOS.Kernel.Threading; +using Ryujinx.HLE.HOS.Services.Sm; using System; using System.Buffers.Binary; using System.Collections.Generic; @@ -12,7 +13,7 @@ using System.Threading; namespace Ryujinx.HLE.HOS.Services { - class ServerBase + class ServerBase : IDisposable { // Must be the maximum value used by services (highest one know is the one used by nvservices = 0x8000). // Having a size that is too low will cause failures as data copy will fail if the receiving buffer is @@ -67,6 +68,9 @@ namespace Ryujinx.HLE.HOS.Services public void AddSessionObj(KServerSession serverSession, IpcService obj) { + // Ensure that the sever loop is running. + InitDone.WaitOne(); + _selfProcess.HandleTable.GenerateHandle(serverSession, out int serverSessionHandle); AddSessionObj(serverSessionHandle, obj); } @@ -86,14 +90,10 @@ namespace Ryujinx.HLE.HOS.Services _context.Syscall.ManageNamedPort("sm:", 50, out int serverPortHandle); AddPort(serverPortHandle, SmObjectFactory); - - InitDone.Set(); - } - else - { - InitDone.Dispose(); } + InitDone.Set(); + KThread thread = KernelStatic.GetCurrentThread(); ulong messagePtr = thread.TlsAddress; _context.Syscall.SetHeapSize(0x200000, out ulong heapAddr); @@ -153,6 +153,8 @@ namespace Ryujinx.HLE.HOS.Services _selfProcess.CpuMemory.Write(messagePtr + 0x8, heapAddr | ((ulong)PointerBufferSize << 48)); } } + + Dispose(); } private bool Process(int serverSessionHandle, ulong recvListAddr) @@ -349,5 +351,30 @@ namespace Ryujinx.HLE.HOS.Services return response; } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + foreach (IpcService service in _sessions.Values) + { + if (service is IDisposable disposableObj) + { + disposableObj.Dispose(); + } + + service.DestroyAtExit(); + } + + _sessions.Clear(); + + InitDone.Dispose(); + } + } + + public void Dispose() + { + Dispose(true); + } } } \ No newline at end of file -- cgit v1.2.3-70-g09d2