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 long wait(notifiable_t **object); 69 70 virtual long wait_object(notifiable_t *object); 71 72 /* Helper methods. */ 73 74 virtual void notify(notifiable_t *object); 75 76 virtual void release(notifiable_t *object); 77 }; 78 79 80 81 /* Collection types. */ 82 83 typedef std::set<ObjectNotifier *> ObjectNotifiers; 84 85 86 87 /* Object-specific notifier resource. */ 88 89 class NotifierResource : public Notifier, public Resource 90 { 91 protected: 92 /* Locking for the resource. */ 93 94 std::mutex _lock; 95 std::condition_variable _condition; 96 97 /* Notifiers and the monitored object. */ 98 99 ObjectNotifiers _notifiers; 100 notifiable_t *_object; 101 102 /* Pending notification status. */ 103 104 bool _pending = false; 105 106 /* Utility methods. */ 107 108 virtual void _notify(); 109 110 virtual void _release(); 111 112 public: 113 l4_cap_idx_t endpoint = L4_INVALID_CAP; 114 115 explicit NotifierResource(notifiable_t *object) 116 : _object(object) 117 { 118 } 119 120 virtual ~NotifierResource(); 121 122 /* Resource methods. */ 123 124 virtual void close(); 125 126 /* Server details. */ 127 128 virtual ipc_server_default_config_type config(); 129 130 virtual void *interface() 131 { return static_cast<Notifier *>(this); } 132 133 /* Notifier methods. */ 134 135 virtual long notify(notify_flags_t flags, notify_values_t values); 136 137 /* Local operations. */ 138 139 virtual long add(ObjectNotifier *notifier, notify_flags_t flags); 140 141 virtual long remove(ObjectNotifier *notifier); 142 143 virtual long wait(); 144 }; 145 146 147 148 /* Helper functions. */ 149 150 ObjectNotifier *notifier_get_task_notifier(); 151 152 ObjectNotifier *notifier_get_local_notifier(); 153 154 // vim: tabstop=4 expandtab shiftwidth=4