Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Block signals when using the exclusive lock.



details:   https://anonhg.NetBSD.org/src/rev/f3d8392b2776
branches:  trunk
changeset: 763648:f3d8392b2776
user:      joerg <joerg%NetBSD.org@localhost>
date:      Tue Mar 29 20:56:35 2011 +0000

description:
Block signals when using the exclusive lock.

diffstat:

 libexec/ld.elf_so/rtld.c |  85 +++++++++++++++++++++++++++--------------------
 libexec/ld.elf_so/rtld.h |   7 ++-
 libexec/ld.elf_so/tls.c  |  19 ++++++----
 usr.bin/ldd/ldd.c        |   8 ++--
 4 files changed, 68 insertions(+), 51 deletions(-)

diffs (truncated from 422 to 300 lines):

diff -r 3a5d71ee6bcc -r f3d8392b2776 libexec/ld.elf_so/rtld.c
--- a/libexec/ld.elf_so/rtld.c  Tue Mar 29 20:10:31 2011 +0000
+++ b/libexec/ld.elf_so/rtld.c  Tue Mar 29 20:56:35 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtld.c,v 1.147 2011/03/28 00:37:40 joerg Exp $  */
+/*     $NetBSD: rtld.c,v 1.148 2011/03/29 20:56:35 joerg Exp $  */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: rtld.c,v 1.147 2011/03/28 00:37:40 joerg Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.148 2011/03/29 20:56:35 joerg Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -121,8 +121,8 @@
 #endif /* RTLD_DEBUG */
 extern Elf_Dyn  _DYNAMIC;
 
-static void _rtld_call_fini_functions(int);
-static void _rtld_call_init_functions(void);
+static void _rtld_call_fini_functions(sigset_t *, int);
+static void _rtld_call_init_functions(sigset_t *);
 static void _rtld_initlist_visit(Objlist *, Obj_Entry *, int);
 static void _rtld_initlist_tsort(Objlist *, int);
 static Obj_Entry *_rtld_dlcheck(void *);
@@ -130,12 +130,12 @@
 static void _rtld_init_dag1(Obj_Entry *, Obj_Entry *);
 static void _rtld_objlist_remove(Objlist *, Obj_Entry *);
 static void _rtld_objlist_clear(Objlist *);
-static void _rtld_unload_object(Obj_Entry *, bool);
+static void _rtld_unload_object(sigset_t *, Obj_Entry *, bool);
 static void _rtld_unref_dag(Obj_Entry *);
 static Obj_Entry *_rtld_obj_from_addr(const void *);
 
 static void
-_rtld_call_fini_functions(int force)
+_rtld_call_fini_functions(sigset_t *mask, int force)
 {
        Objlist_Entry *elm;
        Objlist finilist;
@@ -168,9 +168,9 @@
                 * XXX the fini() call is done.
                 */
                fini = obj->fini;
-               _rtld_exclusive_exit();
+               _rtld_exclusive_exit(mask);
                (*fini)();
-               _rtld_exclusive_enter();
+               _rtld_exclusive_enter(mask);
                if (_rtld_objgen != cur_objgen) {
                        dbg(("restarting fini iteration"));
                        _rtld_objlist_clear(&finilist);
@@ -192,9 +192,9 @@
                obj->fini_called = 1;
                /* XXX See above for the race condition here */
                fini = obj->fini;
-               _rtld_exclusive_exit();
+               _rtld_exclusive_exit(mask);
                (*fini)();
-               _rtld_exclusive_enter();
+               _rtld_exclusive_enter(mask);
                if (_rtld_objgen != cur_objgen) {
                        dbg(("restarting fini iteration"));
                        _rtld_objlist_clear(&finilist);
@@ -206,7 +206,7 @@
 }
 
 static void
-_rtld_call_init_functions()
+_rtld_call_init_functions(sigset_t *mask)
 {
        Objlist_Entry *elm;
        Objlist initlist;
@@ -231,9 +231,9 @@
                    obj->path, (void *)obj->init));
                obj->init_called = 1;
                init = obj->init;
-               _rtld_exclusive_exit();
+               _rtld_exclusive_exit(mask);
                (*init)();
-               _rtld_exclusive_enter();
+               _rtld_exclusive_enter(mask);
                if (_rtld_objgen != cur_objgen) {
                        dbg(("restarting init iteration"));
                        _rtld_objlist_clear(&initlist);
@@ -251,9 +251,9 @@
                    (void *)obj->init));
                obj->init_called = 1;
                init = obj->init;
-               _rtld_exclusive_exit();
+               _rtld_exclusive_exit(mask);
                (*init)();
-               _rtld_exclusive_enter();
+               _rtld_exclusive_enter(mask);
                if (_rtld_objgen != cur_objgen) {
                        dbg(("restarting init iteration"));
                        _rtld_objlist_clear(&initlist);
@@ -338,13 +338,15 @@
 static void
 _rtld_exit(void)
 {
+       sigset_t mask;
+
        dbg(("rtld_exit()"));
 
-       _rtld_exclusive_enter();
+       _rtld_exclusive_enter(&mask);
 
-       _rtld_call_fini_functions(1);
+       _rtld_call_fini_functions(&mask, 1);
 
-       _rtld_exclusive_exit();
+       _rtld_exclusive_exit(&mask);
 }
 
 /*
@@ -383,6 +385,7 @@
        const char **real___progname;
        const Obj_Entry **real___mainprog_obj;
        char ***real_environ;
+       sigset_t        mask;
 #ifdef DEBUG
        const char     *ld_debug;
 #endif
@@ -675,15 +678,15 @@
        if (real___mainprog_obj)
                *real___mainprog_obj = _rtld_objmain;
 
-       _rtld_exclusive_enter();
+       _rtld_exclusive_enter(&mask);
 
        dbg(("calling _init functions"));
-       _rtld_call_init_functions();
+       _rtld_call_init_functions(&mask);
 
        dbg(("control at program entry point = %p, obj = %p, exit = %p",
             _rtld_objmain->entry, _rtld_objmain, _rtld_exit));
 
-       _rtld_exclusive_exit();
+       _rtld_exclusive_exit(&mask);
 
        /*
         * Return with the entry point and the exit procedure in at the top
@@ -792,7 +795,7 @@
  * Note, this is called only for objects loaded by dlopen().
  */
 static void
-_rtld_unload_object(Obj_Entry *root, bool do_fini_funcs)
+_rtld_unload_object(sigset_t *mask, Obj_Entry *root, bool do_fini_funcs)
 {
 
        _rtld_unref_dag(root);
@@ -803,7 +806,7 @@
 
                /* Finalize objects that are about to be unmapped. */
                if (do_fini_funcs)
-                       _rtld_call_fini_functions(0);
+                       _rtld_call_fini_functions(mask, 0);
 
                /* Remove the DAG from all objects' DAG lists. */
                SIMPLEQ_FOREACH(elm, &root->dagmembers, link)
@@ -880,15 +883,16 @@
 dlclose(void *handle)
 {
        Obj_Entry *root;
+       sigset_t mask;
 
        dbg(("dlclose of %p", handle));
 
-       _rtld_exclusive_enter();
+       _rtld_exclusive_enter(&mask);
 
        root = _rtld_dlcheck(handle);
 
        if (root == NULL) {
-               _rtld_exclusive_exit();
+               _rtld_exclusive_exit(&mask);
                return -1;
        }
 
@@ -896,12 +900,12 @@
        _rtld_debug_state();
 
        --root->dl_refcount;
-       _rtld_unload_object(root, true);
+       _rtld_unload_object(&mask, root, true);
 
        _rtld_debug.r_state = RT_CONSISTENT;
        _rtld_debug_state();
 
-       _rtld_exclusive_exit();
+       _rtld_exclusive_exit(&mask);
 
        return 0;
 }
@@ -925,10 +929,11 @@
        int flags = _RTLD_DLOPEN;
        bool nodelete;
        bool now;
+       sigset_t mask;
 
        dbg(("dlopen of %s %d", name, mode));
 
-       _rtld_exclusive_enter();
+       _rtld_exclusive_enter(&mask);
 
        flags |= (mode & RTLD_GLOBAL) ? _RTLD_GLOBAL : 0;
        flags |= (mode & RTLD_NOLOAD) ? _RTLD_NOLOAD : 0;
@@ -955,11 +960,11 @@
                            (_rtld_init_dag(obj),
                            _rtld_relocate_objects(obj,
                            (now || obj->z_now))) == -1) {
-                               _rtld_unload_object(obj, false);
+                               _rtld_unload_object(&mask, obj, false);
                                obj->dl_refcount--;
                                obj = NULL;
                        } else {
-                               _rtld_call_init_functions();
+                               _rtld_call_init_functions(&mask);
                        }
                }
                if (obj != NULL) {
@@ -973,7 +978,7 @@
        _rtld_debug.r_state = RT_CONSISTENT;
        _rtld_debug_state();
 
-       _rtld_exclusive_exit();
+       _rtld_exclusive_exit(&mask);
 
        return obj;
 }
@@ -1010,8 +1015,8 @@
 #endif
 
 #ifdef __HAVE_FUNCTION_DESCRIPTORS
-#define        lookup_mutex_enter()    _rtld_exclusive_enter()
-#define        lookup_mutex_exit()     _rtld_exclusive_exit()
+#define        lookup_mutex_enter()    _rtld_exclusive_enter(&mask)
+#define        lookup_mutex_exit()     _rtld_exclusive_exit(&mask)
 #else
 #define        lookup_mutex_enter()    _rtld_shared_enter()
 #define        lookup_mutex_exit()     _rtld_shared_exit()
@@ -1026,7 +1031,10 @@
        const Elf_Sym *def;
        const Obj_Entry *defobj;
        void *retaddr;
-       DoneList donelist; 
+       DoneList donelist;
+#ifdef __HAVE_FUNCTION_DESCRIPTORS
+       sigset_t mask;
+#endif
 
        dbg(("dlsym of %s in %p", name, handle));
 
@@ -1471,11 +1479,15 @@
 }
 
 void
-_rtld_exclusive_enter(void)
+_rtld_exclusive_enter(sigset_t *mask)
 {
        lwpid_t waiter, self = _lwp_self();
        unsigned int locked_value = (unsigned int)self | RTLD_EXCLUSIVE_MASK;
        unsigned int cur;
+       sigset_t blockmask;
+
+       sigfillset(&blockmask);
+       sigprocmask(SIG_BLOCK, &blockmask, mask);
 
        membar_enter();
 
@@ -1497,7 +1509,7 @@
 }
 
 void
-_rtld_exclusive_exit(void)
+_rtld_exclusive_exit(sigset_t *mask)
 {
        lwpid_t waiter;
 
@@ -1509,4 +1521,5 @@
                _lwp_unpark(waiter, __UNVOLATILE(&_rtld_mutex));
 
        membar_exit();
+       sigprocmask(SIG_SETMASK, mask, NULL);
 }
diff -r 3a5d71ee6bcc -r f3d8392b2776 libexec/ld.elf_so/rtld.h
--- a/libexec/ld.elf_so/rtld.h  Tue Mar 29 20:10:31 2011 +0000
+++ b/libexec/ld.elf_so/rtld.h  Tue Mar 29 20:56:35 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtld.h,v 1.104 2011/03/25 18:07:04 joerg Exp $  */
+/*     $NetBSD: rtld.h,v 1.105 2011/03/29 20:56:35 joerg Exp $  */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -35,6 +35,7 @@



Home | Main Index | Thread Index | Old Index