2008-11-21 Mike Kestner <mkestner@novell.com>

* glib/ManagedValue.cs: rework to ref count a ManagedValue instance
	and pass a GCHandle to it around, instead of taking out multiple
	gchandles on the managed target itself.

svn path=/trunk/gtk-sharp/; revision=119648
This commit is contained in:
Mike Kestner 2008-11-21 17:42:16 +00:00
parent 1d63a0e3e7
commit 8d6e58e175
2 changed files with 57 additions and 7 deletions

View File

@ -1,3 +1,9 @@
2008-11-21 Mike Kestner <mkestner@novell.com>
* glib/ManagedValue.cs: rework to ref count a ManagedValue instance
and pass a GCHandle to it around, instead of taking out multiple
gchandles on the managed target itself.
2008-11-21 Stephane Delcroix <sdelcroix@novell.com> 2008-11-21 Stephane Delcroix <sdelcroix@novell.com>
* glib/Global.cs: implement Global.ApplicationName for localized * glib/Global.cs: implement Global.ApplicationName for localized

View File

@ -26,7 +26,39 @@ namespace GLib {
using GLib; using GLib;
internal class ManagedValue { internal class ManagedValue {
GCHandle gch;
object instance;
int ref_count = 1;
private ManagedValue (object instance)
{
this.instance = instance;
gch = GCHandle.Alloc (this);
}
IntPtr Handle {
get { return (IntPtr) gch; }
}
object Instance {
get { return instance; }
}
void Ref ()
{
ref_count++;
}
void Unref ()
{
if (--ref_count == 0) {
Console.WriteLine ("Killing ManagedValue for " + instance);
instance = null;
gch.Free ();
}
}
[CDeclCallback] [CDeclCallback]
delegate IntPtr CopyFunc (IntPtr gch); delegate IntPtr CopyFunc (IntPtr gch);
[CDeclCallback] [CDeclCallback]
@ -54,13 +86,23 @@ namespace GLib {
} }
} }
static ManagedValue FromHandle (IntPtr ptr)
{
GCHandle gch = (GCHandle) ptr;
ManagedValue val = gch.Target as ManagedValue;
if (val == null)
throw new Exception ("Unexpected GCHandle received.");
return val;
}
static IntPtr Copy (IntPtr ptr) static IntPtr Copy (IntPtr ptr)
{ {
try { try {
if (ptr == IntPtr.Zero) if (ptr == IntPtr.Zero)
return ptr; return ptr;
GCHandle gch = (GCHandle) ptr; ManagedValue val = FromHandle (ptr);
return (IntPtr) GCHandle.Alloc (gch.Target); val.Ref ();
return ptr;
} catch (Exception e) { } catch (Exception e) {
ExceptionManager.RaiseUnhandledException (e, false); ExceptionManager.RaiseUnhandledException (e, false);
} }
@ -73,8 +115,8 @@ namespace GLib {
try { try {
if (ptr == IntPtr.Zero) if (ptr == IntPtr.Zero)
return; return;
GCHandle gch = (GCHandle) ptr; ManagedValue val = FromHandle (ptr);
gch.Free (); val.Unref ();
} catch (Exception e) { } catch (Exception e) {
ExceptionManager.RaiseUnhandledException (e, false); ExceptionManager.RaiseUnhandledException (e, false);
} }
@ -84,14 +126,15 @@ namespace GLib {
{ {
if (obj == null) if (obj == null)
return IntPtr.Zero; return IntPtr.Zero;
return (IntPtr) GCHandle.Alloc (obj); return new ManagedValue (obj).Handle;
} }
public static object ObjectForWrapper (IntPtr ptr) public static object ObjectForWrapper (IntPtr ptr)
{ {
if (ptr == IntPtr.Zero) if (ptr == IntPtr.Zero)
return null; return null;
return ((GCHandle)ptr).Target; ManagedValue val = FromHandle (ptr);
return val == null ? null : val.Instance;
} }
public static void ReleaseWrapper (IntPtr ptr) public static void ReleaseWrapper (IntPtr ptr)
@ -99,7 +142,8 @@ namespace GLib {
if (ptr == IntPtr.Zero) if (ptr == IntPtr.Zero)
return; return;
((GCHandle)ptr).Free (); ManagedValue val = FromHandle (ptr);
val.Unref ();
} }
} }
} }