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>
* glib/Global.cs: implement Global.ApplicationName for localized

View File

@ -26,7 +26,39 @@ namespace GLib {
using GLib;
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]
delegate IntPtr CopyFunc (IntPtr gch);
[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)
{
try {
if (ptr == IntPtr.Zero)
return ptr;
GCHandle gch = (GCHandle) ptr;
return (IntPtr) GCHandle.Alloc (gch.Target);
ManagedValue val = FromHandle (ptr);
val.Ref ();
return ptr;
} catch (Exception e) {
ExceptionManager.RaiseUnhandledException (e, false);
}
@ -73,8 +115,8 @@ namespace GLib {
try {
if (ptr == IntPtr.Zero)
return;
GCHandle gch = (GCHandle) ptr;
gch.Free ();
ManagedValue val = FromHandle (ptr);
val.Unref ();
} catch (Exception e) {
ExceptionManager.RaiseUnhandledException (e, false);
}
@ -84,14 +126,15 @@ namespace GLib {
{
if (obj == null)
return IntPtr.Zero;
return (IntPtr) GCHandle.Alloc (obj);
return new ManagedValue (obj).Handle;
}
public static object ObjectForWrapper (IntPtr ptr)
{
if (ptr == IntPtr.Zero)
return null;
return ((GCHandle)ptr).Target;
ManagedValue val = FromHandle (ptr);
return val == null ? null : val.Instance;
}
public static void ReleaseWrapper (IntPtr ptr)
@ -99,7 +142,8 @@ namespace GLib {
if (ptr == IntPtr.Zero)
return;
((GCHandle)ptr).Free ();
ManagedValue val = FromHandle (ptr);
val.Unref ();
}
}
}