guile-gtk-general
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: scheme closures: crash during garbage collection


From: gregory benison
Subject: Re: scheme closures: crash during garbage collection
Date: Wed, 21 Jun 2006 01:18:34 -0400

Initial reactions:
 - using the glib loop is really distasteful -- you have no guarantee
   that the program will use the loop

Agreed.  I have since figured out that everything I was trying to do
in the glib main loop can be done just as easily in the protected-list
mark function, so that the actions I was trying to defer until some
future invocation of the glib loop are instead deferred until the next
gc mark phase, which seems a lot cleaner to me.


Also, consider glib/REFCOUNTING:

     1. A closure connected to a GObject signal should not be collected
until
        either the closure is disconnected, or the object itself (not the
        wrapper) goes out of existence.

     2. Attaching closures to an object should not prevent the object from
being
        freed. Otherwise, any object with a connected signal will live
forever.
        Closures should only have a weak reference on an object.



I think there can be a solution to this issue without any big change
in the way guile-gnome deals with refcounting and memory management.
I am aiming for a substitute for scm_gc_protect_object() /
scm_gc_unprotect_object() which has the same semantics but is safe to
call during GC, and I think I have it.  The patch I am implementing,
now that I've eliminated the glib-loop tie-in weirdness, is not even
gobject-specific.  Aside from the fact that it uses a GList to manage
a data structure, it wouldn't even need to be linked against glib.

Below is a short test program and its output with debugging messages
turned on.  (This test program would ordinarily trigger the fatal call
to scm_gc_unprotect_object.)  Note that the scheme callback gets
marked properly as long as the gobject is around and when the gobject
is garbage-collected, the scheme procedure ceases being marked.

-------------------------------------- test program
--------------------------------

(use-modules (gnome gtk))
(display "\n\n *** Setting up a gobject and attaching a scheme
callback *** \n\n")
(define obj (make <gobject>))
(connect obj 'notify (lambda args #f))
(display "\n\n *** Calling (gc) a few times *** \n\n")
(gc)(gc)(gc)
(display "\n\n *** Clobbering the scheme reference to the gobject *** \n\n")
(set! obj #f)
(display "\n\n *** Calling (gc) a few times *** \n\n")
(gc)(gc)(gc)(gc)
(display "\n\n *** All done!! *** \n\n")

--------------------------------- output below -------------------------------

*** Setting up a gobject and attaching a scheme callback ***

gclosure.c:   protecting new closure 0xb7dce4e8 of GuileGClosure 0x8e51c58
gc_bridge.c: scheduling object 0x8e51c58 for protection


*** Calling (gc) a few times ***

gc_bridge.c:  ---- entering GC mark function for bridge 0x8e54048 ----
gc_bridge.c: inserting object 0x8e51c58 into protected list
gclosure.c: gclosure_mark: marking SCM 0xb7dce4e8 of GuileGClosure 0x8e51c58
gc_bridge.c:  ---- entering GC mark function for bridge 0x8e54048 ----
gclosure.c: gclosure_mark: marking SCM 0xb7dce4e8 of GuileGClosure 0x8e51c58
gc_bridge.c:  ---- entering GC mark function for bridge 0x8e54048 ----
gclosure.c: gclosure_mark: marking SCM 0xb7dce4e8 of GuileGClosure 0x8e51c58


*** Clobbering the scheme reference to the gobject ***



*** Calling (gc) a few times ***

gc_bridge.c:  ---- entering GC mark function for bridge 0x8e54048 ----
gclosure.c: gclosure_mark: marking SCM 0xb7dce4e8 of GuileGClosure 0x8e51c58
gclosure.c:   unprotecting closure 0xb7dce4e8 of GuileGClosure 0x8e51c58
gc_bridge.c: scheduling object 0x8e51c58 for de-protection
gc_bridge.c:  ---- entering GC mark function for bridge 0x8e54048 ----
gc_bridge.c: excising object 0x8e51c58 from protected list
gc_bridge.c:  ---- entering GC mark function for bridge 0x8e54048 ----
gc_bridge.c:  ---- entering GC mark function for bridge 0x8e54048 ----


*** All done!! ***




reply via email to

[Prev in Thread] Current Thread [Next in Thread]