Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Baulig <martin@novell.com>2006-05-17 14:51:31 +0400
committerMartin Baulig <martin@novell.com>2006-05-17 14:51:31 +0400
commit1663a14d56b8b4ad9b43b6a00d3efcb0adf4b149 (patch)
tree9310a891d3dd6fec6147f50c7acca7119d801d4d /libgc/pthread_stop_world.c
parent20f9256680027576ec788c8906c746c14a253a83 (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.c48
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