mirror of git://sourceware.org/git/glibc.git
Update.
2004-12-10 Ulrich Drepper <drepper@redhat.com> * malloc/arena.c (arena_get2): Prevent endless loop if arenas and list lock are taken.
This commit is contained in:
parent
410b107177
commit
8c7d3691c4
|
|
@ -1,3 +1,8 @@
|
||||||
|
2004-12-10 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* malloc/arena.c (arena_get2): Prevent endless loop if arenas and
|
||||||
|
list lock are taken.
|
||||||
|
|
||||||
2004-12-08 Thorsten Kukuk <kukuk@suse.de>
|
2004-12-08 Thorsten Kukuk <kukuk@suse.de>
|
||||||
|
|
||||||
* nis/nss_nisplus/nisplus-netgrp.c (_nss_nisplus_getnetgrent_r):
|
* nis/nss_nisplus/nisplus-netgrp.c (_nss_nisplus_getnetgrent_r):
|
||||||
|
|
|
||||||
|
|
@ -782,9 +782,12 @@ arena_get2(a_tsd, size) mstate a_tsd; size_t size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the global, circularly linked list for available arenas. */
|
/* Check the global, circularly linked list for available arenas. */
|
||||||
|
bool retried = false;
|
||||||
repeat:
|
repeat:
|
||||||
do {
|
do {
|
||||||
if(!mutex_trylock(&a->mutex)) {
|
if(!mutex_trylock(&a->mutex)) {
|
||||||
|
if (retried)
|
||||||
|
(void)mutex_unlock(&list_lock);
|
||||||
THREAD_STAT(++(a->stat_lock_loop));
|
THREAD_STAT(++(a->stat_lock_loop));
|
||||||
tsd_setspecific(arena_key, (Void_t *)a);
|
tsd_setspecific(arena_key, (Void_t *)a);
|
||||||
return a;
|
return a;
|
||||||
|
|
@ -796,29 +799,33 @@ arena_get2(a_tsd, size) mstate a_tsd; size_t size;
|
||||||
happen during `atfork', or for example on systems where thread
|
happen during `atfork', or for example on systems where thread
|
||||||
creation makes it temporarily impossible to obtain _any_
|
creation makes it temporarily impossible to obtain _any_
|
||||||
locks. */
|
locks. */
|
||||||
if(mutex_trylock(&list_lock)) {
|
if(!retried && mutex_trylock(&list_lock)) {
|
||||||
|
/* We will block to not run in a busy loop. */
|
||||||
|
(void)mutex_lock(&list_lock);
|
||||||
|
|
||||||
|
/* Since we blocked there might be an arena available now. */
|
||||||
|
retried = true;
|
||||||
a = a_tsd;
|
a = a_tsd;
|
||||||
goto repeat;
|
goto repeat;
|
||||||
}
|
}
|
||||||
(void)mutex_unlock(&list_lock);
|
|
||||||
|
|
||||||
/* Nothing immediately available, so generate a new arena. */
|
/* Nothing immediately available, so generate a new arena. */
|
||||||
a = _int_new_arena(size);
|
a = _int_new_arena(size);
|
||||||
if(!a)
|
if(a)
|
||||||
return 0;
|
{
|
||||||
|
|
||||||
tsd_setspecific(arena_key, (Void_t *)a);
|
tsd_setspecific(arena_key, (Void_t *)a);
|
||||||
mutex_init(&a->mutex);
|
mutex_init(&a->mutex);
|
||||||
mutex_lock(&a->mutex); /* remember result */
|
mutex_lock(&a->mutex); /* remember result */
|
||||||
|
|
||||||
/* Add the new arena to the global list. */
|
/* Add the new arena to the global list. */
|
||||||
(void)mutex_lock(&list_lock);
|
|
||||||
a->next = main_arena.next;
|
a->next = main_arena.next;
|
||||||
atomic_write_barrier ();
|
atomic_write_barrier ();
|
||||||
main_arena.next = a;
|
main_arena.next = a;
|
||||||
(void)mutex_unlock(&list_lock);
|
|
||||||
|
|
||||||
THREAD_STAT(++(a->stat_lock_loop));
|
THREAD_STAT(++(a->stat_lock_loop));
|
||||||
|
}
|
||||||
|
(void)mutex_unlock(&list_lock);
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue