FreeBSD Bugzilla – Attachment 178720 Details for
Bug 215826
C++ program signal handlers not called
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Fix nested write locks for the compat rtld locking.
1.patch (text/plain), 3.19 KB, created by
Konstantin Belousov
on 2017-01-10 15:21:38 UTC
(
hide
)
Description:
Fix nested write locks for the compat rtld locking.
Filename:
MIME Type:
Creator:
Konstantin Belousov
Created:
2017-01-10 15:21:38 UTC
Size:
3.19 KB
patch
obsolete
>diff --git a/libexec/rtld-elf/rtld_lock.c b/libexec/rtld-elf/rtld_lock.c >index f31546c4ac9..5c85c8cbd28 100644 >--- a/libexec/rtld-elf/rtld_lock.c >+++ b/libexec/rtld-elf/rtld_lock.c >@@ -38,8 +38,8 @@ > * In this algorithm the lock is a single word. Its low-order bit is > * set when a writer holds the lock. The remaining high-order bits > * contain a count of readers desiring the lock. The algorithm requires >- * atomic "compare_and_store" and "add" operations, which we implement >- * using assembly language sequences in "rtld_start.S". >+ * atomic "compare_and_store" and "add" operations, which we take >+ * from machine/atomic.h. > */ > > #include <sys/param.h> >@@ -64,10 +64,10 @@ typedef struct Struct_Lock { > } Lock; > > static sigset_t fullsigmask, oldsigmask; >-static int thread_flag; >+static int thread_flag, wnested; > > static void * >-def_lock_create() >+def_lock_create(void) > { > void *base; > char *p; >@@ -117,29 +117,38 @@ def_rlock_acquire(void *lock) > static void > def_wlock_acquire(void *lock) > { >- Lock *l = (Lock *)lock; >- sigset_t tmp_oldsigmask; >- >- for ( ; ; ) { >- sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask); >- if (atomic_cmpset_acq_int(&l->lock, 0, WAFLAG)) >- break; >- sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL); >- } >- oldsigmask = tmp_oldsigmask; >+ Lock *l; >+ sigset_t tmp_oldsigmask; >+ int w; >+ >+ l = (Lock *)lock; >+ for (;;) { >+ w = atomic_fetchadd_int(&wnested, 1); >+ if (w == 0) >+ sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask); >+ if (atomic_cmpset_acq_int(&l->lock, 0, WAFLAG)) >+ break; >+ if (atomic_fetchadd_int(&wnested, -1) == 1) >+ sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL); >+ } >+ if (w == 0) >+ oldsigmask = tmp_oldsigmask; > } > > static void > def_lock_release(void *lock) > { >- Lock *l = (Lock *)lock; >- >- if ((l->lock & WAFLAG) == 0) >- atomic_add_rel_int(&l->lock, -RC_INCR); >- else { >- atomic_add_rel_int(&l->lock, -WAFLAG); >- sigprocmask(SIG_SETMASK, &oldsigmask, NULL); >- } >+ Lock *l; >+ >+ l = (Lock *)lock; >+ if ((l->lock & WAFLAG) == 0) >+ atomic_add_rel_int(&l->lock, -RC_INCR); >+ else { >+ assert(wnested > 0); >+ atomic_add_rel_int(&l->lock, -WAFLAG); >+ if (atomic_fetchadd_int(&wnested, -1) == 1) >+ sigprocmask(SIG_SETMASK, &oldsigmask, NULL); >+ } > } > > static int >@@ -269,7 +278,7 @@ lock_restart_for_upgrade(RtldLockState *lockstate) > } > > void >-lockdflt_init() >+lockdflt_init(void) > { > int i; > >@@ -373,12 +382,12 @@ _rtld_atfork_pre(int *locks) > return; > > /* >- * Warning: this does not work with the rtld compat locks >- * above, since the thread signal mask is corrupted (set to >- * all signals blocked) if two locks are taken in write mode. >- * The caller of the _rtld_atfork_pre() must provide the >- * working implementation of the locks, and libthr locks are >- * fine. >+ * Warning: this did not worked well with the rtld compat >+ * locks above, when the thread signal mask was corrupted (set >+ * to all signals blocked) if two locks were taken >+ * simultaneously in the write mode. The caller of the >+ * _rtld_atfork_pre() must provide the working implementation >+ * of the locks anyway, and libthr locks are fine. > */ > wlock_acquire(rtld_phdr_lock, &ls[0]); > wlock_acquire(rtld_bind_lock, &ls[1]);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 215826
:
178664
|
178670
| 178720