Re: VNC Reconnect logic / proper destruction of a VncDisplay



My original attempt at this did not destroy the vncdisplay object -- which unfortunately had the same results. Below is the full code of what I'm trying to do, which is basically a popup when the connection is down, and recurrent reconnect attempts (triggered off the disconnect). The only real interesting part is inside the disconnect() call. I've tried it with and without the vnc_close(), using both 0.5.2 (on RHEL7) and 0.3.10 (RHEL6) with similar results.

#include "vncdisplay.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <unistd.h>

GtkMessageDialog* not_avail;
GtkDialogFlags not_avail_flags = GTK_DIALOG_MODAL;
GtkWidget *window;
char port[1024];
char hostname[1024];

static gchar **args = NULL;
static GtkWidget *vnc;

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_initialized(GtkWidget *vncdisplay, GtkWidget *window)
{
   printf("initialized! - %s - %s\n",hostname,port);

   if (not_avail) {
      gtk_widget_destroy(GTK_WIDGET(not_avail));
      not_avail=0;
   }

   gtk_widget_show_all(window);
   gdk_window_lower(gtk_widget_get_window(GTK_WIDGET(window)));
   gtk_window_set_keep_below(GTK_WINDOW(window), TRUE);
}

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

//   vnc_display_close(VNC_DISPLAY(vnc));
   gtk_main_quit();

   sleep (1);

   vnc_display_open_host(VNC_DISPLAY(vnc), hostname, port);
   gtk_widget_hide_all(window);

   if (!not_avail) {
      not_avail = GTK_MESSAGE_DIALOG(gtk_message_dialog_new(GTK_WINDOW(window),
                                     not_avail_flags,
                                     GTK_MESSAGE_ERROR,
                                     GTK_BUTTONS_NONE,
                                     "Disconnected from VNC server %s:%s\nAttempting reconnect",
                                     hostname,
                                     port));
      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)));
   }

   gtk_main();
}

int main(int argc, char **argv)
{
    GOptionContext *context;
    GError *error = NULL;
    char *display;
    GtkWidget *layout;
    const char *help_msg = "Run 'gvncviewer --help' to see a full list of available command line options";

    /* 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;
    }

    vnc = vnc_display_new();

    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_box_pack_start(GTK_BOX(layout), vnc, TRUE, TRUE, 0);

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

    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");
    vnc_display_open_host(VNC_DISPLAY(vnc), hostname, port);
    vnc_display_set_keyboard_grab(VNC_DISPLAY(vnc), TRUE);
    vnc_display_set_pointer_grab(VNC_DISPLAY(vnc), TRUE);


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

   gtk_window_fullscreen(GTK_WINDOW(window));

   gtk_main(); 

    return 0;
}

On Thu, Feb 11, 2016 at 10:40 AM, Daniel P. Berrange <dan berrange com> wrote:
On Thu, Feb 11, 2016 at 09:34:00AM -0500, Gerald Grignan wrote:
> 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?

Just don't destroy the VncDisplay object. Simply call vnc_display_open_host()
again when you want to reconnect. The existing widget should handle that
fine.


Daniel
--
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|



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