comparison 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
comparison
equal deleted inserted replaced
124:ad5ab8e61c2b 125:1c1f28c124c9
16 STAILQ_INIT(subject->observers); 16 STAILQ_INIT(subject->observers);
17 17
18 return subject; 18 return subject;
19 } 19 }
20 20
21 /*!
22 * \todo Keep ob_factory following subject objects.
23 */
21 void subject_free(ob_factory_t *factory, subject_t *subject) { 24 void subject_free(ob_factory_t *factory, subject_t *subject) {
22 observer_t *observer; 25 observer_t *observer;
23 26
27 if(subject->flags & SUBF_BUSY) {
28 /* Postpond the request until busy status been stoped.
29 * SUBF_BUSY means in subject_notify().
30 */
31 subject->flags |= SUBF_FREE;
32 return;
33 }
34
24 while((observer = STAILQ_HEAD(subject->observers))) { 35 while((observer = STAILQ_HEAD(subject->observers))) {
25 STAILQ_REMOVE(subject->observers, observer_t, next, observer); 36 STAILQ_REMOVE(subject->observers, observer_t, next, observer);
26 factory->observer_free(factory, observer); 37 factory->observer_free(factory, observer);
27 } 38 }
28 factory->subject_free(factory, subject); 39 factory->subject_free(factory, subject);
29 } 40 }
30 41
31 42
32 void subject_notify(ob_factory_t *factory, subject_t *subject, event_t *evt) { 43 void subject_notify(ob_factory_t *factory, subject_t *subject, event_t *evt) {
33 observer_t *observer; 44 observer_t *observer;
45
46 /*!
47 * \note What is happend when the subject is freed by observer?
48 * Postponding the request of free until notification
49 * been finished. (\ref SUBF_BUSY / \ref SUBF_FREE)
50 */
51 subject->flags |= SUBF_BUSY;
34 52
35 evt->tgt = subject; 53 evt->tgt = subject;
36 while(subject) { 54 while(subject) {
37 evt->cur_tgt = subject->obj; 55 evt->cur_tgt = subject->obj;
38 for(observer = STAILQ_HEAD(subject->observers); 56 for(observer = STAILQ_HEAD(subject->observers);
44 if(subject->flags & SUBF_STOP_PROPAGATE) 62 if(subject->flags & SUBF_STOP_PROPAGATE)
45 break; 63 break;
46 64
47 subject = factory->get_parent_subject(factory, subject); 65 subject = factory->get_parent_subject(factory, subject);
48 } 66 }
67
68 subject->flags &= ~SUBF_BUSY;
69 if(subject->flags & SUBF_FREE)
70 subject_free(factory, subject);
49 } 71 }
50 72
51 observer_t *subject_add_observer(ob_factory_t *factory, 73 observer_t *subject_add_observer(ob_factory_t *factory,
52 subject_t *subject, 74 subject_t *subject,
53 evt_handler hdr, void *arg) { 75 evt_handler hdr, void *arg) {