mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-26 20:22:11 +01:00
gthreadedresolver: Document design of GThreadedResolver
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This commit is contained in:
parent
c3209f1d84
commit
ef08e8dd81
@ -39,6 +39,47 @@
|
|||||||
#include "gsocketaddress.h"
|
#include "gsocketaddress.h"
|
||||||
#include "gsrvtarget.h"
|
#include "gsrvtarget.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GThreadedResolver is a threaded wrapper around the system libc’s
|
||||||
|
* `getaddrinfo()`.
|
||||||
|
*
|
||||||
|
* It has to be threaded, as `getaddrinfo()` is synchronous. libc does provide
|
||||||
|
* `getaddrinfo_a()` as an asynchronous version of `getaddrinfo()`, but it does
|
||||||
|
* not integrate with a poll loop. It requires use of sigevent to notify of
|
||||||
|
* completion of an asynchronous operation. That either emits a signal, or calls
|
||||||
|
* a callback function in a newly spawned thread.
|
||||||
|
*
|
||||||
|
* A signal (`SIGEV_SIGNAL`) can’t be used for completion as (aside from being
|
||||||
|
* another expensive round trip into the kernel) GLib cannot pick a `SIG*`
|
||||||
|
* number which is guaranteed to not be in use elsewhere in the process. Various
|
||||||
|
* other things could be interfering with signal dispositions, such as gdb or
|
||||||
|
* other libraries in the process. Using a `signalfd()`
|
||||||
|
* [cannot improve this situation](https://ldpreload.com/blog/signalfd-is-useless).
|
||||||
|
*
|
||||||
|
* A callback function in a newly spawned thread (`SIGEV_THREAD`) could be used,
|
||||||
|
* but that is very expensive. Internally, glibc currently also just implements
|
||||||
|
* `getaddrinfo_a()`
|
||||||
|
* [using its own thread pool](https://github.com/bminor/glibc/blob/master/resolv/gai_misc.c),
|
||||||
|
* and then
|
||||||
|
* [spawns an additional thread for each completion callback](https://github.com/bminor/glibc/blob/master/resolv/gai_notify.c).
|
||||||
|
* That is very expensive.
|
||||||
|
*
|
||||||
|
* No other appropriate sigevent callback types
|
||||||
|
* [currently exist](https://sourceware.org/bugzilla/show_bug.cgi?id=30287), and
|
||||||
|
* [others agree that sigevent is not great](http://davmac.org/davpage/linux/async-io.html#posixaio).
|
||||||
|
*
|
||||||
|
* Hence, #GThreadedResolver calls the normal synchronous `getaddrinfo()` in its
|
||||||
|
* own thread pool. Previously, #GThreadedResolver used the thread pool which is
|
||||||
|
* internal to #GTask by calling g_task_run_in_thread(). That lead to exhaustion
|
||||||
|
* of the #GTask thread pool in some situations, though, as DNS lookups are
|
||||||
|
* quite frequent leaf operations in some use cases. Now, #GThreadedResolver
|
||||||
|
* uses its own private thread pool.
|
||||||
|
*
|
||||||
|
* This is similar to what
|
||||||
|
* [libasyncns](http://git.0pointer.net/libasyncns.git/tree/libasyncns/asyncns.h)
|
||||||
|
* and other multi-threaded users of `getaddrinfo()` do.
|
||||||
|
*/
|
||||||
|
|
||||||
struct _GThreadedResolver
|
struct _GThreadedResolver
|
||||||
{
|
{
|
||||||
GResolver parent_instance;
|
GResolver parent_instance;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user