[Applications.Common] Increment the reference counter on SafeHandle instances (#4691)
authorhjhun <36876573+hjhun@users.noreply.github.com>
Mon, 31 Oct 2022 02:13:39 +0000 (11:13 +0900)
committerGitHub <noreply@github.com>
Mon, 31 Oct 2022 02:13:39 +0000 (11:13 +0900)
* Increment the reference counter on SafeHandle instances.

To prevent the common language runtime from reclaiming memory used by
a handle, this patch adds calling DangerousAddRef() before calling
DangerousGetHandle().

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Modify implementation of using SafeHandle

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Remove unnecesary blank line

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/Tizen.Applications.Common/Tizen.Applications.RPCPort/Parcel.cs
src/Tizen.Applications.Common/Tizen.Applications/AppControl.cs
src/Tizen.Applications.Common/Tizen.Applications/Bundle.cs

index 99f6c349b69972486035df1a31d1640101ca6f87..c1dd827e3b2aaf04006ed14d62b9f7a50a90d64b 100755 (executable)
@@ -425,7 +425,13 @@ namespace Tizen.Applications.RPCPort
         {
             Interop.LibRPCPort.Parcel.ReadBundle(_handle, out IntPtr b);
 
-            return new Bundle(new SafeBundleHandle(b, true));
+            Bundle bundle = null;
+            using (SafeBundleHandle safeBundleHandle = new SafeBundleHandle(b, true))
+            {
+                bundle = new Bundle(safeBundleHandle);
+            }
+
+            return bundle;
         }
 
         /// <summary>
index 20ead07c4a3b4b4d1ae898cea325a9a911f0ca09..4f911a0b275a189bda4231b45be614b3a4abdc59 100755 (executable)
@@ -108,13 +108,34 @@ namespace Tizen.Applications
         {
             if (handle == null)
             {
-                throw new ArgumentNullException("handle");
+                throw new ArgumentNullException(nameof(handle));
             }
 
-            Interop.AppControl.ErrorCode err = Interop.AppControl.DangerousClone(out _handle, handle.DangerousGetHandle());
-            if (err != Interop.AppControl.ErrorCode.None)
+            if (handle.IsInvalid)
             {
-                throw new InvalidOperationException("Failed to clone the appcontrol handle. Err = " + err);
+                throw new ArgumentNullException(nameof(handle), "handle is invalid");
+            }
+
+            bool mustRelease = false;
+            try
+            {
+                handle.DangerousAddRef(ref mustRelease);
+                Interop.AppControl.ErrorCode err = Interop.AppControl.DangerousClone(out _handle, handle.DangerousGetHandle());
+                if (err != Interop.AppControl.ErrorCode.None)
+                {
+                    throw new InvalidOperationException("Failed to clone the appcontrol handle. Err = " + err);
+                }
+            }
+            catch (ObjectDisposedException e)
+            {
+                throw new ArgumentNullException(nameof(handle), e.Message);
+            }
+            finally
+            {
+                if (mustRelease)
+                {
+                    handle.DangerousRelease();
+                }
             }
         }
 
index 791cfad72ba7e86ff0552928b49bc47341a98f22..3cd86a961474708ae4740529a508070af549c188 100644 (file)
@@ -65,15 +65,32 @@ namespace Tizen.Applications
         {
             if (handle == null)
             {
-                throw new ArgumentNullException("handle");
+                throw new ArgumentNullException(nameof(handle));
             }
 
             if (handle.IsInvalid)
             {
-                throw new ArgumentNullException("handle", "handle is invalid");
+                throw new ArgumentNullException(nameof(handle), "handle is invalid");
+            }
+
+            bool mustRelease = false;
+            try
+            {
+                handle.DangerousAddRef(ref mustRelease);
+                _handle = Interop.Bundle.DangerousClone(handle.DangerousGetHandle());
+            }
+            catch (ObjectDisposedException e)
+            {
+                throw new ArgumentNullException(nameof(handle), e.Message);
+            }
+            finally
+            {
+                if (mustRelease)
+                {
+                    handle.DangerousRelease();
+                }
             }
 
-            _handle = Interop.Bundle.DangerousClone(handle.DangerousGetHandle());
             _keys = new HashSet<string>();
             Interop.Bundle.Iterator iterator = (string key, int type, IntPtr keyval, IntPtr userData) =>
             {