Re: pixbuf leakage
"Walter C. Pelissero" <[email protected]> Fri, 23 May 2008 15:54:43 +0200
| Newsgroups | gmane.lisp.clg.devel |
|---|---|
| Message-ID | <[email protected]> |
Espen S Johnsen writes:
> But it suddenly occurred to me why this code is leaking memory. The
> signal handler closures keep references to the loader object, which
> prevents the ref count from reaching zero and thus freeing the
> object. I don't think it is possibly avoid this, but there are two
> ways to work around the problem. One is to disconnect the signal
> handlers when loader is not used any more. The other is to give the
> loader object as the first argument to the callback functions with
> the object keyword argument to signal-connect (this requires the
> latest code from CVS due to a couple of bugs in earlier code).
Well the generalised solution to the problem was easier than I
thought. (Without messing with the C library at all.)
In the following form it's just an add-on (actually a mixin) to avoid
disrupting the CLG code, but I don't think it should be difficult to
hack, say, gobject itself.
(defclass signalled-mixin ()
((signal-handlers :type list
:initform '())))
(defmethod signal-connect ((object signalled-mixin) signal function &key &allow-other-keys)
(declare (ignore signal function))
(let ((handler-id (call-next-method)))
(push handler-id (slot-value object 'signal-handlers))
handler-id))
(defmethod disconnect-all-signal-handlers ((object signalled-mixin))
(with-slots (signal-handlers) object
(dolist (handler-id signal-handlers)
(glib:signal-handler-disconnect object handler-id))
(setf signal-handlers '())))
(defmethod object-destroy-signal ((object glib:gobject))
;; this is the default although gobject itself doesn't accept this
;; signal, neither are its subclasses required to do so
'destroy)
(defmethod initialize-instance ((object signalled-mixin) &key &allow-other-keys)
(call-next-method)
(signal-connect object (object-destroy-signal object)
#'(lambda (object)
(disconnect-all-signal-handlers object))
:object t))
To make use of that, the test code needs the following:
(defclass my-pixbuf-loader (signalled-mixin gdk:pixbuf-loader)
()
(:metaclass glib:gobject-class))
(defmethod object-destroy-signal ((object my-pixbuf-loader))
'closed)
and thus instantiate my-pixbuf-loader instead of pixbuf-loader.
--
walter pelissero
http://www.pelissero.de
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/