diff options
author | Martin Baulig <martin@novell.com> | 2006-05-17 14:51:31 +0400 |
---|---|---|
committer | Martin Baulig <martin@novell.com> | 2006-05-17 14:51:31 +0400 |
commit | 1663a14d56b8b4ad9b43b6a00d3efcb0adf4b149 (patch) | |
tree | 9310a891d3dd6fec6147f50c7acca7119d801d4d /libgc/pthread_stop_world.c | |
parent | 20f9256680027576ec788c8906c746c14a253a83 (diff) |
2006-05-17 Martin Baulig <martin@ximian.com>
Fix a weird race condition which prevented XSP from working inside
the debugger - see doc/debugger-issues.txt for details.
* include/gc.h: Moved the "libgc-mono-debugger.h" #include down
after the gc_pthread_redirects.h one.
* include/libgc-mono-debugger.h
(GCThreadFunctions): Added `thread_created' and `thread_exited'.
(GC_mono_debugger_add_all_threads): New function prototype.
* pthread_stop_world.c (gc_thread_vtable): Allow the vtable and
any function in it be NULL; use NULL as the default vtable.
(GC_mono_debugger_add_all_threads): New public function.
* pthread_support.c (GC_new_thread): Use calloc() instead of
GC_INTERNAL_MALLOC() to allocate the `GC_thread' structure.
(GC_delete_thread): Call `gc_thread_vtable->thread_exited()'.
(GC_thr_init): Call `gc_thread_vtable->thread_created()'.
(GC_start_routine_head): Likewise; use calloc() instead of
GC_INTERNAL_MALLOC() to allocate the `start_info'.
svn path=/trunk/mono/; revision=60766
Diffstat (limited to 'libgc/pthread_stop_world.c')
-rw-r--r-- | libgc/pthread_stop_world.c | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/libgc/pthread_stop_world.c b/libgc/pthread_stop_world.c index 68f1dce4306..6291d47fb2d 100644 --- a/libgc/pthread_stop_world.c +++ b/libgc/pthread_stop_world.c @@ -294,7 +294,7 @@ void GC_restart_handler(int sig) /* world is stopped. Should not fail if it isn't. */ void GC_push_all_stacks() { - gc_thread_vtable->push_all_stacks(); + pthread_push_all_stacks(); } /* There seems to be a very rare thread stopping problem. To help us */ @@ -353,7 +353,7 @@ static void pthread_stop_world() #if DEBUG_THREADS GC_printf1("Stopping the world from 0x%lx\n", pthread_self()); #endif - + n_live_threads = GC_suspend_all(); if (GC_retry_signals) { @@ -412,7 +412,10 @@ void GC_stop_world() /* We should have previously waited for it to become zero. */ # endif /* PARALLEL_MARK */ ++GC_stop_count; - gc_thread_vtable->stop_world (); + if (gc_thread_vtable && gc_thread_vtable->stop_world) + gc_thread_vtable->stop_world (); + else + pthread_stop_world (); # ifdef PARALLEL_MARK GC_release_mark_lock(); # endif @@ -478,7 +481,10 @@ static void pthread_start_world() void GC_start_world() { - gc_thread_vtable->start_world(); + if (gc_thread_vtable && gc_thread_vtable->start_world) + gc_thread_vtable->start_world(); + else + pthread_start_world (); } static void pthread_stop_init() { @@ -527,20 +533,28 @@ static void pthread_stop_init() { /* We hold the allocation lock. */ void GC_stop_init() { - gc_thread_vtable->initialize (); + if (gc_thread_vtable && gc_thread_vtable->initialize) + gc_thread_vtable->initialize (); + else + pthread_stop_init (); +} + +GCThreadFunctions *gc_thread_vtable = NULL; + +void +GC_mono_debugger_add_all_threads (void) +{ + GC_thread p; + int i; + + if (gc_thread_vtable && gc_thread_vtable->thread_created) { + for (i = 0; i < THREAD_TABLE_SZ; i++) { + for (p = GC_threads[i]; p != 0; p = p -> next) { + gc_thread_vtable->thread_created (p->id, &p->stop_info.stack_ptr); + } + } + } } -/* - * This is used by the Mono Debugger to stop/start the world. - */ -GCThreadFunctions pthread_thread_vtable = { - pthread_stop_init, - - pthread_stop_world, - pthread_push_all_stacks, - pthread_start_world -}; - -GCThreadFunctions *gc_thread_vtable = &pthread_thread_vtable; #endif |