mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-01 21:33:09 +02:00
gthreadedresolver: Centralise GTask return handling in worker threads
This will make it simpler to handle timeouts and cancellation in future, as all the logic for working out whether to return will all be in one place, and all the lookup-specific code is now implemented in simple sync functions which don’t need to care about `GTask`s. This commit introduces no functional changes, it’s just setting up for the following commit. Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This commit is contained in:
parent
694394207c
commit
84074ce757
@ -45,6 +45,11 @@ struct _GThreadedResolver
|
|||||||
|
|
||||||
G_DEFINE_TYPE (GThreadedResolver, g_threaded_resolver, G_TYPE_RESOLVER)
|
G_DEFINE_TYPE (GThreadedResolver, g_threaded_resolver, G_TYPE_RESOLVER)
|
||||||
|
|
||||||
|
static void threaded_resolver_worker_cb (GTask *task,
|
||||||
|
gpointer source_object,
|
||||||
|
gpointer task_data,
|
||||||
|
GCancellable *cancellable);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_threaded_resolver_init (GThreadedResolver *gtr)
|
g_threaded_resolver_init (GThreadedResolver *gtr)
|
||||||
{
|
{
|
||||||
@ -143,14 +148,12 @@ lookup_data_free (LookupData *data)
|
|||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static GList *
|
||||||
do_lookup_by_name (GTask *task,
|
do_lookup_by_name (const gchar *hostname,
|
||||||
gpointer source_object,
|
int address_family,
|
||||||
gpointer task_data,
|
GCancellable *cancellable,
|
||||||
GCancellable *cancellable)
|
GError **error)
|
||||||
{
|
{
|
||||||
LookupData *lookup_data = task_data;
|
|
||||||
const char *hostname = lookup_data->lookup_by_name.hostname;
|
|
||||||
struct addrinfo *res = NULL;
|
struct addrinfo *res = NULL;
|
||||||
GList *addresses;
|
GList *addresses;
|
||||||
gint retval;
|
gint retval;
|
||||||
@ -166,7 +169,7 @@ do_lookup_by_name (GTask *task,
|
|||||||
addrinfo_hints.ai_socktype = SOCK_STREAM;
|
addrinfo_hints.ai_socktype = SOCK_STREAM;
|
||||||
addrinfo_hints.ai_protocol = IPPROTO_TCP;
|
addrinfo_hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
addrinfo_hints.ai_family = lookup_data->lookup_by_name.address_family;
|
addrinfo_hints.ai_family = address_family;
|
||||||
retval = getaddrinfo (hostname, NULL, &addrinfo_hints, &res);
|
retval = getaddrinfo (hostname, NULL, &addrinfo_hints, &res);
|
||||||
|
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
@ -192,21 +195,23 @@ do_lookup_by_name (GTask *task,
|
|||||||
g_object_unref (sockaddr);
|
g_object_unref (sockaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_clear_pointer (&res, freeaddrinfo);
|
||||||
|
|
||||||
if (addresses != NULL)
|
if (addresses != NULL)
|
||||||
{
|
{
|
||||||
addresses = g_list_reverse (addresses);
|
addresses = g_list_reverse (addresses);
|
||||||
g_task_return_pointer (task, addresses,
|
return g_steal_pointer (&addresses);
|
||||||
(GDestroyNotify)g_resolver_free_addresses);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* All addresses failed to be converted to GSocketAddresses. */
|
/* All addresses failed to be converted to GSocketAddresses. */
|
||||||
g_task_return_new_error (task,
|
g_set_error (error,
|
||||||
G_RESOLVER_ERROR,
|
G_RESOLVER_ERROR,
|
||||||
G_RESOLVER_ERROR_NOT_FOUND,
|
G_RESOLVER_ERROR_NOT_FOUND,
|
||||||
_("Error resolving “%s”: %s"),
|
_("Error resolving “%s”: %s"),
|
||||||
hostname,
|
hostname,
|
||||||
_("No valid addresses were found"));
|
_("No valid addresses were found"));
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -219,16 +224,17 @@ do_lookup_by_name (GTask *task,
|
|||||||
error_message = g_strdup ("[Invalid UTF-8]");
|
error_message = g_strdup ("[Invalid UTF-8]");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_task_return_new_error (task,
|
g_clear_pointer (&res, freeaddrinfo);
|
||||||
|
|
||||||
|
g_set_error (error,
|
||||||
G_RESOLVER_ERROR,
|
G_RESOLVER_ERROR,
|
||||||
g_resolver_error_from_addrinfo_error (retval),
|
g_resolver_error_from_addrinfo_error (retval),
|
||||||
_("Error resolving “%s”: %s"),
|
_("Error resolving “%s”: %s"),
|
||||||
hostname, error_message);
|
hostname, error_message);
|
||||||
g_free (error_message);
|
g_free (error_message);
|
||||||
}
|
|
||||||
|
|
||||||
if (res)
|
return NULL;
|
||||||
freeaddrinfo (res);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GList *
|
static GList *
|
||||||
@ -247,7 +253,7 @@ lookup_by_name (GResolver *resolver,
|
|||||||
g_task_set_name (task, "[gio] resolver lookup");
|
g_task_set_name (task, "[gio] resolver lookup");
|
||||||
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
||||||
g_task_set_return_on_cancel (task, TRUE);
|
g_task_set_return_on_cancel (task, TRUE);
|
||||||
g_task_run_in_thread_sync (task, do_lookup_by_name);
|
g_task_run_in_thread_sync (task, threaded_resolver_worker_cb);
|
||||||
addresses = g_task_propagate_pointer (task, error);
|
addresses = g_task_propagate_pointer (task, error);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
|
|
||||||
@ -289,7 +295,7 @@ lookup_by_name_with_flags (GResolver *resolver,
|
|||||||
g_task_set_name (task, "[gio] resolver lookup");
|
g_task_set_name (task, "[gio] resolver lookup");
|
||||||
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
||||||
g_task_set_return_on_cancel (task, TRUE);
|
g_task_set_return_on_cancel (task, TRUE);
|
||||||
g_task_run_in_thread_sync (task, do_lookup_by_name);
|
g_task_run_in_thread_sync (task, threaded_resolver_worker_cb);
|
||||||
addresses = g_task_propagate_pointer (task, error);
|
addresses = g_task_propagate_pointer (task, error);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
|
|
||||||
@ -317,7 +323,7 @@ lookup_by_name_with_flags_async (GResolver *resolver,
|
|||||||
g_task_set_name (task, "[gio] resolver lookup");
|
g_task_set_name (task, "[gio] resolver lookup");
|
||||||
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
||||||
g_task_set_return_on_cancel (task, TRUE);
|
g_task_set_return_on_cancel (task, TRUE);
|
||||||
g_task_run_in_thread (task, do_lookup_by_name);
|
g_task_run_in_thread (task, threaded_resolver_worker_cb);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,14 +362,11 @@ lookup_by_name_with_flags_finish (GResolver *resolver,
|
|||||||
return g_task_propagate_pointer (G_TASK (result), error);
|
return g_task_propagate_pointer (G_TASK (result), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gchar *
|
||||||
do_lookup_by_address (GTask *task,
|
do_lookup_by_address (GInetAddress *address,
|
||||||
gpointer source_object,
|
GCancellable *cancellable,
|
||||||
gpointer task_data,
|
GError **error)
|
||||||
GCancellable *cancellable)
|
|
||||||
{
|
{
|
||||||
LookupData *data = task_data;
|
|
||||||
GInetAddress *address = data->lookup_by_address.address;
|
|
||||||
struct sockaddr_storage sockaddr_address;
|
struct sockaddr_storage sockaddr_address;
|
||||||
gsize sockaddr_address_size;
|
gsize sockaddr_address_size;
|
||||||
GSocketAddress *gsockaddr;
|
GSocketAddress *gsockaddr;
|
||||||
@ -379,7 +382,7 @@ do_lookup_by_address (GTask *task,
|
|||||||
retval = getnameinfo ((struct sockaddr *) &sockaddr_address, sockaddr_address_size,
|
retval = getnameinfo ((struct sockaddr *) &sockaddr_address, sockaddr_address_size,
|
||||||
name, sizeof (name), NULL, 0, NI_NAMEREQD);
|
name, sizeof (name), NULL, 0, NI_NAMEREQD);
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
g_task_return_pointer (task, g_strdup (name), g_free);
|
return g_strdup (name);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gchar *phys;
|
gchar *phys;
|
||||||
@ -393,7 +396,7 @@ do_lookup_by_address (GTask *task,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
phys = g_inet_address_to_string (address);
|
phys = g_inet_address_to_string (address);
|
||||||
g_task_return_new_error (task,
|
g_set_error (error,
|
||||||
G_RESOLVER_ERROR,
|
G_RESOLVER_ERROR,
|
||||||
g_resolver_error_from_addrinfo_error (retval),
|
g_resolver_error_from_addrinfo_error (retval),
|
||||||
_("Error reverse-resolving “%s”: %s"),
|
_("Error reverse-resolving “%s”: %s"),
|
||||||
@ -401,6 +404,8 @@ do_lookup_by_address (GTask *task,
|
|||||||
error_message);
|
error_message);
|
||||||
g_free (phys);
|
g_free (phys);
|
||||||
g_free (error_message);
|
g_free (error_message);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,7 +425,7 @@ lookup_by_address (GResolver *resolver,
|
|||||||
g_task_set_name (task, "[gio] resolver lookup");
|
g_task_set_name (task, "[gio] resolver lookup");
|
||||||
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
||||||
g_task_set_return_on_cancel (task, TRUE);
|
g_task_set_return_on_cancel (task, TRUE);
|
||||||
g_task_run_in_thread_sync (task, do_lookup_by_address);
|
g_task_run_in_thread_sync (task, threaded_resolver_worker_cb);
|
||||||
name = g_task_propagate_pointer (task, error);
|
name = g_task_propagate_pointer (task, error);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
|
|
||||||
@ -443,7 +448,7 @@ lookup_by_address_async (GResolver *resolver,
|
|||||||
g_task_set_name (task, "[gio] resolver lookup");
|
g_task_set_name (task, "[gio] resolver lookup");
|
||||||
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
||||||
g_task_set_return_on_cancel (task, TRUE);
|
g_task_set_return_on_cancel (task, TRUE);
|
||||||
g_task_run_in_thread (task, do_lookup_by_address);
|
g_task_run_in_thread (task, threaded_resolver_worker_cb);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1145,17 +1150,13 @@ int res_query(const char *, int, int, u_char *, int);
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static GList *
|
||||||
do_lookup_records (GTask *task,
|
do_lookup_records (const gchar *rrname,
|
||||||
gpointer source_object,
|
GResolverRecordType record_type,
|
||||||
gpointer task_data,
|
GCancellable *cancellable,
|
||||||
GCancellable *cancellable)
|
GError **error)
|
||||||
{
|
{
|
||||||
LookupData *data = task_data;
|
|
||||||
const gchar *rrname = data->lookup_records.rrname;
|
|
||||||
GResolverRecordType record_type = data->lookup_records.record_type;
|
|
||||||
GList *records;
|
GList *records;
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
#if defined(G_OS_UNIX)
|
#if defined(G_OS_UNIX)
|
||||||
gint len = 512;
|
gint len = 512;
|
||||||
@ -1179,9 +1180,9 @@ do_lookup_records (GTask *task,
|
|||||||
struct __res_state res = { 0, };
|
struct __res_state res = { 0, };
|
||||||
if (res_ninit (&res) != 0)
|
if (res_ninit (&res) != 0)
|
||||||
{
|
{
|
||||||
g_task_return_new_error (task, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL,
|
g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL,
|
||||||
_("Error resolving “%s”"), rrname);
|
_("Error resolving “%s”"), rrname);
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1207,7 +1208,7 @@ do_lookup_records (GTask *task,
|
|||||||
}
|
}
|
||||||
|
|
||||||
herr = h_errno;
|
herr = h_errno;
|
||||||
records = g_resolver_records_from_res_query (rrname, rrtype, answer->data, len, herr, &error);
|
records = g_resolver_records_from_res_query (rrname, rrtype, answer->data, len, herr, error);
|
||||||
g_byte_array_free (answer, TRUE);
|
g_byte_array_free (answer, TRUE);
|
||||||
|
|
||||||
#ifdef HAVE_RES_NQUERY
|
#ifdef HAVE_RES_NQUERY
|
||||||
@ -1230,16 +1231,13 @@ do_lookup_records (GTask *task,
|
|||||||
|
|
||||||
dnstype = g_resolver_record_type_to_dnstype (record_type);
|
dnstype = g_resolver_record_type_to_dnstype (record_type);
|
||||||
status = DnsQuery_A (rrname, dnstype, DNS_QUERY_STANDARD, NULL, &results, NULL);
|
status = DnsQuery_A (rrname, dnstype, DNS_QUERY_STANDARD, NULL, &results, NULL);
|
||||||
records = g_resolver_records_from_DnsQuery (rrname, dnstype, status, results, &error);
|
records = g_resolver_records_from_DnsQuery (rrname, dnstype, status, results, error);
|
||||||
if (results != NULL)
|
if (results != NULL)
|
||||||
DnsRecordListFree (results, DnsFreeRecordList);
|
DnsRecordListFree (results, DnsFreeRecordList);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (records)
|
return g_steal_pointer (&records);
|
||||||
g_task_return_pointer (task, records, (GDestroyNotify) free_records);
|
|
||||||
else
|
|
||||||
g_task_return_error (task, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GList *
|
static GList *
|
||||||
@ -1261,7 +1259,7 @@ lookup_records (GResolver *resolver,
|
|||||||
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
||||||
|
|
||||||
g_task_set_return_on_cancel (task, TRUE);
|
g_task_set_return_on_cancel (task, TRUE);
|
||||||
g_task_run_in_thread_sync (task, do_lookup_records);
|
g_task_run_in_thread_sync (task, threaded_resolver_worker_cb);
|
||||||
records = g_task_propagate_pointer (task, error);
|
records = g_task_propagate_pointer (task, error);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
|
|
||||||
@ -1287,7 +1285,7 @@ lookup_records_async (GResolver *resolver,
|
|||||||
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
||||||
|
|
||||||
g_task_set_return_on_cancel (task, TRUE);
|
g_task_set_return_on_cancel (task, TRUE);
|
||||||
g_task_run_in_thread (task, do_lookup_records);
|
g_task_run_in_thread (task, threaded_resolver_worker_cb);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1301,6 +1299,58 @@ lookup_records_finish (GResolver *resolver,
|
|||||||
return g_task_propagate_pointer (G_TASK (result), error);
|
return g_task_propagate_pointer (G_TASK (result), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
threaded_resolver_worker_cb (GTask *task,
|
||||||
|
gpointer source_object,
|
||||||
|
gpointer task_data,
|
||||||
|
GCancellable *cancellable)
|
||||||
|
{
|
||||||
|
LookupData *data = task_data;
|
||||||
|
GError *local_error = NULL;
|
||||||
|
|
||||||
|
switch (data->lookup_type) {
|
||||||
|
case LOOKUP_BY_NAME:
|
||||||
|
{
|
||||||
|
GList *addresses = do_lookup_by_name (data->lookup_by_name.hostname,
|
||||||
|
data->lookup_by_name.address_family,
|
||||||
|
cancellable,
|
||||||
|
&local_error);
|
||||||
|
|
||||||
|
if (addresses != NULL)
|
||||||
|
g_task_return_pointer (task, g_steal_pointer (&addresses), (GDestroyNotify) g_resolver_free_addresses);
|
||||||
|
else
|
||||||
|
g_task_return_error (task, g_steal_pointer (&local_error));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LOOKUP_BY_ADDRESS:
|
||||||
|
{
|
||||||
|
gchar *name = do_lookup_by_address (data->lookup_by_address.address,
|
||||||
|
cancellable,
|
||||||
|
&local_error);
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
g_task_return_pointer (task, g_steal_pointer (&name), g_free);
|
||||||
|
else
|
||||||
|
g_task_return_error (task, g_steal_pointer (&local_error));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LOOKUP_RECORDS:
|
||||||
|
{
|
||||||
|
GList *records = do_lookup_records (data->lookup_records.rrname,
|
||||||
|
data->lookup_records.record_type,
|
||||||
|
cancellable,
|
||||||
|
&local_error);
|
||||||
|
|
||||||
|
if (records != NULL)
|
||||||
|
g_task_return_pointer (task, g_steal_pointer (&records), (GDestroyNotify) free_records);
|
||||||
|
else
|
||||||
|
g_task_return_error (task, g_steal_pointer (&local_error));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_threaded_resolver_class_init (GThreadedResolverClass *threaded_class)
|
g_threaded_resolver_class_init (GThreadedResolverClass *threaded_class)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user