GTK 2.24.10 memory leak on win32?



We have found a regression that block us to migrate our existing apps from
GTK 2.16.x to GTK 2.24.10 (20120208), it seems there is a memory leak in
g_idle_add() use or something related to queue_draw(), anyway the following
code (that I think is correct) do not leak in linux (ubuntu 12.04, gtk
2.24.10) nor on win32 (GTK 2.16) while it leaks about 12kbyte/sec with GTK
2.24.10 on win32.

I'm posting the code here before creating a bugzilla entry for it since I'm
not sure I can use g_idle_add to notify a new frame is available without
freeing the source, that works in linux and in older WIN32 versions and it
seems correct since g_idle_add() documentation says:

*If the function returns FALSE it is automatically removed from the list of
event sources and will not be called again.*

The (real) code is a video player with multiple realtime streams, this code
use g_timeout_add() to simulate the 25fps of the video, I fill the drawing
area with a simple red/blue pattern without thinking to much to endianness
of the pixel components, but this is a sample, the code leaks on
win32/2.24.10 also if I do not draw inside the GdkImage...

Anyway here is the code, as short as I could make it :)

#include <gtk/gtk.h>
#include <stdint.h>

double last_update;
GtkWidget *dest;
GdkImage *img;
GdkGC *gc;
int frames = 0;

int queue_draw() {
    gtk_widget_queue_draw(dest);
    return FALSE;
}

double get_timer() {
    GTimeVal now;
    g_get_current_time(&now);
    return  (double)now.tv_sec + ((double)now.tv_usec / 1000000.0f);
}

void on_expose() {
    gdk_draw_image(dest->window, gc, img, 0, 0, 0, 0, img->width,
img->height);
    frames++;
}

int draw_func() {
    static int pos = 0;
    uint32_t *ptr = (uint32_t *)img->mem;
    int x, y;
    for (x = 0; x < img->width; ++x) {
        for (y = 0; y < pos; ++y)
            ptr[x + y * img->width] = 0xff0000;
        for (y = pos; y < pos + (img->height / 2) && y < img->height; ++y)
            ptr[x + y * img->width] = 0x00ff;
        for (y = pos + img->height / 2 ; y < img->height; ++y)
            ptr[x + y * img->width] = 0xff0000;
    }

    g_idle_add((GSourceFunc)queue_draw, NULL);
    if (++pos >= img->height)
        pos = 0;

    return TRUE;
}


int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);

    GtkWidget *w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    dest = gtk_drawing_area_new();
    gtk_container_add(GTK_CONTAINER(w), dest);
    gtk_widget_set_usize(dest, 352, 288);
    g_signal_connect(dest, "expose-event", on_expose, NULL);
    gtk_widget_set_app_paintable(w, TRUE);
    gtk_widget_set_double_buffered(w, FALSE);
    gtk_widget_show_all(w);
    last_update = get_timer();
    double secs = get_timer();
    img =  gdk_image_new(GDK_IMAGE_FASTEST, gdk_visual_get_system(), 352,
288);
    gc = gdk_gc_new(w->window);

    g_signal_connect(w, "delete-event", (GCallback)gtk_main_quit, NULL);
    g_timeout_add(40, (GSourceFunc)draw_func, NULL);
    gtk_main();

    secs = get_timer() - secs;
    g_printf("%d frames in %f seconds, %f fps\n", frames, secs,
(double)frames / secs);
}

-- 
Ing. Gabriele Greco, DARTS Engineering
Tel: +39-0100980150  Fax: +39-0100980184
s-mail: Piazza Della Vittoria 9/3 - 16121 GENOVA (ITALY)



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