How to deal with getaddrinfo and thread-safety?
getaddrinfo()
is indeed thread-safe. This is required by RFC 3493 Section 6.1:
Functions getaddrinfo() and freeaddrinfo() must be thread-safe.
On some platforms, gethostbyname()
is thread-safe, but on others it is not. What gethostbyname()
is not on all platforms is re-entrant. If you call gethostbyname()
and then call gethostbyname()
again in the same thread, the data from the first call is overwritten with data from the second call. This is because gethostbyname()
usually uses a static buffer internally, that is why you have to copy the data before calling gethostbyname()
again. getaddrinfo()
does not suffer from that problem, as it allocates a new addrinfo
struct every time it is called.
Well, getaddrinfo is not quite thread safe on some platforms, Linux for example: http://man7.org/linux/man-pages/man3/getaddrinfo.3.html
┌────────────────┬───────────────┬────────────────────┐
│Interface │ Attribute │ Value │
├────────────────┼───────────────┼────────────────────┤
│getaddrinfo() │ Thread safety │ MT-Safe env locale │
├────────────────┼───────────────┼────────────────────┤
│freeaddrinfo(), │ Thread safety │ MT-Safe │
│gai_strerror() │ │ │
└────────────────┴───────────────┴────────────────────┘
Note env and locale attibutes:
Other safety remarks
Additional keywords may be attached to functions, indicating features
that do not make a function unsafe to call, but that may need to be
taken into account in certain classes of programs:
locale Functions annotated with locale as an MT-Safety issue read
from the locale object without any form of synchronization.
Functions annotated with locale called concurrently with
locale changes may behave in ways that do not correspond to
any of the locales active during their execution, but an
unpredictable mix thereof.
We do not mark these functions as MT-Unsafe, however, because
functions that modify the locale object are marked with
const:locale and regarded as unsafe. Being unsafe, the latter
are not to be called when multiple threads are running or
asynchronous signals are enabled, and so the locale can be
considered effectively constant in these contexts, which makes
the former safe.
env Functions marked with env as an MT-Safety issue access the
environment with getenv(3) or similar, without any guards to
ensure safety in the presence of concurrent modifications.
We do not mark these functions as MT-Unsafe, however, because
functions that modify the environment are all marked with
const:env and regarded as unsafe. Being unsafe, the latter
are not to be called when multiple threads are running or
asynchronous signals are enabled, and so the environment can
be considered effectively constant in these contexts, which
makes the former safe.
So you will get random segfaults if not take it into account. See this old glibc bug discussion for details: https://sourceware.org/bugzilla/show_bug.cgi?id=13271