Unplug broker from the hash on object invalidation.
authorGuo Rui <firemeteor@Adam.(none)>
Mon, 27 Jul 2009 17:14:43 +0000 (28 01:14 +0800)
committerGuo Rui <firemeteor@Adam.(none)>
Mon, 27 Jul 2009 17:14:43 +0000 (28 01:14 +0800)
This solve the problem comming along with reusing the same memory for an
irrelevant object. The new object will correctly have a separate broker now.

src/script.c

index 10203ad..7b91e6d 100644 (file)
@@ -362,6 +362,12 @@ get_obj_broker(void *obj)
       tmp->valid = 1;
       tmp->b_next = NULL;
     }
+  else
+    {
+      /* Assertion */
+      if (!(*bucket)->valid)
+       exit(1);
+    }
   (*bucket)->ref++;
 
   return *bucket;
@@ -383,9 +389,14 @@ void * get_broker_obj(struct broker **pbroker)
 
 void broker_inv_obj(void *obj)
 {
-  struct broker **b = broker_from_obj(obj);
-  if (*b)
+  struct broker *n, **b = broker_from_obj(obj);
+  if (*b) {
     (*b)->valid = 0;
+    /* Unplug the broker from the hash. */
+    n = *b;
+    *b = (*b)->b_next;
+    n->b_next = 0;
+  }
 }
 
 void broker_unref(struct broker **pbroker)
@@ -394,14 +405,19 @@ void broker_unref(struct broker **pbroker)
   *pbroker = NULL;
   if (--broker->ref == 0)
     {
-      struct broker *n, **b = broker_from_obj(broker->obj);
-      if (*b) {
-         n = (*b)->b_next;
-         free(*b);
-         *b = n;
+      if (broker->valid) {
+         struct broker *n, **b = broker_from_obj(broker->obj);
+         if (*b) {
+             n = (*b)->b_next;
+             free(*b);
+             *b = n;
+         } else {
+             /* FIXME:Should not happen! But act better.*/
+             exit(1);
+         }
       } else {
-         /* FIXME:Should not happen! But act better.*/
-         exit(1);
+         /* It had been unplugged before. */
+         free(broker);
       }
     }
 }