1.1 --- a/libnotifier/include/notifier/notifier.h Wed Mar 29 00:32:20 2023 +0200
1.2 +++ b/libnotifier/include/notifier/notifier.h Mon Apr 03 00:35:34 2023 +0200
1.3 @@ -23,8 +23,8 @@
1.4
1.5 #include <condition_variable>
1.6 #include <list>
1.7 -#include <map>
1.8 #include <mutex>
1.9 +#include <set>
1.10 #include <vector>
1.11
1.12 #include <resource/resource.h>
1.13 @@ -34,36 +34,10 @@
1.14
1.15
1.16
1.17 -/* Object-specific notification details. */
1.18 -
1.19 -class ObjectNotificationState
1.20 -{
1.21 -public:
1.22 - /* Synchronisation primitives for state access and notification. */
1.23 -
1.24 - std::mutex lock;
1.25 - std::condition_variable condition;
1.26 -
1.27 - /* Pending notifications for monitored objects. */
1.28 -
1.29 - notify_flags_t pending_notifications = 0;
1.30 - notify_values_t pending_values = NOTIFY_VALUES_NULL;
1.31 -
1.32 - /* Endpoints associated with monitored objects. */
1.33 -
1.34 - l4_cap_idx_t endpoint = L4_INVALID_CAP;
1.35 -
1.36 - bool is_null() { return l4_is_invalid_cap(endpoint); }
1.37 -};
1.38 -
1.39 -
1.40 -
1.41 /* Collection types. */
1.42
1.43 -typedef std::map<notifiable_t *, ObjectNotificationState> ObjectNotificationStates;
1.44 -typedef std::map<notifiable_t *, std::mutex> ObjectStateLocks;
1.45 -
1.46 -typedef std::vector<ipc_server_config_type *> ServerConfigs;
1.47 +typedef std::list<notifiable_t *> NotifiableObjectQueue;
1.48 +typedef std::set<notifiable_t *> NotifiableObjects;
1.49
1.50
1.51
1.52 @@ -72,102 +46,41 @@
1.53 class ObjectNotifier
1.54 {
1.55 protected:
1.56 - /* General state access locking. */
1.57 -
1.58 - std::mutex _state_lock;
1.59 -
1.60 - /* Object-specific state locking. */
1.61 + /* Locking for the affected queue and monitored object registry. */
1.62
1.63 - ObjectStateLocks _object_locks;
1.64 -
1.65 - /* Notification state. */
1.66 -
1.67 - ObjectNotificationStates _state;
1.68 + std::mutex _affected_lock, _monitored_lock;
1.69 + std::condition_variable _condition;
1.70
1.71 - /* Notifier resource details. */
1.72 -
1.73 - ServerConfigs _configs;
1.74 - bool _started = false;
1.75 - l4_cap_idx_t _irq = L4_INVALID_CAP;
1.76 + /* Objects affected by notifications. */
1.77
1.78 - /* Convenience method to access object state. */
1.79 -
1.80 - virtual ObjectNotificationState &object_state(notifiable_t *object, bool create);
1.81 -
1.82 - /* Helper methods. */
1.83 -
1.84 - virtual bool _transfer(ObjectNotificationState &state, notifiable_t *object);
1.85 + NotifiableObjectQueue _queued;
1.86 + NotifiableObjects _affected, _monitored;
1.87
1.88 public:
1.89 virtual ~ObjectNotifier();
1.90
1.91 /* Local operations. */
1.92
1.93 - virtual long start();
1.94 -
1.95 - virtual void stop();
1.96 -
1.97 virtual long subscribe(notifiable_t *object, notify_flags_t flags);
1.98
1.99 virtual long unsubscribe(notifiable_t *object);
1.100
1.101 - virtual long remove_endpoint(notifiable_t *object, l4_cap_idx_t endpoint);
1.102 + virtual long wait(notifiable_t **object);
1.103 +
1.104 + virtual long wait_object(notifiable_t *object);
1.105
1.106 /* Helper methods. */
1.107
1.108 - virtual void notify(notifiable_t *object, notify_flags_t flags,
1.109 - notify_values_t values) = 0;
1.110 + virtual void notify(notifiable_t *object);
1.111 +
1.112 + virtual void release(notifiable_t *object);
1.113 };
1.114
1.115
1.116
1.117 -/* An object monitoring notifications for a collection of different objects. */
1.118 -
1.119 -class GeneralObjectNotifier : public ObjectNotifier
1.120 -{
1.121 -protected:
1.122 - /* Locking to protect pending notification members and to coordinate access
1.123 - to notifications. */
1.124 -
1.125 - std::mutex _general_lock;
1.126 -
1.127 - /* General lock synchronisation. */
1.128 -
1.129 - std::condition_variable _general_condition;
1.130 -
1.131 - /* Objects affected by notifications. */
1.132 -
1.133 - std::list<notifiable_t *> _affected;
1.134 -
1.135 - /* Helper methods. */
1.136 -
1.137 - virtual bool _retrieve(notifiable_t **object);
1.138 -
1.139 - virtual bool _retrieve_for_object(notifiable_t *object);
1.140 +/* Collection types. */
1.141
1.142 -public:
1.143 - virtual long wait(notifiable_t **object);
1.144 -
1.145 - /* Helper methods. */
1.146 -
1.147 - virtual void notify(notifiable_t *object, notify_flags_t flags,
1.148 - notify_values_t values);
1.149 -};
1.150 -
1.151 -
1.152 -
1.153 -/* An object monitoring notifications for specific objects. */
1.154 -
1.155 -class SpecificObjectNotifier : public ObjectNotifier
1.156 -{
1.157 -public:
1.158 - virtual long wait_object(notifiable_t *object);
1.159 -
1.160 - /* Helper methods. */
1.161 -
1.162 - virtual void notify(notifiable_t *object, notify_flags_t flags,
1.163 - notify_values_t values);
1.164 -};
1.165 +typedef std::set<ObjectNotifier *> ObjectNotifiers;
1.166
1.167
1.168
1.169 @@ -176,19 +89,39 @@
1.170 class NotifierResource : public Notifier, public Resource
1.171 {
1.172 protected:
1.173 - ObjectNotifier *_notifier;
1.174 + /* Locking for the resource. */
1.175 +
1.176 + std::mutex _lock;
1.177 + std::condition_variable _condition;
1.178 +
1.179 + /* Notifiers and the monitored object. */
1.180 +
1.181 + ObjectNotifiers _notifiers;
1.182 notifiable_t *_object;
1.183
1.184 + /* Pending notification status. */
1.185 +
1.186 + bool _pending = false;
1.187 +
1.188 + /* Utility methods. */
1.189 +
1.190 + virtual void _notify();
1.191 +
1.192 + virtual void _release();
1.193 +
1.194 public:
1.195 - explicit NotifierResource(ObjectNotifier *notifier, notifiable_t *object)
1.196 - : _notifier(notifier), _object(object)
1.197 + l4_cap_idx_t endpoint = L4_INVALID_CAP;
1.198 +
1.199 + explicit NotifierResource(notifiable_t *object)
1.200 + : _object(object)
1.201 {
1.202 }
1.203
1.204 - explicit NotifierResource()
1.205 - : _notifier(NULL), _object(NULL)
1.206 - {
1.207 - }
1.208 + virtual ~NotifierResource();
1.209 +
1.210 + /* Resource methods. */
1.211 +
1.212 + virtual void close();
1.213
1.214 /* Server details. */
1.215
1.216 @@ -200,14 +133,22 @@
1.217 /* Notifier methods. */
1.218
1.219 virtual long notify(notify_flags_t flags, notify_values_t values);
1.220 +
1.221 + /* Local operations. */
1.222 +
1.223 + virtual long add(ObjectNotifier *notifier, notify_flags_t flags);
1.224 +
1.225 + virtual long remove(ObjectNotifier *notifier);
1.226 +
1.227 + virtual long wait();
1.228 };
1.229
1.230
1.231
1.232 /* Helper functions. */
1.233
1.234 -SpecificObjectNotifier *notifier_get_task_notifier();
1.235 +ObjectNotifier *notifier_get_task_notifier();
1.236
1.237 -GeneralObjectNotifier *notifier_get_local_notifier();
1.238 +ObjectNotifier *notifier_get_local_notifier();
1.239
1.240 // vim: tabstop=4 expandtab shiftwidth=4