diff --git a/ChangeLog b/ChangeLog index d99c3c3990..684e94d3e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2006-04-25 Ulrich Drepper + [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 , 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)) {