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.
This commit is contained in:
dmg 2021-04-01 19:46:39 +03:00 committed by Harry
parent bfcf29b070
commit 94ea7051f9

View File

@ -26,11 +26,15 @@ namespace GLib {
public class GException : Exception
{
IntPtr errptr;
string msg;
public GException (IntPtr errptr) : base ()
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<d_g_clear_error>(FuncLoader.GetProcAddress(GLibrary.Load(Library.GLib), "g_clear_error"));
~GException ()
{
g_clear_error (ref errptr);
}
}
}