1.1 --- a/libexec/include/exec/external_pager.h Sat Feb 25 18:10:13 2023 +0100
1.2 +++ b/libexec/include/exec/external_pager.h Sat Feb 25 22:11:08 2023 +0100
1.3 @@ -35,7 +35,7 @@
1.4 public NotificationSupport
1.5 {
1.6 protected:
1.7 - unsigned int _endpoint;
1.8 + l4_cap_idx_t _notifier;
1.9
1.10 public:
1.11 explicit ExternalPager(address_t start = 0, address_t end = 0);
1.12 @@ -59,11 +59,9 @@
1.13
1.14 /* Notification methods. */
1.15
1.16 - virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags)
1.17 - { return NotificationSupport::subscribe(notifier, flags, this, &_endpoint); }
1.18 + virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags);
1.19
1.20 - virtual long unsubscribe()
1.21 - { NotificationSupport::unsubscribe(_endpoint, this); return L4_EOK; }
1.22 + virtual long unsubscribe();
1.23 };
1.24
1.25 /* vim: tabstop=2 expandtab shiftwidth=2
2.1 --- a/libexec/lib/src/external_pager.cc Sat Feb 25 18:10:13 2023 +0100
2.2 +++ b/libexec/lib/src/external_pager.cc Sat Feb 25 22:11:08 2023 +0100
2.3 @@ -168,5 +168,21 @@
2.4 return L4_EOK;
2.5 }
2.6
2.7 +/* Subscribe to notifications. */
2.8 +
2.9 +long ExternalPager::subscribe(l4_cap_idx_t notifier, notify_flags_t flags)
2.10 +{
2.11 + _notifier = notifier;
2.12 + return NotificationSupport::subscribe(notifier, flags);
2.13 +}
2.14 +
2.15 +/* Unsubscribe from notifications. */
2.16 +
2.17 +long ExternalPager::unsubscribe()
2.18 +{
2.19 + NotificationSupport::unsubscribe(_notifier);
2.20 + return L4_EOK;
2.21 +}
2.22 +
2.23 /* vim: tabstop=2 expandtab shiftwidth=2
2.24 */
3.1 --- a/libfsserver/include/fsserver/directory_resource.h Sat Feb 25 18:10:13 2023 +0100
3.2 +++ b/libfsserver/include/fsserver/directory_resource.h Sat Feb 25 22:11:08 2023 +0100
3.3 @@ -1,7 +1,7 @@
3.4 /*
3.5 * A resource offering support for directory operations.
3.6 *
3.7 - * Copyright (C) 2021, 2022 Paul Boddie <paul@boddie.org.uk>
3.8 + * Copyright (C) 2021, 2022, 2023 Paul Boddie <paul@boddie.org.uk>
3.9 *
3.10 * This program is free software; you can redistribute it and/or
3.11 * modify it under the terms of the GNU General Public License as
3.12 @@ -36,7 +36,7 @@
3.13
3.14 /* Notification endpoint for event subscription. */
3.15
3.16 - unsigned int _endpoint;
3.17 + l4_cap_idx_t _notifier;
3.18
3.19 public:
3.20 fileid_t fileid;
4.1 --- a/libfsserver/include/fsserver/file_pager.h Sat Feb 25 18:10:13 2023 +0100
4.2 +++ b/libfsserver/include/fsserver/file_pager.h Sat Feb 25 22:11:08 2023 +0100
4.3 @@ -37,7 +37,7 @@
4.4
4.5 /* Notification endpoint for event subscription. */
4.6
4.7 - unsigned int _endpoint;
4.8 + l4_cap_idx_t _notifier = L4_INVALID_CAP;
4.9
4.10 /* Resize flag for notification. */
4.11
5.1 --- a/libfsserver/include/fsserver/notification.h Sat Feb 25 18:10:13 2023 +0100
5.2 +++ b/libfsserver/include/fsserver/notification.h Sat Feb 25 22:11:08 2023 +0100
5.3 @@ -37,7 +37,7 @@
5.4 /* Collection data types. */
5.5
5.6 typedef std::set<l4_cap_idx_t> NotifierSet;
5.7 -typedef std::map<void *, l4_cap_idx_t> SubscriberNotifierMap;
5.8 +typedef std::map<l4_cap_idx_t, unsigned int> NotifierEndpointMap;
5.9
5.10 /* Notification endpoint details. */
5.11
5.12 @@ -75,9 +75,9 @@
5.13
5.14 NotificationEndpointList _endpoints;
5.15
5.16 - /* Notifier subscriber details. */
5.17 + /* Notifier endpoint details. */
5.18
5.19 - SubscriberNotifierMap _subscribers;
5.20 + NotifierEndpointMap _subscribers;
5.21
5.22 /* Deferred notifications for new endpoints. */
5.23
5.24 @@ -86,13 +86,19 @@
5.25
5.26 virtual void release_notifiers();
5.27
5.28 + virtual long _get_endpoint(l4_cap_idx_t notifier, bool remove,
5.29 + unsigned int *endpoint);
5.30 +
5.31 virtual void _notify(unsigned int endpoint, notify_flags_t flags,
5.32 notify_values_t values);
5.33
5.34 + virtual void _notify_others(unsigned int endpoint, notify_flags_t flags,
5.35 + notify_values_t values);
5.36 +
5.37 virtual long _subscribe(unsigned int endpoint, l4_cap_idx_t notifier,
5.38 - notify_flags_t flags, void *subscriber);
5.39 + notify_flags_t flags);
5.40
5.41 - virtual void _unsubscribe(unsigned int endpoint, void *subscriber);
5.42 + virtual void _unsubscribe(l4_cap_idx_t notifier);
5.43
5.44 public:
5.45 explicit NotificationSupport(unsigned int endpoints=0);
5.46 @@ -107,13 +113,15 @@
5.47 virtual void notify_others(unsigned int endpoint, notify_flags_t flags,
5.48 notify_values_t values);
5.49
5.50 - virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags,
5.51 - void *subscriber, unsigned int *endpoint_number);
5.52 + virtual void notify_others(l4_cap_idx_t notifier, notify_flags_t flags,
5.53 + notify_values_t values);
5.54 +
5.55 + virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags);
5.56
5.57 virtual long subscribe(unsigned int endpoint, l4_cap_idx_t notifier,
5.58 - notify_flags_t flags, void *subscriber);
5.59 + notify_flags_t flags);
5.60
5.61 - virtual void unsubscribe(unsigned int endpoint, void *subscriber);
5.62 + virtual void unsubscribe(l4_cap_idx_t notifier);
5.63 };
5.64
5.65 // vim: tabstop=4 expandtab shiftwidth=4
6.1 --- a/libfsserver/include/fsserver/pipe_pager.h Sat Feb 25 18:10:13 2023 +0100
6.2 +++ b/libfsserver/include/fsserver/pipe_pager.h Sat Feb 25 22:11:08 2023 +0100
6.3 @@ -1,7 +1,7 @@
6.4 /*
6.5 * A pipe pager providing access to pipe content and navigation support.
6.6 *
6.7 - * Copyright (C) 2021, 2022 Paul Boddie <paul@boddie.org.uk>
6.8 + * Copyright (C) 2021, 2022, 2023 Paul Boddie <paul@boddie.org.uk>
6.9 *
6.10 * This program is free software; you can redistribute it and/or
6.11 * modify it under the terms of the GNU General Public License as
6.12 @@ -35,6 +35,7 @@
6.13 protected:
6.14 PipePaging *_paging;
6.15 bool _writing;
6.16 + l4_cap_idx_t _notifier = L4_INVALID_CAP;
6.17
6.18 /* Helper methods. */
6.19
7.1 --- a/libfsserver/lib/directories/directory_resource.cc Sat Feb 25 18:10:13 2023 +0100
7.2 +++ b/libfsserver/lib/directories/directory_resource.cc Sat Feb 25 22:11:08 2023 +0100
7.3 @@ -1,7 +1,7 @@
7.4 /*
7.5 * A resource offering support for accessing directories.
7.6 *
7.7 - * Copyright (C) 2021, 2022 Paul Boddie <paul@boddie.org.uk>
7.8 + * Copyright (C) 2021, 2022, 2023 Paul Boddie <paul@boddie.org.uk>
7.9 *
7.10 * This program is free software; you can redistribute it and/or
7.11 * modify it under the terms of the GNU General Public License as
7.12 @@ -125,14 +125,15 @@
7.13
7.14 long DirectoryResource::subscribe(l4_cap_idx_t notifier, notify_flags_t flags)
7.15 {
7.16 - return _provider->subscribe(notifier, flags, this, &_endpoint);
7.17 + _notifier = notifier;
7.18 + return _provider->subscribe(notifier, flags);
7.19 }
7.20
7.21 /* Unsubscribe from notifications. */
7.22
7.23 long DirectoryResource::unsubscribe()
7.24 {
7.25 - _provider->unsubscribe(_endpoint, this);
7.26 + _provider->unsubscribe(_notifier);
7.27 return L4_EOK;
7.28 }
7.29
8.1 --- a/libfsserver/lib/files/file_pager.cc Sat Feb 25 18:10:13 2023 +0100
8.2 +++ b/libfsserver/lib/files/file_pager.cc Sat Feb 25 22:11:08 2023 +0100
8.3 @@ -52,7 +52,7 @@
8.4 {
8.5 /* Notify other users of the file and unsubscribe. */
8.6
8.7 - _provider->notify_others(_endpoint, NOTIFY_PEER_CLOSED, NOTIFY_VALUES_NULL);
8.8 + _provider->notify_others(_notifier, NOTIFY_PEER_CLOSED, NOTIFY_VALUES_NULL);
8.9 unsubscribe();
8.10
8.11 /* Detach the pager, potentially removing the file provider. */
8.12 @@ -70,7 +70,7 @@
8.13
8.14 if (_resized)
8.15 {
8.16 - _provider->notify_others(_endpoint, NOTIFY_CONTENT_AVAILABLE, NOTIFY_VALUES_NULL);
8.17 + _provider->notify_others(_notifier, NOTIFY_CONTENT_AVAILABLE, NOTIFY_VALUES_NULL);
8.18 _resized = false;
8.19 }
8.20
8.21 @@ -153,14 +153,16 @@
8.22 /* Readers can subscribe to new data (flush) and file closed events.
8.23 Writers can subscribe to file closed events. */
8.24
8.25 - return _provider->subscribe(notifier, flags, this, &_endpoint);
8.26 + _notifier = notifier;
8.27 +
8.28 + return _provider->subscribe(notifier, flags);
8.29 }
8.30
8.31 /* Unsubscribe from notifications. */
8.32
8.33 long FilePager::unsubscribe()
8.34 {
8.35 - _provider->unsubscribe(_endpoint, this);
8.36 + _provider->unsubscribe(_notifier);
8.37 return L4_EOK;
8.38 }
8.39
9.1 --- a/libfsserver/lib/generic/notification.cc Sat Feb 25 18:10:13 2023 +0100
9.2 +++ b/libfsserver/lib/generic/notification.cc Sat Feb 25 22:11:08 2023 +0100
9.3 @@ -40,11 +40,28 @@
9.4 {
9.5 }
9.6
9.7 +/* Return an endpoint number, removing the mapping from the given notifier if
9.8 + indicated. */
9.9 +
9.10 +long NotificationSupport::_get_endpoint(l4_cap_idx_t notifier, bool remove, unsigned int *endpoint)
9.11 +{
9.12 + NotifierEndpointMap::iterator itp = _subscribers.find(notifier);
9.13 +
9.14 + if (itp == _subscribers.end())
9.15 + return -L4_ENOENT;
9.16 +
9.17 + *endpoint = itp->second;
9.18 +
9.19 + if (remove)
9.20 + _subscribers.erase(itp);
9.21 +
9.22 + return L4_EOK;
9.23 +}
9.24 +
9.25 /* Subscribe to notifications using a notification object, returning the
9.26 endpoint number. */
9.27
9.28 -long NotificationSupport::subscribe(l4_cap_idx_t notifier, notify_flags_t flags,
9.29 - void *subscriber, unsigned int *endpoint_number)
9.30 +long NotificationSupport::subscribe(l4_cap_idx_t notifier, notify_flags_t flags)
9.31 {
9.32 std::lock_guard<std::mutex> guard(_lock);
9.33
9.34 @@ -59,15 +76,14 @@
9.35 _endpoints[endpoint].deferred_values = _deferred_values;
9.36 }
9.37
9.38 - *endpoint_number = endpoint;
9.39 - return _subscribe(endpoint, notifier, flags, subscriber);
9.40 + return _subscribe(endpoint, notifier, flags);
9.41 }
9.42
9.43 /* Subscribe to a specific endpoint's notifications using a notification
9.44 object. */
9.45
9.46 long NotificationSupport::subscribe(unsigned int endpoint, l4_cap_idx_t notifier,
9.47 - notify_flags_t flags, void *subscriber)
9.48 + notify_flags_t flags)
9.49 {
9.50 std::lock_guard<std::mutex> guard(_lock);
9.51
9.52 @@ -82,22 +98,22 @@
9.53 _endpoints[endpoint].deferred_values = _deferred_values;
9.54 }
9.55
9.56 - return _subscribe(endpoint, notifier, flags, subscriber);
9.57 + return _subscribe(endpoint, notifier, flags);
9.58 }
9.59
9.60 /* Unsubscribe from an endpoint's notifications. */
9.61
9.62 -void NotificationSupport::unsubscribe(unsigned int endpoint, void *subscriber)
9.63 +void NotificationSupport::unsubscribe(l4_cap_idx_t notifier)
9.64 {
9.65 std::lock_guard<std::mutex> guard(_lock);
9.66
9.67 - _unsubscribe(endpoint, subscriber);
9.68 + _unsubscribe(notifier);
9.69 }
9.70
9.71 /* Common subscription functionality. */
9.72
9.73 long NotificationSupport::_subscribe(unsigned int endpoint, l4_cap_idx_t notifier,
9.74 - notify_flags_t flags, void *subscriber)
9.75 + notify_flags_t flags)
9.76 {
9.77 /* Record details of the notifier itself. */
9.78
9.79 @@ -115,28 +131,22 @@
9.80 ep.deferred_values = NOTIFY_VALUES_NULL;
9.81 }
9.82
9.83 - /* Record the subscriber's notifier. */
9.84 + /* Record the notifier's endpoint. */
9.85
9.86 - _subscribers[subscriber] = notifier;
9.87 + _subscribers[notifier] = endpoint;
9.88 return L4_EOK;
9.89 }
9.90
9.91 -void NotificationSupport::_unsubscribe(unsigned int endpoint, void *subscriber)
9.92 +void NotificationSupport::_unsubscribe(l4_cap_idx_t notifier)
9.93 {
9.94 - if (endpoint >= _endpoints.size())
9.95 - return;
9.96 -
9.97 - /* Find and remove the subscriber's notifier. */
9.98 + /* Find and remove the notifier endpoint record. */
9.99
9.100 - SubscriberNotifierMap::iterator itp = _subscribers.find(subscriber);
9.101 - l4_cap_idx_t notifier;
9.102 + unsigned int endpoint;
9.103 + long err = _get_endpoint(notifier, true, &endpoint);
9.104
9.105 - if (itp == _subscribers.end())
9.106 + if (err)
9.107 return;
9.108
9.109 - notifier = itp->second;
9.110 - _subscribers.erase(itp);
9.111 -
9.112 /* Release the notifier. */
9.113
9.114 NotificationEndpoint &ep = _endpoints[endpoint];
9.115 @@ -220,6 +230,29 @@
9.116 {
9.117 std::lock_guard<std::mutex> guard(_lock);
9.118
9.119 + _notify_others(endpoint, flags, values);
9.120 +}
9.121 +
9.122 +/* Notify the other endpoints given a notifier. */
9.123 +
9.124 +void NotificationSupport::notify_others(l4_cap_idx_t notifier, notify_flags_t flags,
9.125 + notify_values_t values)
9.126 +{
9.127 + std::lock_guard<std::mutex> guard(_lock);
9.128 +
9.129 + unsigned int endpoint;
9.130 + long err = _get_endpoint(notifier, false, &endpoint);
9.131 +
9.132 + if (err)
9.133 + return;
9.134 +
9.135 + _notify_others(endpoint, flags, values);
9.136 +}
9.137 +
9.138 +void NotificationSupport::_notify_others(unsigned int endpoint,
9.139 + notify_flags_t flags,
9.140 + notify_values_t values)
9.141 +{
9.142 for (unsigned int i = 0; i < _endpoints.size(); i++)
9.143 if (i != endpoint)
9.144 _notify(i, flags, values);
10.1 --- a/libfsserver/lib/pipes/pipe_pager.cc Sat Feb 25 18:10:13 2023 +0100
10.2 +++ b/libfsserver/lib/pipes/pipe_pager.cc Sat Feb 25 22:11:08 2023 +0100
10.3 @@ -1,7 +1,7 @@
10.4 /*
10.5 * A pipe pager providing access to pipe content and navigation support.
10.6 *
10.7 - * Copyright (C) 2021, 2022 Paul Boddie <paul@boddie.org.uk>
10.8 + * Copyright (C) 2021, 2022, 2023 Paul Boddie <paul@boddie.org.uk>
10.9 *
10.10 * This program is free software; you can redistribute it and/or
10.11 * modify it under the terms of the GNU General Public License as
10.12 @@ -185,16 +185,17 @@
10.13 /* Readers can subscribe to new data (at end), and pipe closed events.
10.14 Writers can subscribe to new space and pipe closed events. */
10.15
10.16 + _notifier = notifier;
10.17 +
10.18 return _paging->subscribe(_writing ? PipePaging::WRITER : PipePaging::READER,
10.19 - notifier, flags, this);
10.20 + notifier, flags);
10.21 }
10.22
10.23 /* Unsubscribe from notifications. */
10.24
10.25 long PipePager::unsubscribe()
10.26 {
10.27 - _paging->unsubscribe(_writing ? PipePaging::WRITER : PipePaging::READER,
10.28 - this);
10.29 + _paging->unsubscribe(_notifier);
10.30 return L4_EOK;
10.31 }
10.32