2007-03-08 Mike Kestner <mkestner@novell.com>

* glib/*.cs : add try/catch blocks to native callback
	methods for DestroyNotify, Copy/Free, and ToggleNotify handlers.  
	Raise UnhandledException events on catches.  

svn path=/trunk/gtk-sharp/; revision=73965
This commit is contained in:
Mike Kestner 2007-03-08 20:28:24 +00:00
parent da407f8ed7
commit 57810954a3
10 changed files with 91 additions and 42 deletions

View File

@ -1,3 +1,9 @@
2007-03-08 Mike Kestner <mkestner@novell.com>
* glib/*.cs : add try/catch blocks to native callback
methods for DestroyNotify, Copy/Free, and ToggleNotify handlers.
Raise UnhandledException events on catches.
2007-03-06 Mike Kestner <mkestner@novell.com>
* generator/Signal.cs : add try/catch blocks to native callback

View File

@ -96,10 +96,14 @@ namespace GLib {
// object that owned the native delegate wrapper no longer
// exists and the instance of the delegate itself is removed from the hash table.
private void OnDestroy (IntPtr data) {
lock (typeof (DelegateWrapper)) {
if (instances.ContainsKey (this)) {
instances.Remove (this);
try {
lock (typeof (DelegateWrapper)) {
if (instances.ContainsKey (this)) {
instances.Remove (this);
}
}
} catch (Exception e) {
ExceptionManager.RaiseUnhandledException (e, false);
}
}
}

View File

@ -55,6 +55,7 @@ namespace GLib {
Console.Error.WriteLine ("Exception in Gtk# callback delegate");
Console.Error.WriteLine (" Note: Applications can use GLib.ExceptionManager.UnhandledException to handle the exception.");
Console.Error.WriteLine (e);
Console.Error.WriteLine (new System.Diagnostics.StackTrace (true));
Environment.Exit (1);
}

View File

@ -27,6 +27,7 @@ namespace GLib {
using System.Collections;
using System.Runtime.InteropServices;
[CDeclCallback]
public delegate bool IdleHandler ();
public class Idle {
@ -40,12 +41,17 @@ namespace GLib {
public bool Handler ()
{
IdleHandler idle_handler = (IdleHandler) real_handler;
try {
IdleHandler idle_handler = (IdleHandler) real_handler;
bool cont = idle_handler ();
if (!cont)
Remove ();
return cont;
bool cont = idle_handler ();
if (!cont)
Remove ();
return cont;
} catch (Exception e) {
ExceptionManager.RaiseUnhandledException (e, false);
}
return false;
}
}

View File

@ -56,18 +56,28 @@ namespace GLib {
static IntPtr Copy (IntPtr ptr)
{
if (ptr == IntPtr.Zero)
return ptr;
GCHandle gch = (GCHandle) ptr;
return (IntPtr) GCHandle.Alloc (gch.Target);
try {
if (ptr == IntPtr.Zero)
return ptr;
GCHandle gch = (GCHandle) ptr;
return (IntPtr) GCHandle.Alloc (gch.Target);
} catch (Exception e) {
ExceptionManager.RaiseUnhandledException (e, false);
}
return IntPtr.Zero;
}
static void Free (IntPtr ptr)
{
if (ptr == IntPtr.Zero)
return;
GCHandle gch = (GCHandle) ptr;
gch.Free ();
try {
if (ptr == IntPtr.Zero)
return;
GCHandle gch = (GCHandle) ptr;
gch.Free ();
} catch (Exception e) {
ExceptionManager.RaiseUnhandledException (e, false);
}
}
public static IntPtr WrapObject (object obj)

View File

@ -347,15 +347,19 @@ namespace GLib {
void NotifyCallback (IntPtr handle, IntPtr pspec, IntPtr gch)
{
GLib.Signal sig = ((GCHandle) gch).Target as GLib.Signal;
if (sig == null)
throw new Exception("Unknown signal GC handle received " + gch);
try {
GLib.Signal sig = ((GCHandle) gch).Target as GLib.Signal;
if (sig == null)
throw new Exception("Unknown signal GC handle received " + gch);
NotifyArgs args = new NotifyArgs ();
args.Args = new object[1];
args.Args[0] = pspec;
NotifyHandler handler = (NotifyHandler) sig.Handler;
handler (GLib.Object.GetObject (handle), args);
NotifyArgs args = new NotifyArgs ();
args.Args = new object[1];
args.Args[0] = pspec;
NotifyHandler handler = (NotifyHandler) sig.Handler;
handler (GLib.Object.GetObject (handle), args);
} catch (Exception e) {
ExceptionManager.RaiseUnhandledException (e, false);
}
}
void ConnectNotification (string signal, NotifyHandler handler)

View File

@ -56,11 +56,15 @@ namespace GLib {
delegate void SignalDestroyNotify (IntPtr data, IntPtr obj);
static void OnNativeDestroy (IntPtr data, IntPtr obj)
{
GCHandle gch = (GCHandle) data;
Signal s = gch.Target as Signal;
s.DisconnectHandler (s.before_id);
s.DisconnectHandler (s.after_id);
gch.Free ();
try {
GCHandle gch = (GCHandle) data;
Signal s = gch.Target as Signal;
s.DisconnectHandler (s.before_id);
s.DisconnectHandler (s.after_id);
gch.Free ();
} catch (Exception e) {
ExceptionManager.RaiseUnhandledException (e, false);
}
}
private Signal (GLib.Object obj, string signal_name, Delegate marshaler)

View File

@ -24,6 +24,7 @@ namespace GLib {
using System;
using System.Runtime.InteropServices;
[CDeclCallback]
public delegate bool TimeoutHandler ();
public class Timeout {
@ -37,12 +38,17 @@ namespace GLib {
public bool Handler ()
{
TimeoutHandler timeout_handler = (TimeoutHandler) real_handler;
try {
TimeoutHandler timeout_handler = (TimeoutHandler) real_handler;
bool cont = timeout_handler ();
if (!cont)
Remove ();
return cont;
bool cont = timeout_handler ();
if (!cont)
Remove ();
return cont;
} catch (Exception e) {
ExceptionManager.RaiseUnhandledException (e, false);
}
return false;
}
}

View File

@ -74,7 +74,7 @@ namespace GLib {
if (weak.IsAlive)
reference = weak.Target;
else
throw new Exception ("Toggling dead object wrapper");
throw new Exception ("Toggling dead wrapper");
}
}
@ -83,9 +83,13 @@ namespace GLib {
static void RefToggled (IntPtr data, IntPtr handle, bool is_last_ref)
{
GCHandle gch = (GCHandle) data;
ToggleRef tref = gch.Target as ToggleRef;
tref.Toggle (is_last_ref);
try {
GCHandle gch = (GCHandle) data;
ToggleRef tref = gch.Target as ToggleRef;
tref.Toggle (is_last_ref);
} catch (Exception e) {
ExceptionManager.RaiseUnhandledException (e, false);
}
}
static ToggleNotifyHandler toggle_notify_callback;

View File

@ -34,10 +34,14 @@ namespace GLib {
delegate void DestroyNotify (IntPtr data);
static void OnNativeDestroy (IntPtr data)
{
GCHandle gch = (GCHandle) data;
WeakObject obj = gch.Target as WeakObject;
obj.Dispose ();
gch.Free ();
try {
GCHandle gch = (GCHandle) data;
WeakObject obj = gch.Target as WeakObject;
obj.Dispose ();
gch.Free ();
} catch (Exception e) {
ExceptionManager.RaiseUnhandledException (e, false);
}
}
void Dispose ()