At the time the main interpreter(one which has no parent) exits, there
could remain some other interpreters being run by detached threads as
in t/pmc/threads_4.pasm. To execute bytecode successfully an
interpreter needs that things like PIO, class vtables, event loop,
class_count_mutex, interpreter_array_mutex, and maybe others are kept
untouched untill the very last interpreter is done. Now
Parrot_really_destroy when is called by the main interpreter shuts
down PIO, kills the event loop, and destroys interpreter_array_mutex
no matter how many interpreters are still active.
The patch provided moves destroying of interpreter_array_mutex into
the sort of commented out with PARROT_DESTROY_FLAG for the main
interpreter part of Parrot_really_destroy and lets a detached thread
to feel free to lock interpreter_array_mutex. With that fix applied,
t/pmc/threads_4.pasm should be ok. The better patch would require
knowledge of a) how many interpreters being alive and b) who heck is
the fery first interpreter, and would do checks like
if ( the_very_last_interpreter )
{
PIO_internal_shutdown( the_very_first_interpreter );
rather than
if ( !interpreter->parent_interpreter )
{
PIO_internal_shutdown( interpreter );
a) interpreter_array traps how many threads are running, and that's
not the same as how many interpreters are running.
b) though the very first interpretere could be derived from following
the parent_interpreter pointer like
interp->parent_interpreter->parent_interpreter, the global variable
would do the job better and woudn't require serializing access to it.
--- parrot/src/events.c Wed Jun 1 13:35:20 2005
+++ parrot-devel/src/events.c Wed Jun 1 13:32:53 2005
@@ -237,10 +237,6 @@
if (event_queue)
PANIC("event queue already exists - missing parent_interp?");
/*
- * we need a global mutex to protect the interpreter array
- */
- MUTEX_INIT(interpreter_array_mutex);
- /*
* create event queue
*/
event_queue = queue_init(TASK_PRIO);
--- parrot/src/inter_create.c Wed Jun 1 13:35:21 2005
+++ parrot-devel/src/inter_create.c Wed Jun 1 13:34:03 2005
@@ -114,6 +114,10 @@
else {
SET_NULL(interpreter->parent_interpreter);
SET_NULL(interpreter->lo_var_ptr);
+ /*
+ * we need a global mutex to protect the interpreter array
+ */
+ MUTEX_INIT(interpreter_array_mutex);
MUTEX_INIT(class_count_mutex);
}
interpreter->resume_flag = RESUME_INITIAL;
@@ -408,6 +412,7 @@
mem_sys_free(interpreter->evc_func_table);
/* strings, chartype, encodings */
if (!interpreter->parent_interpreter) {
+ MUTEX_DESTROY(interpreter_array_mutex);
MUTEX_DESTROY(class_count_mutex);
string_deinit(interpreter);
/*
--- parrot/src/thread.c Wed Jun 1 13:35:21 2005
+++ parrot-devel/src/thread.c Wed Jun 1 13:34:36 2005
@@ -432,7 +432,6 @@
}
}
UNLOCK(interpreter_array_mutex);
- MUTEX_DESTROY(interpreter_array_mutex);
return;
}