summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--nscd/nscd-client.h4
-rw-r--r--nscd/nscd_helper.c10
3 files changed, 15 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index d99c3c3990..684e94d3e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2006-04-25 Ulrich Drepper <drepper@redhat.com>
+ [BZ #2571]
+ * nscd/nscd_helper.c (__nscd_get_map_ref): Make mapptr argument a
+ volatile pointer so that the mapptr->mapped value is re-read after
+ the lock is retrieved.
+ * nscd/nscd-client.h: Update __nscd_get_map_ref prototype.
+
* include/features.h [_GNU_SOURCE] (_POSIX_C_SOURCE): Define to
200112L.
@@ -12,7 +18,7 @@
(struct hconf): Replace service related fields with placeholders.
[BZ #2386]
- * sysdeps/unix/sysv/linux/ia64/clone2.S: Check for NULL stakc
+ * sysdeps/unix/sysv/linux/ia64/clone2.S: Check for NULL stack
pointers to match other architectures.
* sysdeps/unix/sysv/linux/Makefile [subdirs=misc] (tests): Add
tst-clone.
diff --git a/nscd/nscd-client.h b/nscd/nscd-client.h
index 98c167eb62..440697f1be 100644
--- a/nscd/nscd-client.h
+++ b/nscd/nscd-client.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998, 1999, 2000, 2003, 2004, 2005
+/* Copyright (c) 1998, 1999, 2000, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
@@ -277,7 +277,7 @@ extern int __nscd_open_socket (const char *key, size_t keylen,
/* Get reference of mapping. */
extern struct mapped_database *__nscd_get_map_ref (request_type type,
const char *name,
- struct locked_map_ptr *mapptr,
+ volatile struct locked_map_ptr *mapptr,
int *gc_cyclep);
/* Unmap database. */
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
index fd749446be..1dfe746d7a 100644
--- a/nscd/nscd_helper.c
+++ b/nscd/nscd_helper.c
@@ -316,17 +316,18 @@ get_mapping (request_type type, const char *key,
struct mapped_database *
__nscd_get_map_ref (request_type type, const char *name,
- struct locked_map_ptr *mapptr, int *gc_cyclep)
+ volatile struct locked_map_ptr *mapptr, int *gc_cyclep)
{
struct mapped_database *cur = mapptr->mapped;
if (cur == NO_MAPPING)
return cur;
int cnt = 0;
- while (atomic_compare_and_exchange_val_acq (&mapptr->lock, 1, 0) != 0)
+ while (__builtin_expect (atomic_compare_and_exchange_val_acq (&mapptr->lock,
+ 1, 0) != 0, 0))
{
// XXX Best number of rounds?
- if (++cnt > 5)
+ if (__builtin_expect (++cnt > 5, 0))
return NO_MAPPING;
atomic_delay ();
@@ -340,7 +341,8 @@ __nscd_get_map_ref (request_type type, const char *name,
if (cur == NULL
|| (cur->head->nscd_certainly_running == 0
&& cur->head->timestamp + MAPPING_TIMEOUT < time (NULL)))
- cur = get_mapping (type, name, &mapptr->mapped);
+ cur = get_mapping (type, name,
+ (struct mapped_database **) &mapptr->mapped);
if (__builtin_expect (cur != NO_MAPPING, 1))
{