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:
parent
bfcf29b070
commit
94ea7051f9
1 changed files with 12 additions and 28 deletions
|
@ -26,11 +26,15 @@ namespace GLib {
|
||||||
|
|
||||||
public class GException : Exception
|
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 {
|
struct GError {
|
||||||
|
@ -39,34 +43,14 @@ namespace GLib {
|
||||||
public IntPtr Msg;
|
public IntPtr Msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Code {
|
public int Code { get; private set; }
|
||||||
get {
|
|
||||||
GError err = (GError) Marshal.PtrToStructure (errptr, typeof (GError));
|
|
||||||
return err.Code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Domain {
|
public int Domain { get; private set; }
|
||||||
get {
|
|
||||||
GError err = (GError) Marshal.PtrToStructure (errptr, typeof (GError));
|
public override string Message => msg;
|
||||||
return err.Domain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string Message {
|
|
||||||
get {
|
|
||||||
GError err = (GError) Marshal.PtrToStructure (errptr, typeof (GError));
|
|
||||||
return Marshaller.Utf8PtrToString (err.Msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
delegate void d_g_clear_error(ref IntPtr errptr);
|
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"));
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue