Index: tests/test_subtype.py
===================================================================
--- tests/test_subtype.py	(revision 929)
+++ tests/test_subtype.py	(working copy)
@@ -267,3 +267,31 @@
         foo = Foo()
         d = foo.__dict__
 
+    def testFuncClosure(self):
+        """http://bugzilla.gnome.org/show_bug.cgi?id=546802"""
+
+        def make_hyperlink():
+            event_box = gtk.EventBox()
+            def on_hyperlink_mapped(*args):
+                event_box.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
+            event_box.connect("map-event", on_hyperlink_mapped)
+            return event_box
+
+        window = gtk.Window()
+        eb = make_hyperlink()
+        window.add(eb)
+
+        eb_ref = eb.weak_ref()
+        self.assert_(eb_ref() is eb)
+        del eb
+
+        gc.collect()
+        window.show_all()
+        # Need to enter the Gtk main loop to trigger this.
+        # Can do gtk.main(), but the following will exit after triggering the
+        for dummy in range(10):
+            gobject.main_context_default().iteration()
+
+        window.destroy() # gtk itself holds a reference to all windows
+
+        self.assertEqual(eb_ref(), None)
Index: gobject/pygobject.c
===================================================================
--- gobject/pygobject.c	(revision 929)
+++ gobject/pygobject.c	(working copy)
@@ -1030,14 +1030,17 @@
         for (tmp = data->closures; tmp != NULL; tmp = tmp->next) {
             PyGClosure *closure = tmp->data;
 
-            if (closure->callback) ret = visit(closure->callback, arg);
-            if (ret != 0) return ret;
-
-            if (closure->extra_args) ret = visit(closure->extra_args, arg);
-            if (ret != 0) return ret;
-
-            if (closure->swap_data) ret = visit(closure->swap_data, arg);
-            if (ret != 0) return ret;
+            if (self->obj->ref_count == 1)
+            {
+                if (closure->callback) ret = visit(closure->callback, arg);
+                if (ret != 0) return ret;
+                
+                if (closure->extra_args) ret = visit(closure->extra_args, arg);
+                if (ret != 0) return ret;
+                
+                if (closure->swap_data) ret = visit(closure->swap_data, arg);
+                if (ret != 0) return ret;
+            }
         }
     }
     return ret;
