xref: /haiku/headers/private/kernel/Notifications.h (revision e221c09e508ffc3c62738140c9b6fc4fa211662a)
1 /*
2  * Copyright 2007, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
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
11 
12 
13 #include <SupportDefs.h>
14 
15 #include <lock.h>
16 #include <messaging.h>
17 #include <util/khash.h>
18 
19 
20 #ifdef __cplusplus
21 
22 #include <Referenceable.h>
23 
24 #include <util/AutoLock.h>
25 #include <util/KMessage.h>
26 #include <util/OpenHashTable.h>
27 
28 
29 class NotificationService;
30 
31 class NotificationListener {
32 	public:
33 		virtual ~NotificationListener();
34 
35 		virtual void EventOccured(NotificationService& service,
36 			const KMessage* event);
37 		virtual void AllListenersNotified(NotificationService& service);
38 
39 		virtual bool operator==(const NotificationListener& other) const;
40 
41 		bool operator!=(const NotificationListener& other) const
42 			{ return !(*this == other); }
43 };
44 
45 class UserMessagingMessageSender {
46 	public:
47 		UserMessagingMessageSender();
48 
49 		void SendMessage(const KMessage* message, port_id port, int32 token);
50 		void FlushMessage();
51 
52 	private:
53 		enum {
54 			MAX_MESSAGING_TARGET_COUNT	= 16,
55 		};
56 
57 		const KMessage*		fMessage;
58 		messaging_target	fTargets[MAX_MESSAGING_TARGET_COUNT];
59 		int32				fTargetCount;
60 };
61 
62 class UserMessagingListener : public NotificationListener {
63 	public:
64 		UserMessagingListener(UserMessagingMessageSender& sender, port_id port,
65 			int32 token);
66 		virtual ~UserMessagingListener();
67 
68 		virtual void EventOccured(NotificationService& service,
69 			const KMessage* event);
70 		virtual void AllListenersNotified(NotificationService& service);
71 
72 		port_id Port() const	{ return fPort; }
73 		int32 Token() const		{ return fToken; }
74 
75 	private:
76 		UserMessagingMessageSender&	fSender;
77 		port_id						fPort;
78 		int32						fToken;
79 };
80 
81 class NotificationService : public Referenceable {
82 	public:
83 		virtual ~NotificationService();
84 
85 		virtual status_t AddListener(const KMessage* eventSpecifier,
86 			NotificationListener& listener) = 0;
87 		virtual status_t RemoveListener(const KMessage* eventSpecifier,
88 			NotificationListener& listener) = 0;
89 		virtual status_t UpdateListener(const KMessage* eventSpecifier,
90 			NotificationListener& listener) = 0;
91 
92 		virtual const char* Name() = 0;
93 		HashTableLink<NotificationService>& Link() { return fLink; }
94 
95 	private:
96 		HashTableLink<NotificationService> fLink;
97 };
98 
99 class NotificationManager {
100 	public:
101 		static NotificationManager& Manager();
102 		static status_t CreateManager();
103 
104 		status_t RegisterService(NotificationService& service);
105 		void UnregisterService(NotificationService& service);
106 
107 		NotificationService* GetService(const char* name);
108 		void PutService(NotificationService* service);
109 
110 		status_t AddListener(const char* service, uint32 eventMask,
111 			NotificationListener& listener);
112 		status_t AddListener(const char* service,
113 			const KMessage* eventSpecifier, NotificationListener& listener);
114 
115 		status_t UpdateListener(const char* service,
116 			uint32 eventMask, NotificationListener& listener);
117 		status_t UpdateListener(const char* service,
118 			const KMessage* eventSpecifier, NotificationListener& listener);
119 
120 		status_t RemoveListener(const char* service,
121 			const KMessage* eventSpecifier, NotificationListener& listener);
122 
123 	private:
124 		NotificationManager();
125 		~NotificationManager();
126 
127 		status_t _Init();
128 		NotificationService* _ServiceFor(const char* name);
129 
130 		struct HashDefinition {
131 			typedef const char* KeyType;
132 			typedef	NotificationService ValueType;
133 
134 			size_t HashKey(const char* key) const
135 				{ return hash_hash_string(key); }
136 			size_t Hash(NotificationService *service) const
137 				{ return hash_hash_string(service->Name()); }
138 			bool Compare(const char* key, NotificationService* service) const
139 				{ return !strcmp(key, service->Name()); }
140 			HashTableLink<NotificationService>* GetLink(
141 					NotificationService* service) const
142 				{ return &service->Link(); }
143 		};
144 
145 		static NotificationManager sManager;
146 
147 		mutex fLock;
148 		typedef OpenHashTable<HashDefinition> ServiceHash;
149 		ServiceHash	fServiceHash;
150 };
151 
152 extern "C" {
153 
154 #endif	// __cplusplus
155 
156 void notifications_init(void);
157 
158 #ifdef __cplusplus
159 }
160 #endif	// __cplusplus
161 
162 #endif	// _KERNEL_NOTIFICATIONS_H
163