csharp: Fix free_cb calling under dotnet.
authorLauro Moura <lauromoura@expertisesolutions.com.br>
Mon, 15 Apr 2019 17:09:49 +0000 (14:09 -0300)
committerShinwoo Kim <cinoo.kim@samsung.com>
Wed, 17 Apr 2019 01:59:49 +0000 (10:59 +0900)
Summary:
dotnet's GC seems to be more agressive, showing some issues that usually
do not appear when running under Mono's.

This commit uses for free_cb's the same scheme we already use for
regular Eo refs, using a GC handle to keep the cleaning callback alive.

Reviewers: vitor.sousa, felipealmeida, woohyun

Reviewed By: vitor.sousa

Subscribers: segfaultxavi, cedric, #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D8593

16 files changed:
src/bin/eolian_mono/eolian/mono/function_pointer.hh
src/bin/eolian_mono/eolian/mono/klass.hh
src/bindings/mono/efl_mono/efl_all.cs
src/bindings/mono/eina_mono/eina_accessor.cs
src/bindings/mono/eina_mono/eina_array.cs
src/bindings/mono/eina_mono/eina_binbuf.cs
src/bindings/mono/eina_mono/eina_hash.cs
src/bindings/mono/eina_mono/eina_inarray.cs
src/bindings/mono/eina_mono/eina_iterator.cs
src/bindings/mono/eina_mono/eina_strbuf.cs
src/bindings/mono/eina_mono/eina_value.cs
src/bindings/mono/eldbus_mono/eldbus_connection.cs
src/bindings/mono/eldbus_mono/eldbus_message.cs
src/bindings/mono/eldbus_mono/eldbus_object.cs
src/bindings/mono/eldbus_mono/eldbus_proxy.cs
src/bindings/mono/eo_mono/iwrapper.cs

index e243ca7..f724d80 100644 (file)
@@ -84,7 +84,7 @@ struct function_pointer {
                   << scope_tab << scope_tab << scope_tab << "}\n"
                   << scope_tab << scope_tab << scope_tab << "else\n"
                   << scope_tab << scope_tab << scope_tab << "{\n"
-                  << scope_tab << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.efl_mono_thread_safe_free_cb_exec(this._cb_free_cb, this._cb_data);\n"
+                  << scope_tab << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.ThreadSafeFreeCbExec(this._cb_free_cb, this._cb_data);\n"
                   << scope_tab << scope_tab << scope_tab << "}\n"
                   << scope_tab << scope_tab << scope_tab << "this._cb_free_cb = null;\n"
                   << scope_tab << scope_tab << scope_tab << "this._cb_data = IntPtr.Zero;\n"
index 236cc69..329a1c2 100644 (file)
@@ -628,12 +628,12 @@ struct klass
              << scope_tab << scope_tab << scope_tab << "else\n"
              << scope_tab << scope_tab << scope_tab << "{\n"
 
-             << scope_tab << scope_tab << scope_tab << scope_tab << "Monitor.Enter(Efl.Eo.Config.InitLock);\n"
-             << scope_tab << scope_tab << scope_tab << scope_tab << "if (Efl.Eo.Config.Initialized)\n"
+             << scope_tab << scope_tab << scope_tab << scope_tab << "Monitor.Enter(Efl.All.InitLock);\n"
+             << scope_tab << scope_tab << scope_tab << scope_tab << "if (Efl.All.MainLoopInitialized)\n"
              << scope_tab << scope_tab << scope_tab << scope_tab << "{\n"
              << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.efl_mono_thread_safe_native_dispose(h, gcHandlePtr);\n"
              << scope_tab << scope_tab << scope_tab << scope_tab << "}\n\n"
-             << scope_tab << scope_tab << scope_tab << scope_tab << "Monitor.Exit(Efl.Eo.Config.InitLock);\n"
+             << scope_tab << scope_tab << scope_tab << scope_tab << "Monitor.Exit(Efl.All.InitLock);\n"
              << scope_tab << scope_tab << scope_tab << "}\n"
              << scope_tab << scope_tab << "}\n"
              << scope_tab << "}\n\n"
index 70b9825..9a49730 100644 (file)
@@ -43,6 +43,13 @@ public static class All
 {
     private static bool InitializedUi = false;
 
+    public static bool MainLoopInitialized {
+        get;
+        private set;
+    }
+
+    public static readonly object InitLock = new object();
+
     public static void Init(Efl.Csharp.Components components = Efl.Csharp.Components.Basic)
     {
         Eina.Config.Init();
@@ -56,24 +63,38 @@ public static class All
             Efl.Ui.Config.Init();
             InitializedUi = true;
         }
+        Monitor.Enter(InitLock);
+        MainLoopInitialized = true;
+        Monitor.Exit(InitLock);
     }
 
     /// <summary>Shutdowns all EFL subsystems.</summary>
     public static void Shutdown()
     {
         // Try to cleanup everything before actually shutting down.
+        Eina.Log.Debug("Calling GC before shutdown");
         System.GC.Collect();
         System.GC.WaitForPendingFinalizers();
 
+        Monitor.Enter(InitLock);
+        MainLoopInitialized = false;
+        Monitor.Exit(InitLock);
+
         if (InitializedUi)
         {
+            Eina.Log.Debug("Shutting down Elementary");
             Efl.Ui.Config.Shutdown();
         }
 
+        Eina.Log.Debug("Shutting down Eldbus");
         eldbus.Config.Shutdown();
+        Eina.Log.Debug("Shutting down Evas");
         evas_shutdown();
+        Eina.Log.Debug("Shutting down Ecore");
         ecore_shutdown();
+        Eina.Log.Debug("Shutting down Eo");
         Efl.Eo.Config.Shutdown();
+        Eina.Log.Debug("Shutting down Eina");
         Eina.Config.Shutdown();
     }
 }
index d14a203..bafbbd8 100644 (file)
@@ -78,7 +78,7 @@ public class Accessor<T> : IEnumerable<T>, IDisposable
             }
             else
             {
-                Efl.Eo.Globals.efl_mono_thread_safe_free_cb_exec(eina_accessor_free, Handle);
+                Efl.Eo.Globals.ThreadSafeFreeCbExec(eina_accessor_free, Handle);
             }
             Handle = IntPtr.Zero;
         }
index afa73e9..e3bd852 100644 (file)
@@ -155,7 +155,7 @@ public class Array<T> : IEnumerable<T>, IDisposable
             }
             else
             {
-                Efl.Eo.Globals.efl_mono_thread_safe_free_cb_exec(eina_array_free, h);
+                Efl.Eo.Globals.ThreadSafeFreeCbExec(eina_array_free, h);
             }
         }
     }
index 2ae04ec..e5dc817 100644 (file)
@@ -109,7 +109,7 @@ public class Binbuf : IDisposable
             }
             else
             {
-                Efl.Eo.Globals.efl_mono_thread_safe_free_cb_exec(eina_binbuf_free, Handle);
+                Efl.Eo.Globals.ThreadSafeFreeCbExec(eina_binbuf_free, Handle);
             }
         }
     }
index d74c969..8b3c1e7 100644 (file)
@@ -193,7 +193,7 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
             }
             else
             {
-                Efl.Eo.Globals.efl_mono_thread_safe_free_cb_exec(eina_hash_free, h);
+                Efl.Eo.Globals.ThreadSafeFreeCbExec(eina_hash_free, h);
             }
         }
     }
index 8fbd891..c7f3151 100644 (file)
@@ -147,7 +147,7 @@ public class Inarray<T> : IEnumerable<T>, IDisposable
             }
             else
             {
-                Efl.Eo.Globals.efl_mono_thread_safe_free_cb_exec(eina_inarray_free, h);
+                Efl.Eo.Globals.ThreadSafeFreeCbExec(eina_inarray_free, h);
             }
         }
     }
index 75ca1b2..05b5408 100644 (file)
@@ -79,7 +79,7 @@ public class Iterator<T> : IEnumerable<T>, IDisposable
             }
             else
             {
-                Efl.Eo.Globals.efl_mono_thread_safe_free_cb_exec(eina_iterator_free, h);
+                Efl.Eo.Globals.ThreadSafeFreeCbExec(eina_iterator_free, h);
             }
         }
     }
index 927a21d..a538de0 100644 (file)
@@ -99,7 +99,7 @@ public class Strbuf : IDisposable
             }
             else
             {
-                Efl.Eo.Globals.efl_mono_thread_safe_free_cb_exec(eina_strbuf_free, Handle);
+                Efl.Eo.Globals.ThreadSafeFreeCbExec(eina_strbuf_free, Handle);
             }
 
             Handle = IntPtr.Zero;
index 3c9cb53..627c7cb 100644 (file)
@@ -1411,7 +1411,7 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
             }
             else
             {
-                Efl.Eo.Globals.efl_mono_thread_safe_free_cb_exec(eina_value_free, this.Handle);
+                Efl.Eo.Globals.ThreadSafeFreeCbExec(eina_value_free, this.Handle);
             }
         }
 
index ea8a45f..f88f0ac 100644 (file)
@@ -167,7 +167,7 @@ public class Connection : IDisposable
             }
             else
             {
-                Efl.Eo.Globals.efl_mono_thread_safe_free_cb_exec(eldbus_connection_unref, h);
+                Efl.Eo.Globals.ThreadSafeFreeCbExec(eldbus_connection_unref, h);
             }
         }
     }
index eec9167..559c2f1 100644 (file)
@@ -236,7 +236,7 @@ public class Message : IDisposable
             }
             else
             {
-                Efl.Eo.Globals.efl_mono_thread_safe_free_cb_exec(eldbus_message_unref, h);
+                Efl.Eo.Globals.ThreadSafeFreeCbExec(eldbus_message_unref, h);
             }
         }
     }
index 136e840..682fda6 100644 (file)
@@ -158,7 +158,7 @@ public class Object : System.IDisposable
             }
             else
             {
-                Efl.Eo.Globals.efl_mono_thread_safe_free_cb_exec(eldbus_object_unref, h);
+                Efl.Eo.Globals.ThreadSafeFreeCbExec(eldbus_object_unref, h);
             }
         }
     }
index c8ac4d2..f5eec40 100644 (file)
@@ -117,7 +117,7 @@ public class Proxy : IDisposable
             }
             else
             {
-                Efl.Eo.Globals.efl_mono_thread_safe_free_cb_exec(eldbus_proxy_unref, h);
+                Efl.Eo.Globals.ThreadSafeFreeCbExec(eldbus_proxy_unref, h);
             }
         }
     }
index 4f4181d..503b71a 100644 (file)
@@ -77,7 +77,7 @@ public class Globals
         efl_mono_thread_safe_efl_unref(IntPtr eo);
 
     [DllImport(efl.Libs.CustomExports)] public static extern void
-        efl_mono_thread_safe_free_cb_exec(EinaFreeCb free_cb, IntPtr cb_data);
+        efl_mono_thread_safe_free_cb_exec(IntPtr free_cb, IntPtr cb_data);
 
     [DllImport(efl.Libs.Eo)] public static extern IntPtr
         efl_class_name_get(IntPtr eo);
@@ -653,6 +653,7 @@ public class Globals
         return ret;
     }
 
+    private static Efl.FreeGCHandleCb FreeGCHandleCallbackDelegate = new Efl.FreeGCHandleCb(FreeGCHandleCallback);
     public static void FreeGCHandleCallback(IntPtr gcHandlePtr)
     {
         try
@@ -667,6 +668,7 @@ public class Globals
         }
     }
 
+    private static Efl.RemoveEventsCb RemoveEventsCallbackDelegate = new Efl.RemoveEventsCb(RemoveEventsCallback);
     public static void RemoveEventsCallback(IntPtr obj, IntPtr gcHandlePtr)
     {
         try
@@ -696,35 +698,42 @@ public class Globals
 
     public static void SetNativeDisposeCallbacks()
     {
-        efl_mono_gchandle_callbacks_set(FreeGCHandleCallback, RemoveEventsCallback);
+        efl_mono_gchandle_callbacks_set(FreeGCHandleCallbackDelegate, RemoveEventsCallbackDelegate);
     }
 
-} // Globals
+    public static void ThreadSafeFreeCbExec(EinaFreeCb cbFreeCb, IntPtr cbData)
+    {
+        EinaFreeCb cb = (IntPtr gcHandlePtr) => {
+            cbFreeCb(cbData);
+            GCHandle gcHandle = GCHandle.FromIntPtr(gcHandlePtr);
+            gcHandle.Free();
+        };
 
-public static class Config
-{
+        Monitor.Enter(Efl.All.InitLock);
+        if (Efl.All.MainLoopInitialized)
+        {
+            IntPtr cbPtr = Marshal.GetFunctionPointerForDelegate(cb);
+            var handle = GCHandle.Alloc(cb);
+            var handlePtr = GCHandle.ToIntPtr(handle);
 
-    public static bool Initialized {
-        get;
-        private set;
+            efl_mono_thread_safe_free_cb_exec(cbPtr, handlePtr);
+        }
+        Monitor.Exit(Efl.All.InitLock);
     }
 
-    public static readonly object InitLock = new object();
+} // Globals
+
+public static class Config
+{
 
     public static void Init()
     {
         Globals.efl_object_init();
-        Monitor.Enter(InitLock);
-        Initialized = true;
-        Monitor.Exit(InitLock);
         Globals.SetNativeDisposeCallbacks();
     }
 
     public static void Shutdown()
     {
-        Monitor.Enter(InitLock);
-        Initialized = false;
-        Monitor.Exit(InitLock);
         Globals.efl_object_shutdown();
     }
 }