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