summaryrefslogtreecommitdiff
path: root/libc/stdlib/malloc/free.c
diff options
context:
space:
mode:
authorMiles Bader <miles@lsi.nec.co.jp>2002-10-15 02:15:16 +0000
committerMiles Bader <miles@lsi.nec.co.jp>2002-10-15 02:15:16 +0000
commit6882d43363b5411a16657378b2f8110988dd9660 (patch)
tree9ece05cc9c4ae924d012f723b9e20e5eb0f8f396 /libc/stdlib/malloc/free.c
parenta1d020f74e0702791d2d4cbad5a69bcc2adfecfc (diff)
Fix locking to not deadlock when __UCLIBC_UCLINUX_BROKEN_MUNMAP__ is defined.
Diffstat (limited to 'libc/stdlib/malloc/free.c')
-rw-r--r--libc/stdlib/malloc/free.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/libc/stdlib/malloc/free.c b/libc/stdlib/malloc/free.c
index 6c3211360..a00f996d9 100644
--- a/libc/stdlib/malloc/free.c
+++ b/libc/stdlib/malloc/free.c
@@ -105,7 +105,7 @@ free_to_heap (void *mem, struct heap *heap)
#ifdef MALLOC_USE_SBRK
- /* Release the main lock; we're still holding the sbrk lock. */
+ /* Release the heap lock; we're still holding the sbrk lock. */
__heap_unlock (heap);
/* Lower the brk. */
sbrk (start - end);
@@ -161,16 +161,21 @@ free_to_heap (void *mem, struct heap *heap)
else
__malloc_mmapped_blocks = next_mmb;
+ /* Start searching again from the end of this block. */
+ start = mmb_end;
+
+ /* We have to unlock the heap before we recurse to free the mmb
+ descriptor, because we might be unmapping from the mmb
+ heap. */
+ __heap_unlock (heap);
+
/* Release the descriptor block we used. */
free_to_heap (mmb, &__malloc_mmb_heap);
/* Do the actual munmap. */
- __heap_unlock (heap);
munmap ((void *)mmb_start, mmb_end - mmb_start);
- __heap_lock (heap);
- /* Start searching again from the end of that block. */
- start = mmb_end;
+ __heap_lock (heap);
# ifdef __UCLIBC_HAS_THREADS__
/* In a multi-threaded program, it's possible that PREV_MMB has