1.1 --- a/libfsserver/include/fsserver/notification.h Mon Jul 12 23:18:16 2021 +0200
1.2 +++ b/libfsserver/include/fsserver/notification.h Tue Jul 13 00:26:11 2021 +0200
1.3 @@ -22,11 +22,29 @@
1.4 #pragma once
1.5
1.6 #include <set>
1.7 +#include <vector>
1.8
1.9 #include <systypes/base.h>
1.10
1.11
1.12
1.13 +/* Collection data types. */
1.14 +
1.15 +typedef std::set<l4_cap_idx_t> NotifierSet;
1.16 +
1.17 +/* Notification endpoint details. */
1.18 +
1.19 +class NotificationEndpoint
1.20 +{
1.21 +public:
1.22 + NotifierSet notifiers;
1.23 + notify_flags_t flags, deferred;
1.24 +};
1.25 +
1.26 +typedef std::vector<NotificationEndpoint> NotificationEndpointList;
1.27 +
1.28 +
1.29 +
1.30 /* Notification support, allowing pipe or file users to receive events due to
1.31 activity on those objects. */
1.32
1.33 @@ -35,20 +53,16 @@
1.34 protected:
1.35 /* Endpoint count. */
1.36
1.37 - unsigned int _max_endpoints;
1.38 + unsigned int _min_endpoints;
1.39
1.40 - /* Notification endpoints and flags, set up at initialisation for the
1.41 - appropriate number of endpoints. */
1.42 + /* Notification endpoint details. */
1.43
1.44 - std::set<l4_cap_idx_t> *_notifiers;
1.45 - notify_flags_t *_flags, *_deferred;
1.46 + NotificationEndpointList _endpoints;
1.47
1.48 virtual void release_notifiers();
1.49
1.50 public:
1.51 - explicit NotificationSupport(unsigned int endpoints);
1.52 -
1.53 - virtual ~NotificationSupport();
1.54 + explicit NotificationSupport(unsigned int endpoints=0);
1.55
1.56 virtual void notify(unsigned int endpoint, notify_flags_t flags);
1.57
2.1 --- a/libfsserver/include/fsserver/pipe_paging.h Mon Jul 12 23:18:16 2021 +0200
2.2 +++ b/libfsserver/include/fsserver/pipe_paging.h Tue Jul 13 00:26:11 2021 +0200
2.3 @@ -55,7 +55,7 @@
2.4
2.5 /* Endpoint status. */
2.6
2.7 - unsigned int _endpoints = 2;
2.8 + unsigned int _active_endpoints = 2;
2.9
2.10 /* Common functionality. */
2.11
3.1 --- a/libfsserver/lib/generic/notification.cc Mon Jul 12 23:18:16 2021 +0200
3.2 +++ b/libfsserver/lib/generic/notification.cc Tue Jul 13 00:26:11 2021 +0200
3.3 @@ -29,39 +29,29 @@
3.4 /* Initialise endpoints and flags for notifications. */
3.5
3.6 NotificationSupport::NotificationSupport(unsigned int endpoints)
3.7 -: _max_endpoints(endpoints)
3.8 +: _min_endpoints(endpoints)
3.9 {
3.10 - _notifiers = new std::set<l4_cap_idx_t>[endpoints];
3.11 - _flags = new notify_flags_t[endpoints];
3.12 - _deferred = new notify_flags_t[endpoints];
3.13 -
3.14 - for (unsigned int endpoint = 0; endpoint < _max_endpoints; endpoint++)
3.15 - {
3.16 - _flags[endpoint] = 0;
3.17 - _deferred[endpoint] = 0;
3.18 - }
3.19 -}
3.20 -
3.21 -NotificationSupport::~NotificationSupport()
3.22 -{
3.23 - delete _notifiers;
3.24 - delete _flags;
3.25 - delete _deferred;
3.26 + _endpoints.resize(_min_endpoints);
3.27 }
3.28
3.29 /* Subscribe to an endpoint's notifications using a notification endpoint. */
3.30
3.31 void NotificationSupport::subscribe(unsigned int endpoint, l4_cap_idx_t notifier, notify_flags_t flags)
3.32 {
3.33 - _notifiers[endpoint].insert(notifier);
3.34 - _flags[endpoint] = flags;
3.35 + if (endpoint >= _endpoints.size())
3.36 + _endpoints.resize(endpoint + 1);
3.37 +
3.38 + NotificationEndpoint &ep = _endpoints[endpoint];
3.39 +
3.40 + ep.notifiers.insert(notifier);
3.41 + ep.flags = flags;
3.42
3.43 /* Send deferred conditions held from before subscription occurred. */
3.44
3.45 - if (_deferred[endpoint])
3.46 + if (ep.deferred)
3.47 {
3.48 - notify(endpoint, _deferred[endpoint]);
3.49 - _deferred[endpoint] = 0;
3.50 + notify(endpoint, ep.deferred);
3.51 + ep.deferred = 0;
3.52 }
3.53 }
3.54
3.55 @@ -69,14 +59,22 @@
3.56
3.57 void NotificationSupport::unsubscribe(unsigned int endpoint, l4_cap_idx_t notifier)
3.58 {
3.59 - std::set<l4_cap_idx_t>::iterator it = _notifiers[endpoint].find(notifier);
3.60 + if (endpoint >= _endpoints.size())
3.61 + return;
3.62
3.63 - if (it != _notifiers[endpoint].end())
3.64 + NotificationEndpoint &ep = _endpoints[endpoint];
3.65 + NotifierSet::iterator it = ep.notifiers.find(notifier);
3.66 +
3.67 + if (it != ep.notifiers.end())
3.68 {
3.69 - _notifiers[endpoint].erase(it);
3.70 - _flags[endpoint] = 0;
3.71 - _deferred[endpoint] = 0;
3.72 + ep.notifiers.erase(it);
3.73 ipc_cap_free_um(notifier);
3.74 +
3.75 + if (ep.notifiers.empty())
3.76 + {
3.77 + ep.flags = 0;
3.78 + ep.deferred = 0;
3.79 + }
3.80 }
3.81 }
3.82
3.83 @@ -84,32 +82,37 @@
3.84
3.85 void NotificationSupport::notify(unsigned int endpoint, notify_flags_t flags)
3.86 {
3.87 + if (endpoint >= _endpoints.size())
3.88 + return;
3.89 +
3.90 + NotificationEndpoint &ep = _endpoints[endpoint];
3.91 +
3.92 /* Notify the endpoint or hold any notification for potential future
3.93 subscription. */
3.94
3.95 - if (!_notifiers[endpoint].empty())
3.96 + if (!ep.notifiers.empty())
3.97 {
3.98 - if (flags & _flags[endpoint])
3.99 + if (flags & ep.flags)
3.100 {
3.101 - std::set<l4_cap_idx_t>::iterator it;
3.102 + NotifierSet::iterator it;
3.103
3.104 - for (it = _notifiers[endpoint].begin(); it != _notifiers[endpoint].end(); it++)
3.105 + for (it = ep.notifiers.begin(); it != ep.notifiers.end(); it++)
3.106 {
3.107 client_Notifier notifier(*it);
3.108
3.109 - notifier.notify(flags & _flags[endpoint]);
3.110 + notifier.notify(flags & ep.flags);
3.111 }
3.112 }
3.113 }
3.114 else
3.115 - _deferred[endpoint] = flags;
3.116 + ep.deferred = flags;
3.117 }
3.118
3.119 /* Notify the other endpoints. */
3.120
3.121 void NotificationSupport::notify_others(unsigned int endpoint, notify_flags_t flags)
3.122 {
3.123 - for (unsigned int i = 0; i < _max_endpoints; i++)
3.124 + for (unsigned int i = 0; i < _endpoints.size(); i++)
3.125 if (i != endpoint)
3.126 notify(i, flags);
3.127 }
3.128 @@ -118,14 +121,17 @@
3.129
3.130 void NotificationSupport::release_notifiers()
3.131 {
3.132 - for (unsigned int endpoint = 0; endpoint < _max_endpoints; endpoint++)
3.133 + for (unsigned int endpoint = 0; endpoint < _endpoints.size(); endpoint++)
3.134 {
3.135 - std::set<l4_cap_idx_t>::iterator it;
3.136 + NotificationEndpoint &ep = _endpoints[endpoint];
3.137 + NotifierSet::iterator it;
3.138
3.139 - for (it = _notifiers[endpoint].begin(); it != _notifiers[endpoint].end(); it++)
3.140 + for (it = ep.notifiers.begin(); it != ep.notifiers.end(); it++)
3.141 ipc_cap_free_um(*it);
3.142
3.143 - _notifiers[endpoint].clear();
3.144 + ep.notifiers.clear();
3.145 + ep.flags = 0;
3.146 + ep.deferred = 0;
3.147 }
3.148 }
3.149
4.1 --- a/libfsserver/lib/pipes/pipe_paging.cc Mon Jul 12 23:18:16 2021 +0200
4.2 +++ b/libfsserver/lib/pipes/pipe_paging.cc Tue Jul 13 00:26:11 2021 +0200
4.3 @@ -47,7 +47,7 @@
4.4
4.5 int PipePaging::closed()
4.6 {
4.7 - return _endpoints < 2;
4.8 + return _active_endpoints < 2;
4.9 }
4.10
4.11 void PipePaging::discard_region(unsigned int i)
4.12 @@ -66,14 +66,14 @@
4.13
4.14 void PipePaging::detach()
4.15 {
4.16 - if (!_endpoints)
4.17 + if (!_active_endpoints)
4.18 return;
4.19 else
4.20 - _endpoints--;
4.21 + _active_endpoints--;
4.22
4.23 /* Return if the other endpoint is attached. */
4.24
4.25 - if (_endpoints)
4.26 + if (_active_endpoints)
4.27 return;
4.28
4.29 /* Discard all regions from the pipe. */