# HG changeset patch # User Thinker K.F. Li # Date 1221550309 -28800 # Node ID 1c1f28c124c958bfb97087fe581b0f28652acf37 # Parent ad5ab8e61c2b1b39e83302e290ad8e835198394e Postponding free request when a subject is in subject_notify diff -r ad5ab8e61c2b -r 1c1f28c124c9 src/observer.c --- 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, diff -r ad5ab8e61c2b -r 1c1f28c124c9 src/observer.h --- a/src/observer.h Tue Sep 16 14:55:24 2008 +0800 +++ b/src/observer.h Tue Sep 16 15:31:49 2008 +0800 @@ -32,13 +32,15 @@ * \see http://en.wikipedia.org/wiki/Observer_pattern */ struct _subject { - int obj_type; /*!< type of object (a.k.a. OBJT_*). */ - void *obj; /*!< the object this subject for. */ + int obj_type; /*!< \brief type of object (a.k.a. OBJT_*). */ + void *obj; /*!< \brief the object this subject for. */ int flags; STAILQ(observer_t) observers; }; /*! \brief Flag that make a subject to propagate events to parents. */ #define SUBF_STOP_PROPAGATE 0x1 +#define SUBF_BUSY 0x2 /*!< \brief in subject_notify() */ +#define SUBF_FREE 0x4 /*!< \brief in postponding subject_free() */ enum {OBJT_GEO, OBJT_COORD, OBJT_KB, OBJT_PROGM};