summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorMarek Kasik <mkasik@redhat.com>2013-03-13 14:57:55 +0100
committerMarek Kasik <mkasik@redhat.com>2013-03-13 14:59:10 +0100
commit7529b95fab6e261d744cd9ec52ffd17e6e4934ac (patch)
treebf209e2c602b16865e9d560fc94dadee08047d6d /modules
parent7dd2539e1bdedf313fe60a8ac5c75566ebd1c7b6 (diff)
downloadgtk+-7529b95fab6e261d744cd9ec52ffd17e6e4934ac.tar.gz
printing: Don't hang when getting info for Avahi printer
Asynchronously create testing connection to address returned by GaServiceResolver. Don't request info for such printer if the connection fails. https://bugzilla.gnome.org/show_bug.cgi?id=695714
Diffstat (limited to 'modules')
-rw-r--r--modules/printbackends/cups/gtkprintbackendcups.c95
1 files changed, 78 insertions, 17 deletions
diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c
index 60faad06cc..331b73e02b 100644
--- a/modules/printbackends/cups/gtkprintbackendcups.c
+++ b/modules/printbackends/cups/gtkprintbackendcups.c
@@ -149,6 +149,7 @@ struct _GtkPrintBackendCups
GaServiceBrowser *avahi_ipp_browser;
GaServiceBrowser *avahi_ipps_browser;
GaClient *avahi_client;
+ GCancellable *avahi_cancellable;
#endif
};
@@ -2334,6 +2335,8 @@ avahi_data_free (GtkPrintBackendCups *cups_backend)
{
if (cups_backend)
{
+ g_cancellable_cancel (cups_backend->avahi_cancellable);
+ g_clear_object (&cups_backend->avahi_cancellable);
g_clear_pointer (&cups_backend->avahi_default_printer, g_free);
g_list_free_full (cups_backend->avahi_resolvers, g_object_unref);
cups_backend->avahi_resolvers = NULL;
@@ -2517,6 +2520,52 @@ cups_request_avahi_printer_info (const gchar *printer_uri,
}
}
+typedef struct
+{
+ gchar *printer_uri;
+ gchar *host;
+ gint port;
+ gchar *name;
+ gchar *type;
+ gchar *domain;
+ GtkPrintBackendCups *backend;
+} AvahiConnectionTestData;
+
+static void
+avahi_connection_test_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ AvahiConnectionTestData *data = (AvahiConnectionTestData *) user_data;
+ GSocketConnection *connection;
+
+ connection = g_socket_client_connect_to_host_finish (G_SOCKET_CLIENT (source_object),
+ res,
+ &error);
+ g_object_unref (source_object);
+
+ if (connection != NULL)
+ {
+ g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
+ g_object_unref (connection);
+
+ cups_request_avahi_printer_info (data->printer_uri,
+ data->host,
+ data->port,
+ data->name,
+ data->type,
+ data->domain,
+ data->backend);
+ }
+
+ g_free (data->printer_uri);
+ g_free (data->host);
+ g_free (data->name);
+ g_free (data->type);
+ g_free (data->domain);
+ g_free (data);
+}
+
static void
avahi_resolver_found_cb (GaServiceResolver *resolver,
int interface,
@@ -2531,12 +2580,12 @@ avahi_resolver_found_cb (GaServiceResolver *resolver,
glong flags,
gpointer *user_data)
{
- GtkPrintBackendCups *backend = GTK_PRINT_BACKEND_CUPS (user_data);
- AvahiStringList *item;
- const gchar *protocol_string;
- gchar host[AVAHI_ADDRESS_STR_MAX];
- gchar *suffix = NULL;
- gchar *printer_uri;
+ AvahiConnectionTestData *data;
+ GtkPrintBackendCups *backend = GTK_PRINT_BACKEND_CUPS (user_data);
+ AvahiStringList *item;
+ const gchar *protocol_string;
+ gchar host[AVAHI_ADDRESS_STR_MAX];
+ gchar *suffix = NULL;
avahi_address_snprint (host, sizeof (host), address);
@@ -2551,20 +2600,28 @@ avahi_resolver_found_cb (GaServiceResolver *resolver,
else
protocol_string = "ipps";
+ data = g_new0 (AvahiConnectionTestData, 1);
+
if (protocol == GA_PROTOCOL_INET6)
- printer_uri = g_strdup_printf ("%s://[%s]:%u/%s", protocol_string, host, port, suffix);
+ data->printer_uri = g_strdup_printf ("%s://[%s]:%u/%s", protocol_string, host, port, suffix);
else
- printer_uri = g_strdup_printf ("%s://%s:%u/%s", protocol_string, host, port, suffix);
-
- cups_request_avahi_printer_info (printer_uri,
- host,
- port,
- name,
- type,
- domain,
- backend);
+ data->printer_uri = g_strdup_printf ("%s://%s:%u/%s", protocol_string, host, port, suffix);
+
+ data->host = g_strdup (host);
+ data->port = port;
+ data->name = g_strdup (name);
+ data->type = g_strdup (type);
+ data->domain = g_strdup (domain);
+ data->backend = backend;
+
+ /* It can happen that the address is not reachable */
+ g_socket_client_connect_to_host_async (g_socket_client_new (),
+ host,
+ port,
+ backend->avahi_cancellable,
+ avahi_connection_test_cb,
+ data);
- g_free (printer_uri);
g_free (suffix);
}
}
@@ -2782,6 +2839,10 @@ avahi_request_printer_list (GtkPrintBackendCups *cups_backend)
g_clear_object (&cups_backend->avahi_client);
g_clear_error (&error);
}
+ else
+ {
+ cups_backend->avahi_cancellable = g_cancellable_new ();
+ }
}
}
#endif