From 62da1fe6f8fe22eedfb012a84e02c92b1e2071a6 Mon Sep 17 00:00:00 2001
From: Timothy Strelchun <Timothy.Strelchun@Intel.Com>
Date: Sat, 19 Jun 2010 16:23:56 -0700
Subject: [PATCH 1/6] Fixed global reaction handling to prevent multiple removals

Fixed global reaction handling so that one is not removed 
more than once from the global reaction list in 
fusion_reactor_detach_global and process_globals.  This 
involved keeping the global reaction's attached field 
updated in fusion_reactor_attach_global, 
fusion_reactor_detach_global and process_globals.
---
 lib/fusion/reactor.c |   27 ++++++++++++++++++++++++---
 1 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/lib/fusion/reactor.c b/lib/fusion/reactor.c
index 1022cac..baf50d9 100644
--- a/lib/fusion/reactor.c
+++ b/lib/fusion/reactor.c
@@ -1233,7 +1233,8 @@ fusion_reactor_detach_global( FusionReactor  *reactor,
      if (lock != reactor->globals_lock)
           D_WARN( "using old lock once more" );
 
-     D_ASSUME( reaction->attached );
+     // Do not assume the reaction is attached, because it is possible that it may not be.
+     //D_ASSUME( reaction->attached );
 
      /* Check against multiple detach. */
      if (reaction->attached) {
@@ -1377,6 +1378,10 @@ process_globals( FusionReactor      *reactor,
                /*D_DEBUG_AT( Fusion_Reactor, "    -> removing %p, index %d, ctx %p\n",
                            global, global->index, global->ctx );*/
 
+               // Mark as detached, since the global reaction is being removed 
+               // from the global reaction list.
+               global->attached = false;
+
                direct_list_remove( &reactor->globals, &global->link );
           }
      }
@@ -1672,6 +1677,8 @@ fusion_reactor_attach_global (FusionReactor  *reactor,
 
      reaction->index = index;
      reaction->ctx   = ctx;
+     // Mark the reaction as attached now.
+     reaction->attached = true;
 
      pthread_mutex_lock( &reactor->globals_lock );
 
@@ -1691,7 +1698,15 @@ fusion_reactor_detach_global (FusionReactor  *reactor,
 
      pthread_mutex_lock( &reactor->globals_lock );
 
-     direct_list_remove( &reactor->globals, &reaction->link );
+     // Check to prevent multiple detaches from being performed.
+     if (reaction->attached) {
+          // Mark as detached, since the global reaction is being removed 
+          // from the global reaction list.
+          reaction->attached = false;
+
+          // Remove the reaction from the list.
+          direct_list_remove( &reactor->globals, &reaction->link );
+     }
 
      pthread_mutex_unlock( &reactor->globals_lock );
 
@@ -1858,8 +1873,14 @@ process_globals( FusionReactor      *reactor,
                D_WARN( "global reaction index out of bounds (%d/%d)", global->index, max_index );
           }
           else {
-               if (globals[ global->index ]( msg_data, global->ctx ) == RS_REMOVE)
+               // Remove the reaction if requested.
+               if (globals[ global->index ]( msg_data, global->ctx ) == RS_REMOVE) {
+                    // Mark as detached, since the global reaction is being 
+                    // removed from the global reaction list.
+                    global->attached = false;
+
                     direct_list_remove( &reactor->globals, &global->link );
+               }
           }
      }
 
-- 
1.6.1.9.g97c34

