diff options
author | Martin Baulig <martin@novell.com> | 2006-06-29 00:06:07 +0400 |
---|---|---|
committer | Martin Baulig <martin@novell.com> | 2006-06-29 00:06:07 +0400 |
commit | e197d5a04732f9b519e9b1c708f09cd58484eef8 (patch) | |
tree | 061eff7d16065e4c06a7d9cd16b1e617044ef615 /libgc/darwin_stop_world.c | |
parent | 3bca46b08b000621ece4bd8057486dc0a5e52ce4 (diff) |
2006-06-28 Martin Baulig <martin@ximian.com>
* darwin_stop_world.c, pthread_support.c: Committing a patch from
Allan Hsu <allan@imeem.com> to fix memory leaks; see bug #78628.
svn path=/trunk/mono/; revision=62128
Diffstat (limited to 'libgc/darwin_stop_world.c')
-rw-r--r-- | libgc/darwin_stop_world.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/libgc/darwin_stop_world.c b/libgc/darwin_stop_world.c index 53604450328..3c2d8cfa655 100644 --- a/libgc/darwin_stop_world.c +++ b/libgc/darwin_stop_world.c @@ -167,6 +167,7 @@ void GC_push_all_stacks() { void GC_push_all_stacks() { int i; + task_t my_task; kern_return_t r; mach_port_t me; ptr_t lo, hi; @@ -176,7 +177,8 @@ void GC_push_all_stacks() { me = mach_thread_self(); if (!GC_thr_initialized) GC_thr_init(); - r = task_threads(current_task(), &act_list, &listcount); + my_task = current_task(); + r = task_threads(my_task, &act_list, &listcount); if(r != KERN_SUCCESS) ABORT("task_threads failed"); for(i = 0; i < listcount; i++) { thread_act_t thread = act_list[i]; @@ -265,9 +267,11 @@ void GC_push_all_stacks() { (unsigned long) hi ); # endif - GC_push_all_stack(lo, hi); + GC_push_all_stack(lo, hi); + mach_port_deallocate(my_task, thread); } /* for(p=GC_threads[i]...) */ - vm_deallocate(current_task(), (vm_address_t)act_list, sizeof(thread_t) * listcount); + vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount); + mach_port_deallocate(my_task, me); } #endif /* !DARWIN_DONT_PARSE_STACK */ @@ -361,6 +365,8 @@ int GC_suspend_thread_list(thread_act_array_t act_list, int count, } if (!found) GC_mach_threads_count++; } + + mach_port_deallocate(current_task(), my_thread); return changed; } @@ -370,6 +376,7 @@ void GC_stop_world() { int i, changes; GC_thread p; + task_t my_task = current_task(); mach_port_t my_thread = mach_thread_self(); kern_return_t kern_result; thread_act_array_t act_list, prev_list; @@ -405,13 +412,21 @@ void GC_stop_world() prevcount = 0; do { int result; - kern_result = task_threads(current_task(), &act_list, &listcount); + kern_result = task_threads(my_task, &act_list, &listcount); result = GC_suspend_thread_list(act_list, listcount, prev_list, prevcount); changes = result; prev_list = act_list; prevcount = listcount; - vm_deallocate(current_task(), (vm_address_t)act_list, sizeof(thread_t) * listcount); + + if(kern_result == KERN_SUCCESS) { + int i; + + for(i = 0; i < listcount; i++) + mach_port_deallocate(my_task, act_list[i]); + + vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount); + } } while (changes); @@ -428,12 +443,15 @@ void GC_stop_world() #if DEBUG_THREADS GC_printf1("World stopped from 0x%lx\n", my_thread); #endif + + mach_port_deallocate(my_task, my_thread); } /* Caller holds allocation lock, and has held it continuously since */ /* the world stopped. */ void GC_start_world() { + task_t my_task = current_task(); mach_port_t my_thread = mach_thread_self(); int i, j; GC_thread p; @@ -454,7 +472,7 @@ void GC_start_world() } # endif - kern_result = task_threads(current_task(), &act_list, &listcount); + kern_result = task_threads(my_task, &act_list, &listcount); for(i = 0; i < listcount; i++) { thread_act_t thread = act_list[i]; if (thread != my_thread && @@ -482,8 +500,12 @@ void GC_start_world() } } } + + mach_port_deallocate(my_task, thread); } - vm_deallocate(current_task(), (vm_address_t)act_list, sizeof(thread_t) * listcount); + vm_deallocate(my_task, (vm_address_t)act_list, sizeof(thread_t) * listcount); + + mach_port_deallocate(my_task, my_thread); # if DEBUG_THREADS GC_printf0("World started\n"); # endif |