mirror of
https://github.com/Ryujinx/GtkSharp.git
synced 2024-09-09 00:13:20 +02:00
glib: avoid a delegate to be GCed which caused a NRE (bxc#13113)
What seemed to be a race condition (because of not happenning 100% of the times) ended up being an early garbage collection of a delegate that was still referenced by an unmanaged struct without having a managed counterpart [1]. The consequence of this was a NullReferenceException happening in a line which didn't have a dereference of a null object. The way to reproduce it deterministically 100% of the times was setting the env var MONO_NO_SMP. [1] http://www.mono-project.com/Interop_with_Native_Libraries#Memory_Boundaries
This commit is contained in:
parent
e8f4eca14e
commit
6d626a24a7
@ -1,9 +1,11 @@
|
|||||||
// GLib.Type.cs - GLib GType class implementation
|
// GLib.Type.cs - GLib GType class implementation
|
||||||
//
|
//
|
||||||
// Author: Mike Kestner <mkestner@speakeasy.net>
|
// Authors: Mike Kestner <mkestner@speakeasy.net>
|
||||||
|
// Andres G. Aragoneses <knocte@gmail.com>
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003 Mike Kestner
|
// Copyright (c) 2003 Mike Kestner
|
||||||
// Copyright (c) 2003 Novell, Inc.
|
// Copyright (c) 2003 Novell, Inc.
|
||||||
|
// Copyright (c) 2013 Andres G. Aragoneses
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of version 2 of the Lesser GNU General
|
// modify it under the terms of version 2 of the Lesser GNU General
|
||||||
@ -36,11 +38,10 @@ namespace GLib {
|
|||||||
|
|
||||||
IntPtr val;
|
IntPtr val;
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
|
||||||
|
internal delegate void ClassInitDelegate (IntPtr gobject_class_handle);
|
||||||
|
|
||||||
struct GTypeInfo {
|
struct GTypeInfo {
|
||||||
|
|
||||||
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
|
|
||||||
public delegate void ClassInitDelegate (IntPtr gobject_class_handle);
|
|
||||||
|
|
||||||
public ushort class_size;
|
public ushort class_size;
|
||||||
public IntPtr base_init;
|
public IntPtr base_init;
|
||||||
public IntPtr base_finalize;
|
public IntPtr base_finalize;
|
||||||
@ -371,7 +372,7 @@ namespace GLib {
|
|||||||
GTypeInfo info = new GTypeInfo ();
|
GTypeInfo info = new GTypeInfo ();
|
||||||
info.class_size = (ushort) query.class_size;
|
info.class_size = (ushort) query.class_size;
|
||||||
info.instance_size = (ushort) query.instance_size;
|
info.instance_size = (ushort) query.instance_size;
|
||||||
info.class_init = gobject_class_initializer.ClassInit;
|
info.class_init = gobject_class_initializer.ClassInitManagedDelegate;
|
||||||
|
|
||||||
GType gtype = new GType (g_type_register_static (parent_gtype.Val, native_name, ref info, 0));
|
GType gtype = new GType (g_type_register_static (parent_gtype.Val, native_name, ref info, 0));
|
||||||
GLib.Marshaller.Free (native_name);
|
GLib.Marshaller.Free (native_name);
|
||||||
|
@ -188,6 +188,7 @@ namespace GLib {
|
|||||||
|
|
||||||
internal Type Type { get; private set; }
|
internal Type Type { get; private set; }
|
||||||
internal bool HandlersOverriden { get; private set; }
|
internal bool HandlersOverriden { get; private set; }
|
||||||
|
internal GType.ClassInitDelegate ClassInitManagedDelegate { get; private set; }
|
||||||
|
|
||||||
uint idx = 1;
|
uint idx = 1;
|
||||||
bool is_first_subclass;
|
bool is_first_subclass;
|
||||||
@ -196,6 +197,7 @@ namespace GLib {
|
|||||||
|
|
||||||
internal ClassInitializer (Type type)
|
internal ClassInitializer (Type type)
|
||||||
{
|
{
|
||||||
|
ClassInitManagedDelegate = this.ClassInit;
|
||||||
Type = type;
|
Type = type;
|
||||||
gtype = GType.RegisterGObjectType (this);
|
gtype = GType.RegisterGObjectType (this);
|
||||||
is_first_subclass = gtype.GetBaseType () == gtype.GetThresholdType ();
|
is_first_subclass = gtype.GetBaseType () == gtype.GetThresholdType ();
|
||||||
@ -231,7 +233,7 @@ namespace GLib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ClassInit (IntPtr gobject_class_handle)
|
private void ClassInit (IntPtr gobject_class_handle)
|
||||||
{
|
{
|
||||||
bool override_ctor = is_first_subclass;
|
bool override_ctor = is_first_subclass;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user