(root)/
glibc-2.38/
resolv/
tst-resolv-res_init-multi.c
       1  /* Multi-threaded test for resolver initialization.
       2     Copyright (C) 2017-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <netdb.h>
      20  #include <resolv.h>
      21  #include <stdlib.h>
      22  #include <support/check.h>
      23  #include <support/support.h>
      24  #include <support/xthread.h>
      25  
      26  /* Whether name lookups succeed does not really matter.  We use this
      27     to trigger initialization of the resolver.  */
      28  static const char *test_hostname = "www.gnu.org";
      29  
      30  /* The different initialization methods.  */
      31  enum test_type { init, byname, gai };
      32  enum { type_count = 3 };
      33  
      34  /* Thread function.  Perform a few resolver options.  */
      35  static void *
      36  thread_func (void *closure)
      37  {
      38    enum test_type *ptype = closure;
      39    /* Perform a few calls to the requested operation.  */
      40    TEST_VERIFY (*ptype >= 0);
      41    TEST_VERIFY (*ptype < (int) type_count);
      42    for (int i = 0; i < 3; ++i)
      43      switch (*ptype)
      44        {
      45        case init:
      46  	res_init ();
      47  	break;
      48        case byname:
      49  	gethostbyname (test_hostname);
      50  	break;
      51        case gai:
      52  	{
      53  	  struct addrinfo hints = { 0, };
      54  	  struct addrinfo *ai = NULL;
      55  	  if (getaddrinfo (test_hostname, "80", &hints, &ai) == 0)
      56  	    freeaddrinfo (ai);
      57  	}
      58  	break;
      59        }
      60    free (ptype);
      61    return NULL;
      62  }
      63  
      64  static int
      65  do_test (void)
      66  {
      67    /* Start a small number of threads which perform resolver
      68       operations.  */
      69    enum { thread_count = 30 };
      70  
      71    pthread_t threads[thread_count];
      72    for (int i = 0; i < thread_count; ++i)
      73      {
      74        enum test_type *ptype = xmalloc (sizeof (*ptype));
      75        *ptype = i % type_count;
      76        threads[i] = xpthread_create (NULL, thread_func, ptype);
      77      }
      78    for (int i = 0; i < type_count; ++i)
      79      {
      80        enum test_type *ptype = xmalloc (sizeof (*ptype));
      81        *ptype = i;
      82        thread_func (ptype);
      83      }
      84    for (int i = 0; i < thread_count; ++i)
      85      xpthread_join (threads[i]);
      86    return 0;
      87  }
      88  
      89  #include <support/test-driver.c>