1.1 --- a/libfsserver/lib/generic/notification.cc Tue Jul 13 23:18:37 2021 +0200
1.2 +++ b/libfsserver/lib/generic/notification.cc Fri Jul 16 00:38:55 2021 +0200
1.3 @@ -34,13 +34,51 @@
1.4 _endpoints.resize(_min_endpoints);
1.5 }
1.6
1.7 -/* Subscribe to an endpoint's notifications using a notification endpoint. */
1.8 +/* Subscribe to notifications using a notification object, returning the
1.9 + endpoint number. */
1.10 +
1.11 +unsigned int NotificationSupport::subscribe(l4_cap_idx_t notifier, notify_flags_t flags)
1.12 +{
1.13 + std::lock_guard<std::mutex> guard(_lock);
1.14 +
1.15 + unsigned int endpoint = _endpoints.size();
1.16 +
1.17 + _endpoints.resize(endpoint + 1);
1.18 +
1.19 + /* Propagate deferred flags for new endpoints. */
1.20 +
1.21 + if (_deferred)
1.22 + _endpoints[endpoint].deferred = _deferred;
1.23 +
1.24 + _subscribe(endpoint, notifier, flags);
1.25 +
1.26 + return endpoint;
1.27 +}
1.28 +
1.29 +/* Subscribe to a specific endpoint's notifications using a notification
1.30 + object. */
1.31
1.32 void NotificationSupport::subscribe(unsigned int endpoint, l4_cap_idx_t notifier, notify_flags_t flags)
1.33 {
1.34 + std::lock_guard<std::mutex> guard(_lock);
1.35 +
1.36 if (endpoint >= _endpoints.size())
1.37 + {
1.38 _endpoints.resize(endpoint + 1);
1.39
1.40 + /* Propagate deferred flags for new endpoints. */
1.41 +
1.42 + if (_deferred)
1.43 + _endpoints[endpoint].deferred = _deferred;
1.44 + }
1.45 +
1.46 + _subscribe(endpoint, notifier, flags);
1.47 +}
1.48 +
1.49 +/* Common subscription functionality. */
1.50 +
1.51 +void NotificationSupport::_subscribe(unsigned int endpoint, l4_cap_idx_t notifier, notify_flags_t flags)
1.52 +{
1.53 NotificationEndpoint &ep = _endpoints[endpoint];
1.54
1.55 ep.notifiers.insert(notifier);
1.56 @@ -50,7 +88,7 @@
1.57
1.58 if (ep.deferred)
1.59 {
1.60 - notify(endpoint, ep.deferred);
1.61 + _notify(endpoint, ep.deferred);
1.62 ep.deferred = 0;
1.63 }
1.64 }
1.65 @@ -59,6 +97,8 @@
1.66
1.67 void NotificationSupport::unsubscribe(unsigned int endpoint, l4_cap_idx_t notifier)
1.68 {
1.69 + std::lock_guard<std::mutex> guard(_lock);
1.70 +
1.71 if (endpoint >= _endpoints.size())
1.72 return;
1.73
1.74 @@ -82,6 +122,13 @@
1.75
1.76 void NotificationSupport::notify(unsigned int endpoint, notify_flags_t flags)
1.77 {
1.78 + std::lock_guard<std::mutex> guard(_lock);
1.79 +
1.80 + _notify(endpoint, flags);
1.81 +}
1.82 +
1.83 +void NotificationSupport::_notify(unsigned int endpoint, notify_flags_t flags)
1.84 +{
1.85 if (endpoint >= _endpoints.size())
1.86 return;
1.87
1.88 @@ -112,15 +159,21 @@
1.89
1.90 void NotificationSupport::notify_others(unsigned int endpoint, notify_flags_t flags)
1.91 {
1.92 + std::lock_guard<std::mutex> guard(_lock);
1.93 +
1.94 for (unsigned int i = 0; i < _endpoints.size(); i++)
1.95 if (i != endpoint)
1.96 - notify(i, flags);
1.97 + _notify(i, flags);
1.98 +
1.99 + _deferred |= flags;
1.100 }
1.101
1.102 /* Release notifiers for each endpoint. */
1.103
1.104 void NotificationSupport::release_notifiers()
1.105 {
1.106 + std::lock_guard<std::mutex> guard(_lock);
1.107 +
1.108 for (unsigned int endpoint = 0; endpoint < _endpoints.size(); endpoint++)
1.109 {
1.110 NotificationEndpoint &ep = _endpoints[endpoint];