VNC Reconnect logic / proper destruction of a VncDisplay



Hello all,

I am using gtk-vnc-0.3.10 (on RHEL6), but also have used 0.5.2 (on RHEL7) with similar results. I've been having issues with properly destroying everything allocated to the VncDisplay.

The main driver for this is to have a vncviewer (started off with the gvncviewer.c example) which will automatically attempt reconnecting upon connection loss. While what I have is accomplishing the goal, every reconnect attempt leaks more and more memory (allocated during the vnc_display_open_host() call).

Valgrind seems to point to the GdkPixBuf area, but I would think that would be destroyed when I destroy the vnc object.

What I'm wondering is -- what's going wrong here (I don't see any obvious leaks on my part), or is there a better alternative to reconnecting that I could use instead?

Below is a stripped down (but compileable) version of gvncviewer I'm working with that expresses the problem. Compile, try a ./gvncviewer <random fake host> <random fake ip>,top -p $(pidof gvncviewer) and watch it grow.

Thanks,

Gerald

#include "vncdisplay.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <unistd.h>
GtkMessageDialog* not_avail = 0;
GtkDialogFlags not_avail_flags = GTK_DIALOG_MODAL;
GtkWidget *window = 0;
GOptionContext *context = 0;
GError *error = NULL;
char *display = 0;
GtkWidget *layout = 0;
char port[1024] = {0};
char hostname[1024] = {0};
static gchar **args = 0;
static GtkWidget *vnc = 0;
const char *help_msg = "Run 'gvncviewer --help' to see a full list of available command line options";

bool init();

static const GOptionEntry options [] =
{
{
G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &args,
NULL, "[hostname][:display]" },
{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, 0 }
};

static void vnc_disconnected(GtkWidget *vncdisplay G_GNUC_UNUSED)
{
   printf("disconnected! - %s - %s\n",hostname,port);

   gtk_main_quit();
   gtk_widget_destroy(GTK_WIDGET(vnc));
   vnc=0;
   gtk_widget_destroy(GTK_WIDGET(window));
   window=0;
sleep(1);
   init();
      gtk_widget_hide_all(GTK_WIDGET(not_avail));
      gtk_window_set_type_hint(GTK_WINDOW(not_avail),GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);
      gtk_window_set_position(GTK_WINDOW(not_avail),GTK_WIN_POS_CENTER_ALWAYS);
      gtk_window_set_keep_below(GTK_WINDOW(not_avail), TRUE);
      gtk_widget_show_all(GTK_WIDGET(not_avail));
      gdk_window_lower(gtk_widget_get_window(GTK_WIDGET(not_avail)));
}

int main(int argc, char **argv)
{
/* Setup command line options */
context = g_option_context_new ("- Simple VNC Client");
g_option_context_add_main_entries (context, options, NULL);
g_option_context_add_group (context, gtk_get_option_group (TRUE));
g_option_context_add_group (context, vnc_display_get_option_group ());
g_option_context_parse (context, &argc, &argv, &error);
if (error) {
g_print ("%s\n%s\n",
error->message,
help_msg);
g_error_free (error);
return 1;
}
if (!args || (g_strv_length(args) != 1)) {
fprintf(stderr, "Usage: gvncviewer [hostname][:display]\n%s\n", help_msg);
return 1;
}

    snprintf(hostname, sizeof(hostname), "%s", args[0]);
    display = strchr(hostname, ':');

    if (display) {
        *display = 0;
        snprintf(port, sizeof(port), "%d", 5900 + atoi(display + 1));
    } else
        snprintf(port, sizeof(port), "%d", 5900);

    if (!*hostname)
        snprintf(hostname, sizeof(hostname), "%s", "127.0.0.1");

    init();
}

bool init() {
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_widget_hide_all(window);
layout = gtk_vbox_new(FALSE, 0);

gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
gtk_window_set_keep_below(GTK_WINDOW(window), TRUE);


   gtk_window_set_decorated(GTK_WINDOW(window),FALSE); 
   gtk_container_add(GTK_CONTAINER(window), layout);

    vnc = vnc_display_new();
    
gtk_box_pack_start(GTK_BOX(layout), vnc, TRUE, TRUE, 0);
        vnc_display_open_host(VNC_DISPLAY(vnc), hostname, port);
vnc_display_set_pointer_grab(VNC_DISPLAY(vnc), TRUE);
vnc_display_set_keyboard_grab(VNC_DISPLAY(vnc), TRUE);
gtk_widget_realize(vnc);

g_signal_connect(vnc, "vnc-disconnected",
G_CALLBACK(vnc_disconnected), NULL);


   gtk_main(); 

return 0;
}


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