1.1 --- a/libfsserver/lib/generic/notification.cc Mon Jul 12 23:18:16 2021 +0200
1.2 +++ b/libfsserver/lib/generic/notification.cc Tue Jul 13 00:26:11 2021 +0200
1.3 @@ -29,39 +29,29 @@
1.4 /* Initialise endpoints and flags for notifications. */
1.5
1.6 NotificationSupport::NotificationSupport(unsigned int endpoints)
1.7 -: _max_endpoints(endpoints)
1.8 +: _min_endpoints(endpoints)
1.9 {
1.10 - _notifiers = new std::set<l4_cap_idx_t>[endpoints];
1.11 - _flags = new notify_flags_t[endpoints];
1.12 - _deferred = new notify_flags_t[endpoints];
1.13 -
1.14 - for (unsigned int endpoint = 0; endpoint < _max_endpoints; endpoint++)
1.15 - {
1.16 - _flags[endpoint] = 0;
1.17 - _deferred[endpoint] = 0;
1.18 - }
1.19 -}
1.20 -
1.21 -NotificationSupport::~NotificationSupport()
1.22 -{
1.23 - delete _notifiers;
1.24 - delete _flags;
1.25 - delete _deferred;
1.26 + _endpoints.resize(_min_endpoints);
1.27 }
1.28
1.29 /* Subscribe to an endpoint's notifications using a notification endpoint. */
1.30
1.31 void NotificationSupport::subscribe(unsigned int endpoint, l4_cap_idx_t notifier, notify_flags_t flags)
1.32 {
1.33 - _notifiers[endpoint].insert(notifier);
1.34 - _flags[endpoint] = flags;
1.35 + if (endpoint >= _endpoints.size())
1.36 + _endpoints.resize(endpoint + 1);
1.37 +
1.38 + NotificationEndpoint &ep = _endpoints[endpoint];
1.39 +
1.40 + ep.notifiers.insert(notifier);
1.41 + ep.flags = flags;
1.42
1.43 /* Send deferred conditions held from before subscription occurred. */
1.44
1.45 - if (_deferred[endpoint])
1.46 + if (ep.deferred)
1.47 {
1.48 - notify(endpoint, _deferred[endpoint]);
1.49 - _deferred[endpoint] = 0;
1.50 + notify(endpoint, ep.deferred);
1.51 + ep.deferred = 0;
1.52 }
1.53 }
1.54
1.55 @@ -69,14 +59,22 @@
1.56
1.57 void NotificationSupport::unsubscribe(unsigned int endpoint, l4_cap_idx_t notifier)
1.58 {
1.59 - std::set<l4_cap_idx_t>::iterator it = _notifiers[endpoint].find(notifier);
1.60 + if (endpoint >= _endpoints.size())
1.61 + return;
1.62
1.63 - if (it != _notifiers[endpoint].end())
1.64 + NotificationEndpoint &ep = _endpoints[endpoint];
1.65 + NotifierSet::iterator it = ep.notifiers.find(notifier);
1.66 +
1.67 + if (it != ep.notifiers.end())
1.68 {
1.69 - _notifiers[endpoint].erase(it);
1.70 - _flags[endpoint] = 0;
1.71 - _deferred[endpoint] = 0;
1.72 + ep.notifiers.erase(it);
1.73 ipc_cap_free_um(notifier);
1.74 +
1.75 + if (ep.notifiers.empty())
1.76 + {
1.77 + ep.flags = 0;
1.78 + ep.deferred = 0;
1.79 + }
1.80 }
1.81 }
1.82
1.83 @@ -84,32 +82,37 @@
1.84
1.85 void NotificationSupport::notify(unsigned int endpoint, notify_flags_t flags)
1.86 {
1.87 + if (endpoint >= _endpoints.size())
1.88 + return;
1.89 +
1.90 + NotificationEndpoint &ep = _endpoints[endpoint];
1.91 +
1.92 /* Notify the endpoint or hold any notification for potential future
1.93 subscription. */
1.94
1.95 - if (!_notifiers[endpoint].empty())
1.96 + if (!ep.notifiers.empty())
1.97 {
1.98 - if (flags & _flags[endpoint])
1.99 + if (flags & ep.flags)
1.100 {
1.101 - std::set<l4_cap_idx_t>::iterator it;
1.102 + NotifierSet::iterator it;
1.103
1.104 - for (it = _notifiers[endpoint].begin(); it != _notifiers[endpoint].end(); it++)
1.105 + for (it = ep.notifiers.begin(); it != ep.notifiers.end(); it++)
1.106 {
1.107 client_Notifier notifier(*it);
1.108
1.109 - notifier.notify(flags & _flags[endpoint]);
1.110 + notifier.notify(flags & ep.flags);
1.111 }
1.112 }
1.113 }
1.114 else
1.115 - _deferred[endpoint] = flags;
1.116 + ep.deferred = flags;
1.117 }
1.118
1.119 /* Notify the other endpoints. */
1.120
1.121 void NotificationSupport::notify_others(unsigned int endpoint, notify_flags_t flags)
1.122 {
1.123 - for (unsigned int i = 0; i < _max_endpoints; i++)
1.124 + for (unsigned int i = 0; i < _endpoints.size(); i++)
1.125 if (i != endpoint)
1.126 notify(i, flags);
1.127 }
1.128 @@ -118,14 +121,17 @@
1.129
1.130 void NotificationSupport::release_notifiers()
1.131 {
1.132 - for (unsigned int endpoint = 0; endpoint < _max_endpoints; endpoint++)
1.133 + for (unsigned int endpoint = 0; endpoint < _endpoints.size(); endpoint++)
1.134 {
1.135 - std::set<l4_cap_idx_t>::iterator it;
1.136 + NotificationEndpoint &ep = _endpoints[endpoint];
1.137 + NotifierSet::iterator it;
1.138
1.139 - for (it = _notifiers[endpoint].begin(); it != _notifiers[endpoint].end(); it++)
1.140 + for (it = ep.notifiers.begin(); it != ep.notifiers.end(); it++)
1.141 ipc_cap_free_um(*it);
1.142
1.143 - _notifiers[endpoint].clear();
1.144 + ep.notifiers.clear();
1.145 + ep.flags = 0;
1.146 + ep.deferred = 0;
1.147 }
1.148 }
1.149