vfs: check userland buffers before reading them.
[haiku.git] / headers / private / kernel / Notifications.h
blobd3ea2fe466d697974cf40df9343acaa742727cbd
1 /*
2 * Copyright 2007-2009, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 * Ingo Weinhold, bonefish@cs.tu-berlin.de
8 */
9 #ifndef _KERNEL_NOTIFICATIONS_H
10 #define _KERNEL_NOTIFICATIONS_H
13 #include <SupportDefs.h>
15 #include <lock.h>
16 #include <messaging.h>
17 #include <util/StringHash.h>
20 #ifdef __cplusplus
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 {
32 public:
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;
43 bool operator!=(
44 const NotificationListener& other) const
45 { return !(*this == other); }
48 class UserMessagingMessageSender {
49 public:
50 UserMessagingMessageSender();
52 void SendMessage(const KMessage* message,
53 port_id port, int32 token);
54 void FlushMessage();
56 private:
57 enum {
58 MAX_MESSAGING_TARGET_COUNT = 16,
61 const KMessage* fMessage;
62 messaging_target fTargets[MAX_MESSAGING_TARGET_COUNT];
63 int32 fTargetCount;
66 class UserMessagingListener : public NotificationListener {
67 public:
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; }
81 bool operator==(
82 const NotificationListener& _other) const;
84 private:
85 UserMessagingMessageSender& fSender;
86 port_id fPort;
87 int32 fToken;
90 inline bool
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 {
100 public:
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; }
114 private:
115 NotificationService* fLink;
118 struct default_listener : public DoublyLinkedListLinkImpl<default_listener> {
119 ~default_listener();
121 uint32 eventMask;
122 team_id team;
123 NotificationListener* listener;
126 typedef DoublyLinkedList<default_listener> DefaultListenerList;
129 class DefaultNotificationService : public NotificationService {
130 public:
131 DefaultNotificationService(const char* name);
132 virtual ~DefaultNotificationService();
134 inline bool Lock()
135 { return recursive_lock_lock(&fLock)
136 == B_OK; }
137 inline void Unlock()
138 { recursive_lock_unlock(&fLock); }
140 inline void Notify(const KMessage& event, uint32 eventMask);
141 void NotifyLocked(const KMessage& event,
142 uint32 eventMask);
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; }
155 status_t Register();
156 void Unregister();
158 protected:
159 virtual status_t ToEventMask(const KMessage& eventSpecifier,
160 uint32& eventMask);
161 virtual void FirstAdded();
162 virtual void LastRemoved();
164 recursive_lock fLock;
165 DefaultListenerList fListeners;
166 const char* fName;
169 class DefaultUserNotificationService : public DefaultNotificationService,
170 NotificationListener {
171 public:
172 DefaultUserNotificationService(
173 const char* name);
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);
187 private:
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 {
199 public:
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,
208 uint32 eventMask,
209 NotificationListener& listener);
210 status_t AddListener(const char* service,
211 const KMessage* eventSpecifier,
212 NotificationListener& listener);
214 status_t UpdateListener(const char* service,
215 uint32 eventMask,
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);
225 private:
226 NotificationManager();
227 ~NotificationManager();
229 status_t _Init();
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;
250 mutex fLock;
251 ServiceHash fServiceHash;
255 void
256 DefaultNotificationService::Notify(const KMessage& event, uint32 eventMask)
258 RecursiveLocker _(fLock);
259 NotifyLocked(event, eventMask);
263 extern "C" {
265 #endif // __cplusplus
267 void notifications_init(void);
269 #ifdef __cplusplus
271 #endif // __cplusplus
273 #endif // _KERNEL_NOTIFICATIONS_H