From 94ea7051f90dd737d2d65e4b21c18dcf9f25133b Mon Sep 17 00:00:00 2001 From: dmg Date: Thu, 1 Apr 2021 19:46:39 +0300 Subject: [PATCH] GException improvements with multithreading Read all GError fields in GException constructor and free GError memory. Quote from gtksharp2 fix: The original impl did not take into account exceptions marshalling across thread boundaries so it could end up with the error being accessed after being disposed. --- Source/Libs/GLibSharp/GException.cs | 40 +++++++++-------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/Source/Libs/GLibSharp/GException.cs b/Source/Libs/GLibSharp/GException.cs index 4160b0bb0..0c76244dd 100644 --- a/Source/Libs/GLibSharp/GException.cs +++ b/Source/Libs/GLibSharp/GException.cs @@ -26,11 +26,15 @@ namespace GLib { public class GException : Exception { - IntPtr errptr; - - public GException (IntPtr errptr) : base () + string msg; + + public GException (IntPtr errptr) { - this.errptr = errptr; + var err = (GError)Marshal.PtrToStructure(errptr, typeof(GError)); + Domain = err.Domain; + Code = err.Code; + msg = Marshaller.Utf8PtrToString(err.Msg); + g_clear_error(ref errptr); } struct GError { @@ -39,34 +43,14 @@ namespace GLib { public IntPtr Msg; } - public int Code { - get { - GError err = (GError) Marshal.PtrToStructure (errptr, typeof (GError)); - return err.Code; - } - } + public int Code { get; private set; } - public int Domain { - get { - GError err = (GError) Marshal.PtrToStructure (errptr, typeof (GError)); - return err.Domain; - } - } + public int Domain { get; private set; } + + public override string Message => msg; - public override string Message { - get { - GError err = (GError) Marshal.PtrToStructure (errptr, typeof (GError)); - return Marshaller.Utf8PtrToString (err.Msg); - } - } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void d_g_clear_error(ref IntPtr errptr); static d_g_clear_error g_clear_error = FuncLoader.LoadFunction(FuncLoader.GetProcAddress(GLibrary.Load(Library.GLib), "g_clear_error")); - ~GException () - { - g_clear_error (ref errptr); - } } } - -