This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.25-669-g89f6307


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  89f6307c5d270ed4f11cee373031fa9f2222f2b9 (commit)
      from  e237357a5a0559dee92261f1914d1fa2cd43a1a8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=89f6307c5d270ed4f11cee373031fa9f2222f2b9

commit 89f6307c5d270ed4f11cee373031fa9f2222f2b9
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Jul 4 11:18:34 2017 +0200

    resolv: Fix improper assert in __resolv_conf_attach

diff --git a/ChangeLog b/ChangeLog
index 3cc4f2c..5bbc323 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2017-07-04  Florian Weimer  <fweimer@redhat.com>
+
+	* resolv/resolv_conf.c (struct resolv_conf_global): Clarify free
+	list management and the role of free_list_start.
+	(decrement_at_index): Put zero at the end of the free list.
+	(__resolv_conf_attach): Fix bogus assert.
+	* resolv/Makefile (tests): Add tst-resolv-res_init-multi.
+	(tst-resolv-res_init-multi): Link with -lresolv, -lpthread.
+
 2017-07-03  Florian Weimer  <fweimer@redhat.com>
 
 	resolv: Introduce free list for resolv_conf index slosts.
diff --git a/resolv/Makefile b/resolv/Makefile
index 5cb2e53..6942e85 100644
--- a/resolv/Makefile
+++ b/resolv/Makefile
@@ -51,6 +51,7 @@ tests += \
   tst-resolv-basic \
   tst-resolv-edns \
   tst-resolv-network \
+  tst-resolv-res_init-multi \
   tst-resolv-search \
 
 # These tests need libdl.
@@ -160,6 +161,8 @@ $(objpfx)tst-resolv-basic: $(objpfx)libresolv.so $(shared-thread-library)
 $(objpfx)tst-resolv-edns: $(objpfx)libresolv.so $(shared-thread-library)
 $(objpfx)tst-resolv-network: $(objpfx)libresolv.so $(shared-thread-library)
 $(objpfx)tst-resolv-res_init: $(libdl) $(objpfx)libresolv.so
+$(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \
+  $(shared-thread-library)
 $(objpfx)tst-resolv-res_init-thread: $(libdl) $(objpfx)libresolv.so \
   $(shared-thread-library)
 $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c
index b98cf92..0ed36cd 100644
--- a/resolv/resolv_conf.c
+++ b/resolv/resolv_conf.c
@@ -58,8 +58,10 @@ struct resolv_conf_global
      the array element is overwritten with NULL.  */
   struct resolv_conf_array array;
 
-  /* Start of the free list in the array.  The MSB is set if this
-     field has been initialized.  */
+  /* Start of the free list in the array.  Zero if the free list is
+     empty.  Otherwise, free_list_start >> 1 is the first element of
+     the free list (and the free list entries all have their LSB set
+     and are shifted one to the left).  */
   uintptr_t free_list_start;
 
   /* Cached current configuration object for /etc/resolv.conf.  */
@@ -567,11 +569,7 @@ decrement_at_index (struct resolv_conf_global *global_copy, size_t index)
           struct resolv_conf *conf = (struct resolv_conf *) *slot;
           conf_decrement (conf);
           /* Put the slot onto the free list.  */
-          if (global_copy->free_list_start == 0)
-            /* Not yet initialized.  */
-            *slot = 1;
-          else
-            *slot = global_copy->free_list_start;
+          *slot = global_copy->free_list_start;
           global_copy->free_list_start = (index << 1) | 1;
         }
     }
@@ -598,7 +596,8 @@ __resolv_conf_attach (struct __res_state *resp, struct resolv_conf *conf)
         index = global_copy->free_list_start >> 1;
         uintptr_t *slot = resolv_conf_array_at (&global_copy->array, index);
         global_copy->free_list_start = *slot;
-        assert (global_copy->free_list_start & 1);
+        assert (global_copy->free_list_start == 0
+                || global_copy->free_list_start & 1);
         /* Install the configuration pointer.  */
         *slot = (uintptr_t) conf;
       }
diff --git a/resolv/tst-resolv-res_init-multi.c b/resolv/tst-resolv-res_init-multi.c
new file mode 100644
index 0000000..bdc68a5
--- /dev/null
+++ b/resolv/tst-resolv-res_init-multi.c
@@ -0,0 +1,89 @@
+/* Multi-threaded test for resolver initialization.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <netdb.h>
+#include <resolv.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/xthread.h>
+
+/* Whether name lookups succeed does not really matter.  We use this
+   to trigger initialization of the resolver.  */
+static const char *test_hostname = "www.gnu.org";
+
+/* The different initialization methods.  */
+enum test_type { init, byname, gai };
+enum { type_count = 3 };
+
+/* Thread function.  Perform a few resolver options.  */
+static void *
+thread_func (void *closure)
+{
+  enum test_type *ptype = closure;
+  /* Perform a few calls to the requested operation.  */
+  TEST_VERIFY (*ptype >= 0);
+  TEST_VERIFY (*ptype < (int) type_count);
+  for (int i = 0; i < 3; ++i)
+    switch (*ptype)
+      {
+      case init:
+	res_init ();
+	break;
+      case byname:
+	gethostbyname (test_hostname);
+	break;
+      case gai:
+	{
+	  struct addrinfo hints = { 0, };
+	  struct addrinfo *ai = NULL;
+	  if (getaddrinfo (test_hostname, "80", &hints, &ai) == 0)
+	    freeaddrinfo (ai);
+	}
+	break;
+      }
+  free (ptype);
+  return NULL;
+}
+
+static int
+do_test (void)
+{
+  /* Start a small number of threads which perform resolver
+     operations.  */
+  enum { thread_count = 30 };
+
+  pthread_t threads[thread_count];
+  for (int i = 0; i < thread_count; ++i)
+    {
+      enum test_type *ptype = xmalloc (sizeof (*ptype));
+      *ptype = i % type_count;
+      threads[i] = xpthread_create (NULL, thread_func, ptype);
+    }
+  for (int i = 0; i < type_count; ++i)
+    {
+      enum test_type *ptype = xmalloc (sizeof (*ptype));
+      *ptype = i;
+      thread_func (ptype);
+    }
+  for (int i = 0; i < thread_count; ++i)
+    xpthread_join (threads[i]);
+  return 0;
+}
+
+#include <support/test-driver.c>

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                          |    9 ++++
 resolv/Makefile                    |    3 +
 resolv/resolv_conf.c               |   15 +++---
 resolv/tst-resolv-res_init-multi.c |   89 ++++++++++++++++++++++++++++++++++++
 4 files changed, 108 insertions(+), 8 deletions(-)
 create mode 100644 resolv/tst-resolv-res_init-multi.c


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]