[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 99f6c34..c1dd827 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 20ead07..4f911a0 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 791cfad..3cd86a9 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) =>
             {