1 /* 2 * Generic object event notification support. 3 * 4 * Copyright (C) 2021, 2022, 2023 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #pragma once 23 24 #include <condition_variable> 25 #include <list> 26 #include <mutex> 27 #include <set> 28 #include <vector> 29 30 #include <resource/resource.h> 31 #include <systypes/base.h> 32 33 #include "notifier_interface.h" 34 35 36 37 /* Collection types. */ 38 39 typedef std::list<notifiable_t *> NotifiableObjectQueue; 40 typedef std::set<notifiable_t *> NotifiableObjects; 41 42 43 44 /* An object for monitoring object event notifications. */ 45 46 class ObjectNotifier 47 { 48 protected: 49 /* Locking for the affected queue and monitored object registry. */ 50 51 std::mutex _affected_lock, _monitored_lock; 52 std::condition_variable _condition; 53 54 /* Objects affected by notifications. */ 55 56 NotifiableObjectQueue _queued; 57 NotifiableObjects _affected, _monitored; 58 59 public: 60 virtual ~ObjectNotifier(); 61 62 /* Local operations. */ 63 64 virtual long subscribe(notifiable_t *object, notify_flags_t flags); 65 66 virtual long unsubscribe(notifiable_t *object); 67 68 virtual void update(notifiable_t *object); 69 70 virtual long wait(notifiable_t **object); 71 72 virtual long wait_object(notifiable_t *object); 73 74 /* Helper methods. */ 75 76 virtual void notify(notifiable_t *object); 77 78 virtual void release(notifiable_t *object); 79 }; 80 81 82 83 /* Collection types. */ 84 85 typedef std::set<ObjectNotifier *> ObjectNotifiers; 86 87 88 89 /* Object-specific notifier resource. */ 90 91 class NotifierResource : public Notifier, public Resource 92 { 93 protected: 94 /* Locking for the resource. */ 95 96 std::mutex _lock; 97 std::condition_variable _condition; 98 99 /* Notifiers and the monitored object. */ 100 101 ObjectNotifiers _notifiers; 102 notifiable_t *_object; 103 104 /* Utility methods. */ 105 106 virtual void _notify(); 107 108 virtual void _release(); 109 110 public: 111 l4_cap_idx_t endpoint = L4_INVALID_CAP; 112 113 explicit NotifierResource(notifiable_t *object) 114 : _object(object) 115 { 116 } 117 118 virtual ~NotifierResource(); 119 120 /* Resource methods. */ 121 122 virtual void close(); 123 124 /* Server details. */ 125 126 virtual ipc_server_default_config_type config(); 127 128 virtual void *interface() 129 { return static_cast<Notifier *>(this); } 130 131 /* Notifier methods. */ 132 133 virtual long notify(notify_flags_t flags, notify_values_t values); 134 135 /* Local operations. */ 136 137 virtual long add(ObjectNotifier *notifier, notify_flags_t flags); 138 139 virtual long remove(ObjectNotifier *notifier); 140 }; 141 142 143 144 /* Helper functions. */ 145 146 ObjectNotifier *notifier_get_task_notifier(); 147 148 ObjectNotifier *notifier_get_local_notifier(); 149 150 // vim: tabstop=4 expandtab shiftwidth=4