2 * Copyright 2007-2009, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Axel Dörfler, axeld@pinc-software.de
7 * Ingo Weinhold, bonefish@cs.tu-berlin.de
9 #ifndef _KERNEL_NOTIFICATIONS_H
10 #define _KERNEL_NOTIFICATIONS_H
13 #include <SupportDefs.h>
16 #include <messaging.h>
17 #include <util/StringHash.h>
22 #include <Referenceable.h>
24 #include <util/AutoLock.h>
25 #include <util/KMessage.h>
26 #include <util/OpenHashTable.h>
29 class NotificationService
;
31 class NotificationListener
{
33 virtual ~NotificationListener();
35 virtual void EventOccurred(NotificationService
& service
,
36 const KMessage
* event
);
37 virtual void AllListenersNotified(
38 NotificationService
& service
);
40 virtual bool operator==(
41 const NotificationListener
& other
) const;
44 const NotificationListener
& other
) const
45 { return !(*this == other
); }
48 class UserMessagingMessageSender
{
50 UserMessagingMessageSender();
52 void SendMessage(const KMessage
* message
,
53 port_id port
, int32 token
);
58 MAX_MESSAGING_TARGET_COUNT
= 16,
61 const KMessage
* fMessage
;
62 messaging_target fTargets
[MAX_MESSAGING_TARGET_COUNT
];
66 class UserMessagingListener
: public NotificationListener
{
68 UserMessagingListener(
69 UserMessagingMessageSender
& sender
,
70 port_id port
, int32 token
);
71 virtual ~UserMessagingListener();
73 virtual void EventOccurred(NotificationService
& service
,
74 const KMessage
* event
);
75 virtual void AllListenersNotified(
76 NotificationService
& service
);
78 port_id
Port() const { return fPort
; }
79 int32
Token() const { return fToken
; }
82 const NotificationListener
& _other
) const;
85 UserMessagingMessageSender
& fSender
;
91 UserMessagingListener::operator==(const NotificationListener
& _other
) const
93 const UserMessagingListener
* other
94 = dynamic_cast<const UserMessagingListener
*>(&_other
);
95 return other
!= NULL
&& other
->Port() == Port()
96 && other
->Token() == Token();
99 class NotificationService
: public BReferenceable
{
101 virtual ~NotificationService();
103 virtual status_t
AddListener(const KMessage
* eventSpecifier
,
104 NotificationListener
& listener
) = 0;
105 virtual status_t
RemoveListener(const KMessage
* eventSpecifier
,
106 NotificationListener
& listener
) = 0;
107 virtual status_t
UpdateListener(const KMessage
* eventSpecifier
,
108 NotificationListener
& listener
) = 0;
110 virtual const char* Name() = 0;
111 NotificationService
*&
112 Link() { return fLink
; }
115 NotificationService
* fLink
;
118 struct default_listener
: public DoublyLinkedListLinkImpl
<default_listener
> {
123 NotificationListener
* listener
;
126 typedef DoublyLinkedList
<default_listener
> DefaultListenerList
;
129 class DefaultNotificationService
: public NotificationService
{
131 DefaultNotificationService(const char* name
);
132 virtual ~DefaultNotificationService();
135 { return recursive_lock_lock(&fLock
)
138 { recursive_lock_unlock(&fLock
); }
140 inline void Notify(const KMessage
& event
, uint32 eventMask
);
141 void NotifyLocked(const KMessage
& event
,
144 inline bool HasListeners() const
145 { return !fListeners
.IsEmpty(); }
146 virtual status_t
AddListener(const KMessage
* eventSpecifier
,
147 NotificationListener
& listener
);
148 virtual status_t
UpdateListener(const KMessage
* eventSpecifier
,
149 NotificationListener
& listener
);
150 virtual status_t
RemoveListener(const KMessage
* eventSpecifier
,
151 NotificationListener
& listener
);
153 virtual const char* Name() { return fName
; }
159 virtual status_t
ToEventMask(const KMessage
& eventSpecifier
,
161 virtual void FirstAdded();
162 virtual void LastRemoved();
164 recursive_lock fLock
;
165 DefaultListenerList fListeners
;
169 class DefaultUserNotificationService
: public DefaultNotificationService
,
170 NotificationListener
{
172 DefaultUserNotificationService(
174 virtual ~DefaultUserNotificationService();
176 virtual status_t
AddListener(const KMessage
* eventSpecifier
,
177 NotificationListener
& listener
);
178 virtual status_t
UpdateListener(const KMessage
* eventSpecifier
,
179 NotificationListener
& listener
);
180 virtual status_t
RemoveListener(const KMessage
* eventSpecifier
,
181 NotificationListener
& listener
);
183 status_t
RemoveUserListeners(port_id port
, uint32 token
);
184 status_t
UpdateUserListener(uint32 eventMask
,
185 port_id port
, uint32 token
);
188 virtual void EventOccurred(NotificationService
& service
,
189 const KMessage
* event
);
190 virtual void AllListenersNotified(
191 NotificationService
& service
);
192 status_t
_AddListener(uint32 eventMask
,
193 NotificationListener
& listener
);
195 UserMessagingMessageSender fSender
;
198 class NotificationManager
{
200 static NotificationManager
& Manager();
201 static status_t
CreateManager();
203 status_t
RegisterService(NotificationService
& service
);
204 void UnregisterService(
205 NotificationService
& service
);
207 status_t
AddListener(const char* service
,
209 NotificationListener
& listener
);
210 status_t
AddListener(const char* service
,
211 const KMessage
* eventSpecifier
,
212 NotificationListener
& listener
);
214 status_t
UpdateListener(const char* service
,
216 NotificationListener
& listener
);
217 status_t
UpdateListener(const char* service
,
218 const KMessage
* eventSpecifier
,
219 NotificationListener
& listener
);
221 status_t
RemoveListener(const char* service
,
222 const KMessage
* eventSpecifier
,
223 NotificationListener
& listener
);
226 NotificationManager();
227 ~NotificationManager();
230 NotificationService
* _ServiceFor(const char* name
);
232 struct HashDefinition
{
233 typedef const char* KeyType
;
234 typedef NotificationService ValueType
;
236 size_t HashKey(const char* key
) const
237 { return hash_hash_string(key
); }
238 size_t Hash(NotificationService
*service
) const
239 { return hash_hash_string(service
->Name()); }
240 bool Compare(const char* key
, NotificationService
* service
) const
241 { return !strcmp(key
, service
->Name()); }
242 NotificationService
*& GetLink(
243 NotificationService
* service
) const
244 { return service
->Link(); }
246 typedef BOpenHashTable
<HashDefinition
> ServiceHash
;
248 static NotificationManager sManager
;
251 ServiceHash fServiceHash
;
256 DefaultNotificationService::Notify(const KMessage
& event
, uint32 eventMask
)
258 RecursiveLocker
_(fLock
);
259 NotifyLocked(event
, eventMask
);
265 #endif // __cplusplus
267 void notifications_init(void);
271 #endif // __cplusplus
273 #endif // _KERNEL_NOTIFICATIONS_H