[Tizen.Applications] Add finalizer in TizenSyncronizationContext (#429)
authorpjh9216 <jh9216.park@samsung.com>
Thu, 30 Aug 2018 06:32:17 +0000 (15:32 +0900)
committerGitHub <noreply@github.com>
Thu, 30 Aug 2018 06:32:17 +0000 (15:32 +0900)
* [Tizen.Applications] Add finalizer in TizenSyncronizationContext

- To clean up native sources, the finalizer was added

Signed-off-by: Junghoon Park <jh9216.park@samsung.com>
* [Tizen.Applications.Common] Fix typo

Signed-off-by: Junghoon Park <jh9216.park@samsung.com>
* Consider multiple sources

Signed-off-by: Junghoon Park <jh9216.park@samsung.com>
src/Tizen.Applications.Common/Interop/Interop.Glib.cs
src/Tizen.Applications.Common/Tizen.Applications/TizenSynchronizationContext.cs [changed mode: 0644->0755]

index 576a6e2..ae64db1 100755 (executable)
@@ -26,5 +26,8 @@ internal static partial class Interop
 
         [DllImport(Libraries.Glib, EntryPoint = "g_idle_add", CallingConvention = CallingConvention.Cdecl)]
         internal static extern uint IdleAdd(GSourceFunc d, IntPtr data);
+
+        [DllImport(Libraries.Glib, EntryPoint = "g_source_remove", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern bool RemoveSource(uint source);
     }
 }
old mode 100644 (file)
new mode 100755 (executable)
index 741242c..4dd40d0
@@ -16,6 +16,7 @@
 
 using System;
 using System.Collections.Concurrent;
+using System.Collections.Generic;
 using System.Threading;
 
 namespace Tizen.Applications
@@ -29,7 +30,8 @@ namespace Tizen.Applications
     {
         private readonly Interop.Glib.GSourceFunc _wrapperHandler;
         private readonly Object _transactionLock = new Object();
-        private readonly ConcurrentDictionary<int, Action> _handlerMap = new ConcurrentDictionary<int, Action>();
+        private readonly ConcurrentDictionary<int, KeyValuePair<Action,uint>> _handlerMap
+            = new ConcurrentDictionary<int, KeyValuePair<Action, uint>>();
         private int _transactionId = 0;
 
         /// <summary>
@@ -42,6 +44,18 @@ namespace Tizen.Applications
         }
 
         /// <summary>
+        /// Finalizer to clean up the native source
+        /// </summary>
+        ~TizenSynchronizationContext()
+        {
+            foreach (var s in _handlerMap.Values)
+            {
+                if (s.Value > 0)
+                    Interop.Glib.RemoveSource(s.Value);
+            }
+        }
+
+        /// <summary>
         /// Initilizes a new TizenSynchronizationContext and install into the current thread.
         /// </summary>
         /// <remarks>
@@ -114,8 +128,8 @@ namespace Tizen.Applications
             {
                 id = _transactionId++;
             }
-            _handlerMap.TryAdd(id, action);
-            Interop.Glib.IdleAdd(_wrapperHandler, (IntPtr)id);
+            _handlerMap.TryAdd(id, new KeyValuePair<Action,uint>(action,
+                Interop.Glib.IdleAdd(_wrapperHandler, (IntPtr)id)));
         }
 
         private bool Handler(IntPtr userData)
@@ -123,9 +137,8 @@ namespace Tizen.Applications
             int key = (int)userData;
             if (_handlerMap.ContainsKey(key))
             {
-                Action action;
-                _handlerMap.TryRemove(key, out action);
-                action?.Invoke();
+                _handlerMap.TryRemove(key, out var p);
+                p.Key?.Invoke();
             }
             return false;
         }