From eafadf10c7d8fe51ca6af11aadef64f5f6bcf8e0 Mon Sep 17 00:00:00 2001
From: merry <git@mary.rs>
Date: Mon, 24 Oct 2022 00:51:54 +0100
Subject: [PATCH] Ryujinx.Tests.Unicorn: Implement IDisposable (#3794)

Dispose unicorn when done
---
 Ryujinx.Tests.Unicorn/UnicornAArch32.cs | 20 ++++++++++++++++++--
 Ryujinx.Tests.Unicorn/UnicornAArch64.cs | 20 ++++++++++++++++++--
 Ryujinx.Tests/Cpu/CpuTest.cs            |  6 ++++++
 Ryujinx.Tests/Cpu/CpuTest32.cs          |  6 ++++++
 4 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/Ryujinx.Tests.Unicorn/UnicornAArch32.cs b/Ryujinx.Tests.Unicorn/UnicornAArch32.cs
index e1efb52fec..e634e0d2aa 100644
--- a/Ryujinx.Tests.Unicorn/UnicornAArch32.cs
+++ b/Ryujinx.Tests.Unicorn/UnicornAArch32.cs
@@ -3,9 +3,10 @@ using System;
 
 namespace Ryujinx.Tests.Unicorn
 {
-    public class UnicornAArch32
+    public class UnicornAArch32 : IDisposable
     {
         internal readonly IntPtr uc;
+        private bool _isDisposed = false;
 
         public IndexedProperty<int, uint> R
         {
@@ -107,7 +108,22 @@ namespace Ryujinx.Tests.Unicorn
 
         ~UnicornAArch32()
         {
-            Interface.Checked(Native.Interface.uc_close(uc));
+            Dispose(false);
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_isDisposed)
+            {
+                Interface.Checked(Native.Interface.uc_close(uc));
+                _isDisposed = true;
+            }
         }
 
         public void RunForCount(ulong count)
diff --git a/Ryujinx.Tests.Unicorn/UnicornAArch64.cs b/Ryujinx.Tests.Unicorn/UnicornAArch64.cs
index 4453d18d00..c5d5540b1d 100644
--- a/Ryujinx.Tests.Unicorn/UnicornAArch64.cs
+++ b/Ryujinx.Tests.Unicorn/UnicornAArch64.cs
@@ -3,9 +3,10 @@ using System;
 
 namespace Ryujinx.Tests.Unicorn
 {
-    public class UnicornAArch64
+    public class UnicornAArch64 : IDisposable
     {
         internal readonly IntPtr uc;
+        private bool _isDisposed = false;
 
         public IndexedProperty<int, ulong> X
         {
@@ -96,7 +97,22 @@ namespace Ryujinx.Tests.Unicorn
 
         ~UnicornAArch64()
         {
-            Interface.Checked(Native.Interface.uc_close(uc));
+            Dispose(false);
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_isDisposed)
+            {
+                Interface.Checked(Native.Interface.uc_close(uc));
+                _isDisposed = true;
+            }
         }
 
         public void RunForCount(ulong count)
diff --git a/Ryujinx.Tests/Cpu/CpuTest.cs b/Ryujinx.Tests/Cpu/CpuTest.cs
index 5fe43dec4d..f983a03fb5 100644
--- a/Ryujinx.Tests/Cpu/CpuTest.cs
+++ b/Ryujinx.Tests/Cpu/CpuTest.cs
@@ -80,6 +80,12 @@ namespace Ryujinx.Tests.Cpu
         [TearDown]
         public void Teardown()
         {
+            if (_unicornAvailable)
+            {
+                _unicornEmu.Dispose();
+                _unicornEmu = null;
+            }
+
             _memory.DecrementReferenceCount();
             _context.Dispose();
             _ram.Dispose();
diff --git a/Ryujinx.Tests/Cpu/CpuTest32.cs b/Ryujinx.Tests/Cpu/CpuTest32.cs
index aaf0ecfb69..2c36396f9a 100644
--- a/Ryujinx.Tests/Cpu/CpuTest32.cs
+++ b/Ryujinx.Tests/Cpu/CpuTest32.cs
@@ -76,6 +76,12 @@ namespace Ryujinx.Tests.Cpu
         [TearDown]
         public void Teardown()
         {
+            if (_unicornAvailable)
+            {
+                _unicornEmu.Dispose();
+                _unicornEmu = null;
+            }
+
             _memory.DecrementReferenceCount();
             _context.Dispose();
             _ram.Dispose();