This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
PATCH: Fix lock/unlock in sysdeps/ia64/dl-fptr.c
- To: davidm at hpl dot hp dot com
- Subject: PATCH: Fix lock/unlock in sysdeps/ia64/dl-fptr.c
- From: "H . J . Lu" <hjl at lucon dot org>
- Date: Wed, 26 Sep 2001 20:23:45 -0700
- Cc: GNU C Library <libc-alpha at sourceware dot cygnus dot com>
I don't have ia64. But I think lock/unlock in sysdeps/ia64/dl-fptr.c
are wrong. They don't even follow the comments:
/* Locking is tricky: we may get a signal while holding the lock and
the signal handler may end up calling into the dynamic loader
again. Also, if a real-time process spins on the lock, a
non-realtime process may never get the chance to release it's lock,
unless the realtime process relinquishes the CPU from time to time.
Hence we (a) block signals before acquiring the lock and (b) do a
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
nanosleep() when we detect prolongued contention. */
Bad things can happen if there is a signal between acquiring the lock
and blocking signals. Here is a patch.
BTW, I think glibc should have a generic implementation for function
descriptors so that ia64, hppa, ... can share the code.
H.J.
----
2001-09-26 H.J. Lu <hjl@gnu.org>
* sysdeps/ia64/dl-fptr.c (lock): Block signals before acquiring
lock.
(unlock): Unblock signals after releasing lock.
--- sysdeps/ia64/dl-fptr.c.lock Tue Sep 11 07:42:44 2001
+++ sysdeps/ia64/dl-fptr.c Wed Sep 26 20:14:33 2001
@@ -72,6 +72,7 @@ local =
int i = 10000; \
if (!__sigismember (&(l)->full_sigset, SIGINT)) \
__sigfillset (&(l)->full_sigset); \
+ __sigprocmask (SIG_BLOCK, &(l)->full_sigset, &_saved_set); \
\
while (testandset ((int *) &(l)->lock)) \
{ \
@@ -84,11 +85,10 @@ local =
ts.tv_sec = 0; \
ts.tv_nsec = 1*1000*1000; \
__nanosleep (&ts, NULL); \
- } \
- __sigprocmask (SIG_BLOCK, &(l)->full_sigset, &_saved_set);
+ }
# define unlock(l) \
- __sigprocmask (SIG_SETMASK, &_saved_set, NULL); \
(l)->lock = 0; \
+ __sigprocmask (SIG_SETMASK, &_saved_set, NULL); \
}
#else
# define lock(l)