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