java-gobject-introspection r131 - trunk/src/org/gnome/gir/gobject
- From: walters svn gnome org
- To: svn-commits-list gnome org
- Subject: java-gobject-introspection r131 - trunk/src/org/gnome/gir/gobject
- Date: Thu, 27 Nov 2008 21:44:45 +0000 (UTC)
Author: walters
Date: Thu Nov 27 21:44:45 2008
New Revision: 131
URL: http://svn.gnome.org/viewvc/java-gobject-introspection?rev=131&view=rev
Log:
Correctly handle object disposal while we still hold a strong ref
Modified:
trunk/src/org/gnome/gir/gobject/GObject.java
Modified: trunk/src/org/gnome/gir/gobject/GObject.java
==============================================================================
--- trunk/src/org/gnome/gir/gobject/GObject.java (original)
+++ trunk/src/org/gnome/gir/gobject/GObject.java Thu Nov 27 21:44:45 2008
@@ -69,11 +69,12 @@
private static final Map<GObject, Boolean> strongReferences = new ConcurrentHashMap<GObject, Boolean>();
private final IntPtr objectID = new IntPtr(System.identityHashCode(this));
+ private boolean disposed = false;
/* Hold a strong Java reference between this proxy object and any signal
* handlers installed. Often this would be done anyways, but if you're
* just calling System.out.println in a callback, it would otherwise
- * be elgible for GC.
+ * be eligible for GC.
*/
private Map<Long,Callback> signalHandlers = new HashMap<Long, Callback>();
@@ -136,7 +137,7 @@
/*
* The weak notify is just a convenient hook into object destruction so
- * we can clear out our signal handlers hash.
+ * we can clear out our signal handlers and strong ref; see below.
*/
GObjectAPI.gobj.g_object_weak_ref(this, weakNotify, null);
@@ -236,10 +237,24 @@
return propValue.unboxAndUnset();
}
+ private static void handleDispose(GObject object) {
+ if (object.disposed)
+ return;
+ /* Make sure we're not holding a hidden strong ref anymore */
+ strongReferences.remove(object);
+ /* Clear out our signal handler references */
+ object.signalHandlers = null;
+ object.disposed = true;
+ }
+
@Override
- protected void finalize() throws Throwable {
- debugMemory(this, "REMOVING TOGGLE %s %s%n");
+ protected void finalize() throws Throwable {
+ super.finalize();
+ /* If the native object already went away, we have nothing to do here. */
+ if (disposed)
+ return;
/* Take away the toggle reference */
+ debugMemory(this, "REMOVING TOGGLE %s %s%n");
GObjectAPI.gobj.g_object_remove_toggle_ref(getNativeAddress(), toggle, objectID);
}
@@ -294,8 +309,10 @@
private GObjectAPI.GParamSpec findProperty(String propertyName) {
return GObjectAPI.gobj.g_object_class_find_property(getNativeAddress().getPointer(0), propertyName);
}
+
/*
- * Hooks to/from native disposal
+ * Hooks to/from native disposal. These callbacks are global statics, and should
+ * never themselves be GC'd.
*/
private static final GToggleNotify toggle = new GToggleNotify() {
public void callback(Pointer data, Pointer ptr, boolean is_last_ref) {
@@ -323,12 +340,11 @@
@Override
public void callback(Pointer data, Pointer obj) {
GObject o = (GObject) Internals.instanceFor(obj);
- debugMemory(o, "WEAK %s %s obj=%s%n", o, obj);
- // Clear out the signal handler references
+ NativeObject.Internals.debugMemory("WEAK %s target=%s%n", obj, o);
if (o == null)
return;
synchronized (o) {
- o.signalHandlers = null;
+ handleDispose(o);
}
}
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]