mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-24 13:06:14 +01:00
gthreadedresolver: Combine closure structs for different lookup types
This introduces no functional changes, but will make a reorganisation of the code simpler in the next commit. Rather than dealing with three different closure types, this changes the code to deal with one which is a tagged union of the three. Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This commit is contained in:
parent
6e499764e4
commit
694394207c
@ -71,24 +71,75 @@ g_resolver_error_from_addrinfo_error (gint err)
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *hostname;
|
enum {
|
||||||
int address_family;
|
LOOKUP_BY_NAME,
|
||||||
|
LOOKUP_BY_ADDRESS,
|
||||||
|
LOOKUP_RECORDS,
|
||||||
|
} lookup_type;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
char *hostname;
|
||||||
|
int address_family;
|
||||||
|
} lookup_by_name;
|
||||||
|
struct {
|
||||||
|
GInetAddress *address; /* (owned) */
|
||||||
|
} lookup_by_address;
|
||||||
|
struct {
|
||||||
|
char *rrname;
|
||||||
|
GResolverRecordType record_type;
|
||||||
|
} lookup_records;
|
||||||
|
};
|
||||||
} LookupData;
|
} LookupData;
|
||||||
|
|
||||||
static LookupData *
|
static LookupData *
|
||||||
lookup_data_new (const char *hostname,
|
lookup_data_new_by_name (const char *hostname,
|
||||||
int address_family)
|
int address_family)
|
||||||
{
|
{
|
||||||
LookupData *data = g_new (LookupData, 1);
|
LookupData *data = g_new0 (LookupData, 1);
|
||||||
data->hostname = g_strdup (hostname);
|
data->lookup_type = LOOKUP_BY_NAME;
|
||||||
data->address_family = address_family;
|
data->lookup_by_name.hostname = g_strdup (hostname);
|
||||||
return data;
|
data->lookup_by_name.address_family = address_family;
|
||||||
|
return g_steal_pointer (&data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LookupData *
|
||||||
|
lookup_data_new_by_address (GInetAddress *address)
|
||||||
|
{
|
||||||
|
LookupData *data = g_new0 (LookupData, 1);
|
||||||
|
data->lookup_type = LOOKUP_BY_ADDRESS;
|
||||||
|
data->lookup_by_address.address = g_object_ref (address);
|
||||||
|
return g_steal_pointer (&data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LookupData *
|
||||||
|
lookup_data_new_records (const gchar *rrname,
|
||||||
|
GResolverRecordType record_type)
|
||||||
|
{
|
||||||
|
LookupData *data = g_new0 (LookupData, 1);
|
||||||
|
data->lookup_type = LOOKUP_RECORDS;
|
||||||
|
data->lookup_records.rrname = g_strdup (rrname);
|
||||||
|
data->lookup_records.record_type = record_type;
|
||||||
|
return g_steal_pointer (&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lookup_data_free (LookupData *data)
|
lookup_data_free (LookupData *data)
|
||||||
{
|
{
|
||||||
g_free (data->hostname);
|
switch (data->lookup_type) {
|
||||||
|
case LOOKUP_BY_NAME:
|
||||||
|
g_free (data->lookup_by_name.hostname);
|
||||||
|
break;
|
||||||
|
case LOOKUP_BY_ADDRESS:
|
||||||
|
g_clear_object (&data->lookup_by_address.address);
|
||||||
|
break;
|
||||||
|
case LOOKUP_RECORDS:
|
||||||
|
g_free (data->lookup_records.rrname);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +150,7 @@ do_lookup_by_name (GTask *task,
|
|||||||
GCancellable *cancellable)
|
GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
LookupData *lookup_data = task_data;
|
LookupData *lookup_data = task_data;
|
||||||
const char *hostname = lookup_data->hostname;
|
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;
|
||||||
@ -115,7 +166,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->address_family;
|
addrinfo_hints.ai_family = lookup_data->lookup_by_name.address_family;
|
||||||
retval = getaddrinfo (hostname, NULL, &addrinfo_hints, &res);
|
retval = getaddrinfo (hostname, NULL, &addrinfo_hints, &res);
|
||||||
|
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
@ -190,11 +241,11 @@ lookup_by_name (GResolver *resolver,
|
|||||||
GList *addresses;
|
GList *addresses;
|
||||||
LookupData *data;
|
LookupData *data;
|
||||||
|
|
||||||
data = lookup_data_new (hostname, AF_UNSPEC);
|
data = lookup_data_new_by_name (hostname, AF_UNSPEC);
|
||||||
task = g_task_new (resolver, cancellable, NULL, NULL);
|
task = g_task_new (resolver, cancellable, NULL, NULL);
|
||||||
g_task_set_source_tag (task, lookup_by_name);
|
g_task_set_source_tag (task, lookup_by_name);
|
||||||
g_task_set_name (task, "[gio] resolver lookup");
|
g_task_set_name (task, "[gio] resolver lookup");
|
||||||
g_task_set_task_data (task, 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, do_lookup_by_name);
|
||||||
addresses = g_task_propagate_pointer (task, error);
|
addresses = g_task_propagate_pointer (task, error);
|
||||||
@ -232,11 +283,11 @@ lookup_by_name_with_flags (GResolver *resolver,
|
|||||||
GList *addresses;
|
GList *addresses;
|
||||||
LookupData *data;
|
LookupData *data;
|
||||||
|
|
||||||
data = lookup_data_new (hostname, flags_to_family (flags));
|
data = lookup_data_new_by_name (hostname, flags_to_family (flags));
|
||||||
task = g_task_new (resolver, cancellable, NULL, NULL);
|
task = g_task_new (resolver, cancellable, NULL, NULL);
|
||||||
g_task_set_source_tag (task, lookup_by_name_with_flags);
|
g_task_set_source_tag (task, lookup_by_name_with_flags);
|
||||||
g_task_set_name (task, "[gio] resolver lookup");
|
g_task_set_name (task, "[gio] resolver lookup");
|
||||||
g_task_set_task_data (task, 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, do_lookup_by_name);
|
||||||
addresses = g_task_propagate_pointer (task, error);
|
addresses = g_task_propagate_pointer (task, error);
|
||||||
@ -256,7 +307,7 @@ lookup_by_name_with_flags_async (GResolver *resolver,
|
|||||||
GTask *task;
|
GTask *task;
|
||||||
LookupData *data;
|
LookupData *data;
|
||||||
|
|
||||||
data = lookup_data_new (hostname, flags_to_family (flags));
|
data = lookup_data_new_by_name (hostname, flags_to_family (flags));
|
||||||
task = g_task_new (resolver, cancellable, callback, user_data);
|
task = g_task_new (resolver, cancellable, callback, user_data);
|
||||||
|
|
||||||
g_debug ("%s: starting new lookup for %s with GTask %p, LookupData %p",
|
g_debug ("%s: starting new lookup for %s with GTask %p, LookupData %p",
|
||||||
@ -264,7 +315,7 @@ lookup_by_name_with_flags_async (GResolver *resolver,
|
|||||||
|
|
||||||
g_task_set_source_tag (task, lookup_by_name_with_flags_async);
|
g_task_set_source_tag (task, lookup_by_name_with_flags_async);
|
||||||
g_task_set_name (task, "[gio] resolver lookup");
|
g_task_set_name (task, "[gio] resolver lookup");
|
||||||
g_task_set_task_data (task, 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, do_lookup_by_name);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
@ -311,7 +362,8 @@ do_lookup_by_address (GTask *task,
|
|||||||
gpointer task_data,
|
gpointer task_data,
|
||||||
GCancellable *cancellable)
|
GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
GInetAddress *address = task_data;
|
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;
|
||||||
@ -358,13 +410,15 @@ lookup_by_address (GResolver *resolver,
|
|||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
LookupData *data = NULL;
|
||||||
GTask *task;
|
GTask *task;
|
||||||
gchar *name;
|
gchar *name;
|
||||||
|
|
||||||
|
data = lookup_data_new_by_address (address);
|
||||||
task = g_task_new (resolver, cancellable, NULL, NULL);
|
task = g_task_new (resolver, cancellable, NULL, NULL);
|
||||||
g_task_set_source_tag (task, lookup_by_address);
|
g_task_set_source_tag (task, lookup_by_address);
|
||||||
g_task_set_name (task, "[gio] resolver lookup");
|
g_task_set_name (task, "[gio] resolver lookup");
|
||||||
g_task_set_task_data (task, g_object_ref (address), g_object_unref);
|
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, do_lookup_by_address);
|
||||||
name = g_task_propagate_pointer (task, error);
|
name = g_task_propagate_pointer (task, error);
|
||||||
@ -380,12 +434,14 @@ lookup_by_address_async (GResolver *resolver,
|
|||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
LookupData *data = NULL;
|
||||||
GTask *task;
|
GTask *task;
|
||||||
|
|
||||||
|
data = lookup_data_new_by_address (address);
|
||||||
task = g_task_new (resolver, cancellable, callback, user_data);
|
task = g_task_new (resolver, cancellable, callback, user_data);
|
||||||
g_task_set_source_tag (task, lookup_by_address_async);
|
g_task_set_source_tag (task, lookup_by_address_async);
|
||||||
g_task_set_name (task, "[gio] resolver lookup");
|
g_task_set_name (task, "[gio] resolver lookup");
|
||||||
g_task_set_task_data (task, g_object_ref (address), g_object_unref);
|
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, do_lookup_by_address);
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
@ -1074,18 +1130,6 @@ g_resolver_records_from_DnsQuery (const gchar *rrname,
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char *rrname;
|
|
||||||
GResolverRecordType record_type;
|
|
||||||
} LookupRecordsData;
|
|
||||||
|
|
||||||
static void
|
|
||||||
free_lookup_records_data (LookupRecordsData *lrd)
|
|
||||||
{
|
|
||||||
g_free (lrd->rrname);
|
|
||||||
g_slice_free (LookupRecordsData, lrd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_records (GList *records)
|
free_records (GList *records)
|
||||||
{
|
{
|
||||||
@ -1107,7 +1151,9 @@ do_lookup_records (GTask *task,
|
|||||||
gpointer task_data,
|
gpointer task_data,
|
||||||
GCancellable *cancellable)
|
GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
LookupRecordsData *lrd = task_data;
|
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;
|
GError *error = NULL;
|
||||||
|
|
||||||
@ -1134,20 +1180,20 @@ do_lookup_records (GTask *task,
|
|||||||
if (res_ninit (&res) != 0)
|
if (res_ninit (&res) != 0)
|
||||||
{
|
{
|
||||||
g_task_return_new_error (task, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL,
|
g_task_return_new_error (task, G_RESOLVER_ERROR, G_RESOLVER_ERROR_INTERNAL,
|
||||||
_("Error resolving “%s”"), lrd->rrname);
|
_("Error resolving “%s”"), rrname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rrtype = g_resolver_record_type_to_rrtype (lrd->record_type);
|
rrtype = g_resolver_record_type_to_rrtype (record_type);
|
||||||
answer = g_byte_array_new ();
|
answer = g_byte_array_new ();
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
g_byte_array_set_size (answer, len * 2);
|
g_byte_array_set_size (answer, len * 2);
|
||||||
#if defined(HAVE_RES_NQUERY)
|
#if defined(HAVE_RES_NQUERY)
|
||||||
len = res_nquery (&res, lrd->rrname, C_IN, rrtype, answer->data, answer->len);
|
len = res_nquery (&res, rrname, C_IN, rrtype, answer->data, answer->len);
|
||||||
#else
|
#else
|
||||||
len = res_query (lrd->rrname, C_IN, rrtype, answer->data, answer->len);
|
len = res_query (rrname, C_IN, rrtype, answer->data, answer->len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If answer fit in the buffer then we're done */
|
/* If answer fit in the buffer then we're done */
|
||||||
@ -1161,7 +1207,7 @@ do_lookup_records (GTask *task,
|
|||||||
}
|
}
|
||||||
|
|
||||||
herr = h_errno;
|
herr = h_errno;
|
||||||
records = g_resolver_records_from_res_query (lrd->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
|
||||||
@ -1182,9 +1228,9 @@ do_lookup_records (GTask *task,
|
|||||||
DNS_RECORD *results = NULL;
|
DNS_RECORD *results = NULL;
|
||||||
WORD dnstype;
|
WORD dnstype;
|
||||||
|
|
||||||
dnstype = g_resolver_record_type_to_dnstype (lrd->record_type);
|
dnstype = g_resolver_record_type_to_dnstype (record_type);
|
||||||
status = DnsQuery_A (lrd->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 (lrd->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);
|
||||||
|
|
||||||
@ -1205,16 +1251,14 @@ lookup_records (GResolver *resolver,
|
|||||||
{
|
{
|
||||||
GTask *task;
|
GTask *task;
|
||||||
GList *records;
|
GList *records;
|
||||||
LookupRecordsData *lrd;
|
LookupData *data = NULL;
|
||||||
|
|
||||||
task = g_task_new (resolver, cancellable, NULL, NULL);
|
task = g_task_new (resolver, cancellable, NULL, NULL);
|
||||||
g_task_set_source_tag (task, lookup_records);
|
g_task_set_source_tag (task, lookup_records);
|
||||||
g_task_set_name (task, "[gio] resolver lookup records");
|
g_task_set_name (task, "[gio] resolver lookup records");
|
||||||
|
|
||||||
lrd = g_slice_new (LookupRecordsData);
|
data = lookup_data_new_records (rrname, record_type);
|
||||||
lrd->rrname = g_strdup (rrname);
|
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
||||||
lrd->record_type = record_type;
|
|
||||||
g_task_set_task_data (task, lrd, (GDestroyNotify) free_lookup_records_data);
|
|
||||||
|
|
||||||
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, do_lookup_records);
|
||||||
@ -1233,16 +1277,14 @@ lookup_records_async (GResolver *resolver,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GTask *task;
|
GTask *task;
|
||||||
LookupRecordsData *lrd;
|
LookupData *data = NULL;
|
||||||
|
|
||||||
task = g_task_new (resolver, cancellable, callback, user_data);
|
task = g_task_new (resolver, cancellable, callback, user_data);
|
||||||
g_task_set_source_tag (task, lookup_records_async);
|
g_task_set_source_tag (task, lookup_records_async);
|
||||||
g_task_set_name (task, "[gio] resolver lookup records");
|
g_task_set_name (task, "[gio] resolver lookup records");
|
||||||
|
|
||||||
lrd = g_slice_new (LookupRecordsData);
|
data = lookup_data_new_records (rrname, record_type);
|
||||||
lrd->rrname = g_strdup (rrname);
|
g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) lookup_data_free);
|
||||||
lrd->record_type = record_type;
|
|
||||||
g_task_set_task_data (task, lrd, (GDestroyNotify) free_lookup_records_data);
|
|
||||||
|
|
||||||
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, do_lookup_records);
|
||||||
|
Loading…
Reference in New Issue
Block a user