zmike pushed a commit to branch efl-1.22.

http://git.enlightenment.org/core/efl.git/commit/?id=79134bf23fb284ed81dd1d9ccb78b513a2b7571b

commit 79134bf23fb284ed81dd1d9ccb78b513a2b7571b
Author: Lauro Moura <[email protected]>
Date:   Mon Apr 15 14:09:49 2019 -0300

    csharp: Fix free_cb calling under dotnet.
    
    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
---
 .../eolian_mono/eolian/mono/function_pointer.hh    |  2 +-
 src/bin/eolian_mono/eolian/mono/klass.hh           |  6 ++--
 src/bindings/mono/efl_mono/efl_all.cs              | 21 ++++++++++++
 src/bindings/mono/eina_mono/eina_accessor.cs       |  2 +-
 src/bindings/mono/eina_mono/eina_array.cs          |  2 +-
 src/bindings/mono/eina_mono/eina_binbuf.cs         |  2 +-
 src/bindings/mono/eina_mono/eina_hash.cs           |  2 +-
 src/bindings/mono/eina_mono/eina_inarray.cs        |  2 +-
 src/bindings/mono/eina_mono/eina_iterator.cs       |  2 +-
 src/bindings/mono/eina_mono/eina_strbuf.cs         |  2 +-
 src/bindings/mono/eina_mono/eina_value.cs          |  2 +-
 src/bindings/mono/eldbus_mono/eldbus_connection.cs |  2 +-
 src/bindings/mono/eldbus_mono/eldbus_message.cs    |  2 +-
 src/bindings/mono/eldbus_mono/eldbus_object.cs     |  2 +-
 src/bindings/mono/eldbus_mono/eldbus_proxy.cs      |  2 +-
 src/bindings/mono/eo_mono/iwrapper.cs              | 39 +++++++++++++---------
 16 files changed, 61 insertions(+), 31 deletions(-)

diff --git a/src/bin/eolian_mono/eolian/mono/function_pointer.hh 
b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
index e243ca744c..f724d8029e 100644
--- a/src/bin/eolian_mono/eolian/mono/function_pointer.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
@@ -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"
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh 
b/src/bin/eolian_mono/eolian/mono/klass.hh
index 236cc69759..329a1c297f 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -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"
diff --git a/src/bindings/mono/efl_mono/efl_all.cs 
b/src/bindings/mono/efl_mono/efl_all.cs
index 70b9825b9d..9a49730093 100644
--- a/src/bindings/mono/efl_mono/efl_all.cs
+++ b/src/bindings/mono/efl_mono/efl_all.cs
@@ -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();
     }
 }
diff --git a/src/bindings/mono/eina_mono/eina_accessor.cs 
b/src/bindings/mono/eina_mono/eina_accessor.cs
index d14a2039d5..bafbbd84fe 100644
--- a/src/bindings/mono/eina_mono/eina_accessor.cs
+++ b/src/bindings/mono/eina_mono/eina_accessor.cs
@@ -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;
         }
diff --git a/src/bindings/mono/eina_mono/eina_array.cs 
b/src/bindings/mono/eina_mono/eina_array.cs
index afa73e9775..e3bd852e2b 100644
--- a/src/bindings/mono/eina_mono/eina_array.cs
+++ b/src/bindings/mono/eina_mono/eina_array.cs
@@ -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);
             }
         }
     }
diff --git a/src/bindings/mono/eina_mono/eina_binbuf.cs 
b/src/bindings/mono/eina_mono/eina_binbuf.cs
index 2ae04ec1bd..e5dc817085 100644
--- a/src/bindings/mono/eina_mono/eina_binbuf.cs
+++ b/src/bindings/mono/eina_mono/eina_binbuf.cs
@@ -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);
             }
         }
     }
diff --git a/src/bindings/mono/eina_mono/eina_hash.cs 
b/src/bindings/mono/eina_mono/eina_hash.cs
index d74c96970b..8b3c1e7db5 100644
--- a/src/bindings/mono/eina_mono/eina_hash.cs
+++ b/src/bindings/mono/eina_mono/eina_hash.cs
@@ -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);
             }
         }
     }
diff --git a/src/bindings/mono/eina_mono/eina_inarray.cs 
b/src/bindings/mono/eina_mono/eina_inarray.cs
index 8fbd89191c..c7f3151ac1 100644
--- a/src/bindings/mono/eina_mono/eina_inarray.cs
+++ b/src/bindings/mono/eina_mono/eina_inarray.cs
@@ -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);
             }
         }
     }
diff --git a/src/bindings/mono/eina_mono/eina_iterator.cs 
b/src/bindings/mono/eina_mono/eina_iterator.cs
index 75ca1b2785..05b5408606 100644
--- a/src/bindings/mono/eina_mono/eina_iterator.cs
+++ b/src/bindings/mono/eina_mono/eina_iterator.cs
@@ -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);
             }
         }
     }
diff --git a/src/bindings/mono/eina_mono/eina_strbuf.cs 
b/src/bindings/mono/eina_mono/eina_strbuf.cs
index 927a21da08..a538de0fd2 100644
--- a/src/bindings/mono/eina_mono/eina_strbuf.cs
+++ b/src/bindings/mono/eina_mono/eina_strbuf.cs
@@ -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;
diff --git a/src/bindings/mono/eina_mono/eina_value.cs 
b/src/bindings/mono/eina_mono/eina_value.cs
index 3c9cb53ced..627c7cb343 100644
--- a/src/bindings/mono/eina_mono/eina_value.cs
+++ b/src/bindings/mono/eina_mono/eina_value.cs
@@ -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);
             }
         }
 
diff --git a/src/bindings/mono/eldbus_mono/eldbus_connection.cs 
b/src/bindings/mono/eldbus_mono/eldbus_connection.cs
index ea8a45f7a1..f88f0ac598 100644
--- a/src/bindings/mono/eldbus_mono/eldbus_connection.cs
+++ b/src/bindings/mono/eldbus_mono/eldbus_connection.cs
@@ -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);
             }
         }
     }
diff --git a/src/bindings/mono/eldbus_mono/eldbus_message.cs 
b/src/bindings/mono/eldbus_mono/eldbus_message.cs
index eec9167d18..559c2f10b9 100644
--- a/src/bindings/mono/eldbus_mono/eldbus_message.cs
+++ b/src/bindings/mono/eldbus_mono/eldbus_message.cs
@@ -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);
             }
         }
     }
diff --git a/src/bindings/mono/eldbus_mono/eldbus_object.cs 
b/src/bindings/mono/eldbus_mono/eldbus_object.cs
index 136e8407ac..682fda6565 100644
--- a/src/bindings/mono/eldbus_mono/eldbus_object.cs
+++ b/src/bindings/mono/eldbus_mono/eldbus_object.cs
@@ -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);
             }
         }
     }
diff --git a/src/bindings/mono/eldbus_mono/eldbus_proxy.cs 
b/src/bindings/mono/eldbus_mono/eldbus_proxy.cs
index c8ac4d265a..f5eec40d43 100644
--- a/src/bindings/mono/eldbus_mono/eldbus_proxy.cs
+++ b/src/bindings/mono/eldbus_mono/eldbus_proxy.cs
@@ -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);
             }
         }
     }
diff --git a/src/bindings/mono/eo_mono/iwrapper.cs 
b/src/bindings/mono/eo_mono/iwrapper.cs
index 4f4181d244..503b71ad28 100644
--- a/src/bindings/mono/eo_mono/iwrapper.cs
+++ b/src/bindings/mono/eo_mono/iwrapper.cs
@@ -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();
     }
 }

-- 


Reply via email to