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:
parent
427db879c9
commit
3600eb76c6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=55165
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user