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;
 }
 

Reply via email to