diff src/observer.c @ 125:1c1f28c124c9

Postponding free request when a subject is in subject_notify
author Thinker K.F. Li <thinker@branda.to>
date Tue, 16 Sep 2008 15:31:49 +0800
parents a6763f080da5
children 55f2c6402c81
line wrap: on
line diff
--- a/src/observer.c	Tue Sep 16 14:55:24 2008 +0800
+++ b/src/observer.c	Tue Sep 16 15:31:49 2008 +0800
@@ -18,9 +18,20 @@
     return subject;
 }
 
+/*!
+ * \todo Keep ob_factory following subject objects.
+ */
 void subject_free(ob_factory_t *factory, subject_t *subject) {
     observer_t *observer;
 
+    if(subject->flags & SUBF_BUSY) {
+	/* Postpond the request until busy status been stoped.
+	 * SUBF_BUSY means in subject_notify().
+	 */
+	subject->flags |= SUBF_FREE;
+	return;
+    }
+	
     while((observer = STAILQ_HEAD(subject->observers))) {
 	STAILQ_REMOVE(subject->observers, observer_t, next, observer);
 	factory->observer_free(factory, observer);
@@ -32,6 +43,13 @@
 void subject_notify(ob_factory_t *factory, subject_t *subject, event_t *evt) {
     observer_t *observer;
 
+    /*!
+     * \note What is happend when the subject is freed by observer?
+     *		Postponding the request of free until notification
+     *		been finished. (\ref SUBF_BUSY / \ref SUBF_FREE)
+     */
+    subject->flags |= SUBF_BUSY;
+
     evt->tgt = subject;
     while(subject) {
 	evt->cur_tgt = subject->obj;
@@ -46,6 +64,10 @@
 
 	subject = factory->get_parent_subject(factory, subject);
     }
+
+    subject->flags &= ~SUBF_BUSY;
+    if(subject->flags & SUBF_FREE)
+	subject_free(factory, subject);
 }
 
 observer_t *subject_add_observer(ob_factory_t *factory,