]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
* elf/dl-close.c (_dl_close_worker): Renamed from _dl_close and
authorJakub Jelinek <jakub@redhat.com>
Fri, 12 Jan 2007 15:21:33 +0000 (15:21 +0000)
committerJakub Jelinek <jakub@redhat.com>
Fri, 12 Jan 2007 15:21:33 +0000 (15:21 +0000)
split out locking and parameter checking.
(_dl_close): Call _dl_close_worker after locking and checking.
* elf/dl-open.c (_dl_open): Call _dl_close_worker instead of
_dl_close.
* elf/Makefile: Add rules to build and run tst-thrlock.
* elf/tst-thrlock.c:  New file.

[BZ #3429]
* elf/dl-open.c (dl_open_worker): Keep holding dl_load_lock until
we are sure we do not need it anymore for _dl_close.  Also move
the asserts inside the lock region.
Patch mostly by Suzuki <suzuki@in.ibm.com>.

ChangeLog
elf/Makefile
elf/dl-close.c
elf/dl-open.c
elf/tst-thrlock.c

index 3785256cd4afb01e14cc26b9e473e45a5be9f82a..dc410a1f8c55985d57edecc890915c3540a79570 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2006-10-27  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf/dl-close.c (_dl_close_worker): Renamed from _dl_close and
+       split out locking and parameter checking.
+       (_dl_close): Call _dl_close_worker after locking and checking.
+       * elf/dl-open.c (_dl_open): Call _dl_close_worker instead of
+       _dl_close.
+       * elf/Makefile: Add rules to build and run tst-thrlock.
+       * elf/tst-thrlock.c:  New file.
+
+       [BZ #3429]
+       * elf/dl-open.c (dl_open_worker): Keep holding dl_load_lock until
+       we are sure we do not need it anymore for _dl_close.  Also move
+       the asserts inside the lock region.
+       Patch mostly by Suzuki <suzuki@in.ibm.com>.
+
 2006-10-17  Jakub Jelinek  <jakub@redhat.com>
 
        * sunrpc/xdr_mem.c (xdrmem_setpos): Don't compare addresses
index b1a9bab022d0bd100d8d79e4ff62c7d302309c43..06e376d80321222a154e6005f7a9164820a117d4 100644 (file)
@@ -171,7 +171,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
         tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \
         unload3 unload4 unload5 unload6 unload7 tst-global1 order2 \
         tst-audit1 tst-audit2 \
-        tst-stackguard1 tst-addr1
+        tst-stackguard1 tst-addr1 tst-thrlock
 #       reldep9
 test-srcs = tst-pathopt
 tests-vis-yes = vismain
@@ -916,3 +916,5 @@ $(objpfx)tst-leaks1-mem: $(objpfx)tst-leaks1.out
 tst-leaks1-ENV = MALLOC_TRACE=$(objpfx)tst-leaks1.mtrace
 
 $(objpfx)tst-addr1: $(libdl)
+
+$(objpfx)tst-thrlock: $(libdl) $(shared-thread-library)
index 6a2ad976a74141ce96bf74ad0c4fc28b47e8cb9b..cc7a9b3213501b5f292c28e1944179a1da685c5c 100644 (file)
@@ -101,22 +101,9 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
 
 
 void
-_dl_close (void *_map)
+_dl_close_worker (struct link_map *map)
 {
-  struct link_map *map = _map;
   Lmid_t ns = map->l_ns;
-  unsigned int i;
-  /* First see whether we can remove the object at all.  */
-  if (__builtin_expect (map->l_flags_1 & DF_1_NODELETE, 0)
-      && map->l_init_called)
-    /* Nope.  Do nothing.  */
-    return;
-
-  if (__builtin_expect (map->l_direct_opencount, 1) == 0)
-    GLRO(dl_signal_error) (0, map->l_name, NULL, N_("shared object not open"));
-
-  /* Acquire the lock.  */
-  __rtld_lock_lock_recursive (GL(dl_load_lock));
 
   /* One less direct use.  */
   --map->l_direct_opencount;
@@ -137,7 +124,6 @@ _dl_close (void *_map)
        _dl_debug_printf ("\nclosing file=%s; direct_opencount=%u\n",
                          map->l_name, map->l_direct_opencount);
 
-      __rtld_lock_unlock_recursive (GL(dl_load_lock));
       return;
     }
 
@@ -240,7 +226,7 @@ _dl_close (void *_map)
 #endif
   bool unload_any = false;
   unsigned int first_loaded = ~0;
-  for (i = 0; i < nloaded; ++i)
+  for (unsigned int i = 0; i < nloaded; ++i)
     {
       struct link_map *imap = maps[i];
 
@@ -411,7 +397,7 @@ _dl_close (void *_map)
 
   /* Check each element of the search list to see if all references to
      it are gone.  */
-  for (i = first_loaded; i < nloaded; ++i)
+  for (unsigned int i = first_loaded; i < nloaded; ++i)
     {
       struct link_map *imap = maps[i];
       if (!used[i])
@@ -627,6 +613,30 @@ _dl_close (void *_map)
     goto retry;
 
   dl_close_state = not_pending;
+}
+
+
+void
+_dl_close (void *_map)
+{
+  struct link_map *map = _map;
+
+  /* First see whether we can remove the object at all.  */
+  if (__builtin_expect (map->l_flags_1 & DF_1_NODELETE, 0))
+    {
+      assert (map->l_init_called);
+      /* Nope.  Do nothing.  */
+      return;
+    }
+
+  if (__builtin_expect (map->l_direct_opencount, 1) == 0)
+    GLRO(dl_signal_error) (0, map->l_name, NULL, N_("shared object not open"));
+
+  /* Acquire the lock.  */
+  __rtld_lock_lock_recursive (GL(dl_load_lock));
+
+  _dl_close_worker (map);
+
   __rtld_lock_unlock_recursive (GL(dl_load_lock));
 }
 
index 8d057f82eb923c7eee6fb5f30f20325d29d17f6f..50c0d54f274b22f9a6412cf7cc61ce51d5aff24f 100644 (file)
@@ -547,15 +547,9 @@ no more namespaces available for dlmopen()"));
   _dl_unload_cache ();
 #endif
 
-  /* Release the lock.  */
-  __rtld_lock_unlock_recursive (GL(dl_load_lock));
-
+  /* See if an error occurred during loading.  */
   if (__builtin_expect (errstring != NULL, 0))
     {
-      /* Some error occurred during loading.  */
-      char *local_errstring;
-      size_t len_errstring;
-
       /* Remove the object from memory.  It may be in an inconsistent
         state if relocation failed, for example.  */
       if (args.map)
@@ -572,12 +566,18 @@ no more namespaces available for dlmopen()"));
            GL(dl_tls_dtv_gaps) = true;
 #endif
 
-         _dl_close (args.map);
+         _dl_close_worker (args.map);
        }
 
+      assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
+
+      /* Release the lock.  */
+      __rtld_lock_unlock_recursive (GL(dl_load_lock));
+
       /* Make a local copy of the error string so that we can release the
         memory allocated for it.  */
-      len_errstring = strlen (errstring) + 1;
+      size_t len_errstring = strlen (errstring) + 1;
+      char *local_errstring;
       if (objname == errstring + len_errstring)
        {
          size_t total_len = len_errstring + strlen (objname) + 1;
@@ -594,14 +594,15 @@ no more namespaces available for dlmopen()"));
       if (malloced)
        free ((char *) errstring);
 
-      assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
-
       /* Reraise the error.  */
       _dl_signal_error (errcode, objname, NULL, local_errstring);
     }
 
   assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
 
+  /* Release the lock.  */
+  __rtld_lock_unlock_recursive (GL(dl_load_lock));
+
 #ifndef SHARED
   DL_STATIC_INIT (args.map);
 #endif
index fe72eba141e47f20a59efe598abe9d5769e16be4..71f1fbb35d1dc56695a3d08d77ab980e86aa483e 100644 (file)
@@ -27,9 +27,8 @@ tf (void *arg)
   return NULL;
 }
 
-
-static int
-do_test (void)
+int
+main (void)
 {
 #define N 10
   pthread_t th[N];
@@ -54,6 +53,3 @@ do_test (void)
     }
   return 0;
 }
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"