976596008bb9bc4ee79639c36bfe2497105442fa
[bertos.git] / mware / observer.c
1 /**
2  * \file
3  * <!--
4  * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
5  * This file is part of DevLib - See README.devlib for information.
6  * -->
7  *
8  * \brief Simple notifier for the observer/subject pattern (implementation)
9  *
10  * \version $Id$
11  * \author Bernardo Innocenti <bernie@develer.com>
12  */
13
14 #include "observer.h"
15 #include <cfg/cpu.h>  // IRQ_DISABLE/IRQ_ENABLE
16
17
18 void observer_SetEvent(Observer *observer, void (*event)(int event_id, void *param))
19 {
20         observer->event = event;
21 }
22
23 void observer_InitSubject(Subject *subject)
24 {
25         LIST_INIT(&subject->observers);
26 }
27
28 void observer_Subscribe(Subject *subject, Observer *observer)
29 {
30         ATOMIC(ADDHEAD(&subject->observers, &observer->link));
31 }
32
33 void observer_Unsubscribe(UNUSED_ARG(Subject *,subject), Observer *observer)
34 {
35         ATOMIC(REMOVE(&observer->link));
36 }
37
38 void observer_notify(Subject *subject, int event_id, void *param)
39 {
40         Observer *observer;
41         cpuflags_t irqstate;
42         IRQ_SAVE_DISABLE(irqstate);
43
44         /*
45          * Run over list with protection against other
46          * threads, but re-enable irqs in callbacks.
47          */
48         FOREACH_NODE(observer, &subject->observers)
49         {
50                 IRQ_RESTORE(irqstate);
51                 observer->event(event_id, param);
52                 IRQ_SAVE_DISABLE(irqstate);
53         }
54
55         IRQ_RESTORE(irqstate);
56 }