protected virtual void Dispose(bool Disposing) { if (Disposing && !Disposed) { //If there is still some thread running, disposing the objects is not //safe as the thread may try to access those resources. Instead, we set //the flag to have the Process disposed when all threads finishes. //Note: This may not happen if the guest code gets stuck on a infinite loop. if (TlsSlots.Count > 0) { ShouldDispose = true; Logging.Info($"Process {ProcessId} waiting all threads terminate..."); return; } Disposed = true; foreach (object Obj in HandleTable.Clear()) { if (Obj is KSession Session) { Session.Dispose(); } } ServiceNvDrv.Fds.DeleteProcess(this); ServiceNvDrv.NvMaps.DeleteProcess(this); ServiceNvDrv.NvMapsById.DeleteProcess(this); ServiceNvDrv.NvMapsFb.DeleteProcess(this); Scheduler.Dispose(); AppletState.Dispose(); SvcHandler.Dispose(); Memory.Dispose(); Logging.Info($"Process {ProcessId} exiting..."); } }
protected virtual void Dispose(bool Disposing) { if (Disposing && !Disposed) { if (NeedsHbAbi && Executables[0].FilePath.EndsWith(Homebrew.TemporaryNroSuffix)) { File.Delete(Executables[0].FilePath); } //If there is still some thread running, disposing the objects is not //safe as the thread may try to access those resources. Instead, we set //the flag to have the Process disposed when all threads finishes. //Note: This may not happen if the guest code gets stuck on a infinite loop. if (TlsSlots.Count > 0) { ShouldDispose = true; Ns.Log.PrintInfo(LogClass.Loader, $"Process {ProcessId} waiting all threads terminate..."); return; } Disposed = true; foreach (object Obj in HandleTable.Clear()) { if (Obj is KSession Session) { Session.Dispose(); } } INvDrvServices.UnloadProcess(this); AppletState.Dispose(); SvcHandler.Dispose(); Memory.Dispose(); Ns.Log.PrintInfo(LogClass.Loader, $"Process {ProcessId} exiting..."); } }