From: Lauro Moura Date: Mon, 15 Apr 2019 17:09:49 +0000 (-0300) Subject: csharp: Fix free_cb calling under dotnet. X-Git-Tag: accepted/tizen/unified/20190419.020103~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b87e3c1c4b173a6680ab674c5d8cb3389e71727f;p=platform%2Fupstream%2Fefl.git 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 --- diff --git a/src/bin/eolian_mono/eolian/mono/function_pointer.hh b/src/bin/eolian_mono/eolian/mono/function_pointer.hh index e243ca7..f724d80 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 236cc69..329a1c2 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 70b9825..9a49730 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); } /// Shutdowns all EFL subsystems. 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 d14a203..bafbbd8 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 : IEnumerable, 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 afa73e9..e3bd852 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 : IEnumerable, 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 2ae04ec..e5dc817 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 d74c969..8b3c1e7 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 : IEnumerable>, 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 8fbd891..c7f3151 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 : IEnumerable, 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 75ca1b2..05b5408 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 : IEnumerable, 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 927a21d..a538de0 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 3c9cb53..627c7cb 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, IEquatable } 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 ea8a45f..f88f0ac 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 eec9167..559c2f1 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 136e840..682fda6 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 c8ac4d2..f5eec40 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 4f4181d..503b71a 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(); } }