Thanks for your reply, Matheus.
To avoid changing gtkD's Pixbuf.d, I sub-classed it. To verify its effect, I added printouts in the ctor and dtor:
import glib.Timeout;
import gdk.Pixbuf;
import gtk.Image;
import gtk.Main;
import gtk.MainWindow;
public class MyPixbuf : gdk.Pixbuf.Pixbuf
{
public this(string filename)
{
super(filename);
std.stdio.stdout.writeln("MyPixbuf");
}
~this()
{
std.stdio.stdout.writeln("~MyPixbuf");
this.gdkPixbuf = null;
this.unref();
}
}
private class MyMainWindow : MainWindow
{
private int iteration;
private MyPixbuf pixbuf;
private Image image;
private size_t filenameIdx;
private string[] filenames = [
"image1.jpg",
"image2.jpg",
];
public this(string text)
{
super(text);
this.setDefaultSize(600, 400);
this.setResizable(false);
this.image = new Image();
this.add(this.image);
new Timeout(1000, &this.cbTimer);
}
private bool cbTimer()
{
auto filename = this.filenames[this.filenameIdx];
if (++this.filenameIdx >= this.filenames.length) this.filenameIdx = 0;
if (this.pixbuf) {
delete this.pixbuf;
}
this.pixbuf = new MyPixbuf(filename);
this.image.setFromPixbuf(this.pixbuf);
// stop after 20 image switches to avoid out of memory
return ++this.iteration < 20;
}
}
void main(string[] args)
{
Main.init(args);
auto win = new MyMainWindow("Image Test");
win.showAll();
Main.run();
}
I get the following output:
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
MyPixbuf
~MyPixbuf
MyPixbuf
~MyPixbuf
(dvgtkd:21102): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
(dvgtkd:21102): GLib-CRITICAL **: Source ID 7 was not found when attempting to remove it
Since 10 times the dtor had problems, the memory leak still remains for 9 blocks (why not 10?):
==00:00:01:23.908 21109== 272,753,892 bytes in 9 blocks are possibly lost in loss record 7,504 of 7,504
==00:00:01:23.908 21109== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==00:00:01:23.908 21109== by 0x6A2D9CC: gdk_pixbuf_new (in /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0.3000.7)
==00:00:01:23.908 21109== by 0x11BE46E0: ??? (in /usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-jpeg.so)
==00:00:01:23.908 21109== by 0x6A31B41: gdk_pixbuf_new_from_file (in /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0.3000.7)
==00:00:01:23.908 21109== by 0x6D0B82: _D3gdk6Pixbuf6Pixbuf6__ctorMFAyaZC3gdk6Pixbuf6Pixbuf (in dvgtkd)
==00:00:01:23.908 21109== by 0x6B1784: _D6dvgtkd8MyPixbuf6__ctorMFAyaZC6dvgtkd8MyPixbuf (dvgtkd.d:24)
==00:00:01:23.908 21109== by 0x6B1968: _D6dvgtkd12MyMainWindow7cbTimerMFZb (dvgtkd.d:73)
==00:00:01:23.908 21109== by 0x6F3D38: _D4glib7Timeout7Timeout16callAllListenersMFZb (in dvgtkd)
==00:00:01:23.908 21109== by 0x6F3CD4: _D4glib7Timeout7Timeout15timeoutCallbackUC4glib7Timeout7TimeoutZb (in dvgtkd)
==00:00:01:23.908 21109== by 0x5C70702: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:01:23.908 21109== by 0x5C6FCE4: g_main_context_dispatch (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:01:23.908 21109== by 0x5C70047: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:01:23.908 21109== by 0x5C70309: g_main_loop_run (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0)
==00:00:01:23.908 21109== by 0xC2E8FE4: gtk_main (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.1000.8)
==00:00:01:23.908 21109== by 0x813852: _D3gtk4Main4Main3runFZv (in dvgtkd)
==00:00:01:23.908 21109== by 0x6B19FF: _Dmain (dvgtkd.d:87)
==00:00:01:23.908 21109== by 0x950942: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv (in dvgtkd)
==00:00:01:23.909 21109== by 0x950895: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (in dvgtkd)
==00:00:01:23.909 21109== by 0x9508FB: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv (in dvgtkd)
==00:00:01:23.909 21109== by 0x950895: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (in dvgtkd)
==00:00:01:23.909 21109== by 0x950816: _d_run_main (in dvgtkd)
==00:00:01:23.909 21109== by 0x6C058C: main (in dvgtkd)
Why is the dtor failing every 2nd time? Can someone explain that?
What causes this message:
Source ID 7 was not found when attempting to remove it
Diez