Work around an assert failure in the dynamic linker's default thread

locking functions.  If an application loads a shared object with
dlopen() and the shared object has an init function which requires
lazy binding, then _rtld_bind is called when the thread is already
inside the dynamic linker.  This leads to a recursive acquisition
of the lock, which I was not expecting -- hence the assert failure.

This work-around makes the default locking functions handle recursive
locking.  It is NOT the correct fix -- that should be implemented
at the generic locking level rather than in the default locking
functions.  I will implement the correct fix in a future commit.

Since the dllockinit() interface will likely need to change, warn
about that in both the man page and the header file.
This commit is contained in:
John Polstra 1999-12-28 04:38:17 +00:00
parent 427db879c9
commit 3600eb76c6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=55165
6 changed files with 37 additions and 16 deletions

View File

@ -66,6 +66,7 @@ __BEGIN_DECLS
int dladdr __P((const void *, Dl_info *));
int dlclose __P((void *));
const char *dlerror __P((void));
/* XXX dllockinit() interface is likely to change. */
void dllockinit __P((void *_context,
void *(*_lock_create)(void *_context),
void (*_rlock_acquire)(void *_lock),

View File

@ -39,6 +39,10 @@
"void (*lock_release)(void *lock)" "void (*lock_destroy)(void *lock)" \
"void (*context_destroy)(void *context)"
.Sh DESCRIPTION
.Bf Sy
This interface is subject to change and should not be used yet.
.Ef
.Pp
Threads packages can call
.Nm
at initialization time to register locking functions for the dynamic

View File

@ -51,8 +51,11 @@ void
lockdflt_acquire(void *lock)
{
LockDflt *l = (LockDflt *)lock;
sigprocmask(SIG_BLOCK, &l->lock_mask, &l->old_mask);
assert(l->depth == 0);
sigset_t old_mask;
sigprocmask(SIG_BLOCK, &l->lock_mask, &old_mask);
if (l->depth == 0)
l->old_mask = old_mask;
l->depth++;
}
@ -81,9 +84,10 @@ void
lockdflt_release(void *lock)
{
LockDflt *l = (LockDflt *)lock;
assert(l->depth == 1);
l->depth--;
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
assert(l->depth >= 0);
if (l->depth == 0)
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
}
void

View File

@ -51,8 +51,11 @@ void
lockdflt_acquire(void *lock)
{
LockDflt *l = (LockDflt *)lock;
sigprocmask(SIG_BLOCK, &l->lock_mask, &l->old_mask);
assert(l->depth == 0);
sigset_t old_mask;
sigprocmask(SIG_BLOCK, &l->lock_mask, &old_mask);
if (l->depth == 0)
l->old_mask = old_mask;
l->depth++;
}
@ -81,9 +84,10 @@ void
lockdflt_release(void *lock)
{
LockDflt *l = (LockDflt *)lock;
assert(l->depth == 1);
l->depth--;
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
assert(l->depth >= 0);
if (l->depth == 0)
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
}
void

View File

@ -51,8 +51,11 @@ void
lockdflt_acquire(void *lock)
{
LockDflt *l = (LockDflt *)lock;
sigprocmask(SIG_BLOCK, &l->lock_mask, &l->old_mask);
assert(l->depth == 0);
sigset_t old_mask;
sigprocmask(SIG_BLOCK, &l->lock_mask, &old_mask);
if (l->depth == 0)
l->old_mask = old_mask;
l->depth++;
}
@ -81,9 +84,10 @@ void
lockdflt_release(void *lock)
{
LockDflt *l = (LockDflt *)lock;
assert(l->depth == 1);
l->depth--;
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
assert(l->depth >= 0);
if (l->depth == 0)
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
}
void

View File

@ -51,8 +51,11 @@ void
lockdflt_acquire(void *lock)
{
LockDflt *l = (LockDflt *)lock;
sigprocmask(SIG_BLOCK, &l->lock_mask, &l->old_mask);
assert(l->depth == 0);
sigset_t old_mask;
sigprocmask(SIG_BLOCK, &l->lock_mask, &old_mask);
if (l->depth == 0)
l->old_mask = old_mask;
l->depth++;
}
@ -81,9 +84,10 @@ void
lockdflt_release(void *lock)
{
LockDflt *l = (LockDflt *)lock;
assert(l->depth == 1);
l->depth--;
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
assert(l->depth >= 0);
if (l->depth == 0)
sigprocmask(SIG_SETMASK, &l->old_mask, NULL);
}
void