# HG changeset patch # User Paul Boddie # Date 1677359468 -3600 # Node ID 4b10ee4a1045e8b79b12ba71f1e1708ea50fe64e # Parent 9cdaf13d4f25dc762fbf06acd9e254747691a07b Simplified the subscribe and unsubscribe interfaces, removing the opaque subscriber parameter and employing the notifier as a way of finding endpoints. Various users of the interfaces consequently retain the notifier instead of the endpoint number to be able to perform the unsubscribe operation. diff -r 9cdaf13d4f25 -r 4b10ee4a1045 libexec/include/exec/external_pager.h --- a/libexec/include/exec/external_pager.h Sat Feb 25 18:10:13 2023 +0100 +++ b/libexec/include/exec/external_pager.h Sat Feb 25 22:11:08 2023 +0100 @@ -35,7 +35,7 @@ public NotificationSupport { protected: - unsigned int _endpoint; + l4_cap_idx_t _notifier; public: explicit ExternalPager(address_t start = 0, address_t end = 0); @@ -59,11 +59,9 @@ /* Notification methods. */ - virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags) - { return NotificationSupport::subscribe(notifier, flags, this, &_endpoint); } + virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags); - virtual long unsubscribe() - { NotificationSupport::unsubscribe(_endpoint, this); return L4_EOK; } + virtual long unsubscribe(); }; /* vim: tabstop=2 expandtab shiftwidth=2 diff -r 9cdaf13d4f25 -r 4b10ee4a1045 libexec/lib/src/external_pager.cc --- a/libexec/lib/src/external_pager.cc Sat Feb 25 18:10:13 2023 +0100 +++ b/libexec/lib/src/external_pager.cc Sat Feb 25 22:11:08 2023 +0100 @@ -168,5 +168,21 @@ return L4_EOK; } +/* Subscribe to notifications. */ + +long ExternalPager::subscribe(l4_cap_idx_t notifier, notify_flags_t flags) +{ + _notifier = notifier; + return NotificationSupport::subscribe(notifier, flags); +} + +/* Unsubscribe from notifications. */ + +long ExternalPager::unsubscribe() +{ + NotificationSupport::unsubscribe(_notifier); + return L4_EOK; +} + /* vim: tabstop=2 expandtab shiftwidth=2 */ diff -r 9cdaf13d4f25 -r 4b10ee4a1045 libfsserver/include/fsserver/directory_resource.h --- a/libfsserver/include/fsserver/directory_resource.h Sat Feb 25 18:10:13 2023 +0100 +++ b/libfsserver/include/fsserver/directory_resource.h Sat Feb 25 22:11:08 2023 +0100 @@ -1,7 +1,7 @@ /* * A resource offering support for directory operations. * - * Copyright (C) 2021, 2022 Paul Boddie + * Copyright (C) 2021, 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -36,7 +36,7 @@ /* Notification endpoint for event subscription. */ - unsigned int _endpoint; + l4_cap_idx_t _notifier; public: fileid_t fileid; diff -r 9cdaf13d4f25 -r 4b10ee4a1045 libfsserver/include/fsserver/file_pager.h --- a/libfsserver/include/fsserver/file_pager.h Sat Feb 25 18:10:13 2023 +0100 +++ b/libfsserver/include/fsserver/file_pager.h Sat Feb 25 22:11:08 2023 +0100 @@ -37,7 +37,7 @@ /* Notification endpoint for event subscription. */ - unsigned int _endpoint; + l4_cap_idx_t _notifier = L4_INVALID_CAP; /* Resize flag for notification. */ diff -r 9cdaf13d4f25 -r 4b10ee4a1045 libfsserver/include/fsserver/notification.h --- a/libfsserver/include/fsserver/notification.h Sat Feb 25 18:10:13 2023 +0100 +++ b/libfsserver/include/fsserver/notification.h Sat Feb 25 22:11:08 2023 +0100 @@ -37,7 +37,7 @@ /* Collection data types. */ typedef std::set NotifierSet; -typedef std::map SubscriberNotifierMap; +typedef std::map NotifierEndpointMap; /* Notification endpoint details. */ @@ -75,9 +75,9 @@ NotificationEndpointList _endpoints; - /* Notifier subscriber details. */ + /* Notifier endpoint details. */ - SubscriberNotifierMap _subscribers; + NotifierEndpointMap _subscribers; /* Deferred notifications for new endpoints. */ @@ -86,13 +86,19 @@ virtual void release_notifiers(); + virtual long _get_endpoint(l4_cap_idx_t notifier, bool remove, + unsigned int *endpoint); + virtual void _notify(unsigned int endpoint, notify_flags_t flags, notify_values_t values); + virtual void _notify_others(unsigned int endpoint, notify_flags_t flags, + notify_values_t values); + virtual long _subscribe(unsigned int endpoint, l4_cap_idx_t notifier, - notify_flags_t flags, void *subscriber); + notify_flags_t flags); - virtual void _unsubscribe(unsigned int endpoint, void *subscriber); + virtual void _unsubscribe(l4_cap_idx_t notifier); public: explicit NotificationSupport(unsigned int endpoints=0); @@ -107,13 +113,15 @@ virtual void notify_others(unsigned int endpoint, notify_flags_t flags, notify_values_t values); - virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags, - void *subscriber, unsigned int *endpoint_number); + virtual void notify_others(l4_cap_idx_t notifier, notify_flags_t flags, + notify_values_t values); + + virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags); virtual long subscribe(unsigned int endpoint, l4_cap_idx_t notifier, - notify_flags_t flags, void *subscriber); + notify_flags_t flags); - virtual void unsubscribe(unsigned int endpoint, void *subscriber); + virtual void unsubscribe(l4_cap_idx_t notifier); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r 9cdaf13d4f25 -r 4b10ee4a1045 libfsserver/include/fsserver/pipe_pager.h --- a/libfsserver/include/fsserver/pipe_pager.h Sat Feb 25 18:10:13 2023 +0100 +++ b/libfsserver/include/fsserver/pipe_pager.h Sat Feb 25 22:11:08 2023 +0100 @@ -1,7 +1,7 @@ /* * A pipe pager providing access to pipe content and navigation support. * - * Copyright (C) 2021, 2022 Paul Boddie + * Copyright (C) 2021, 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -35,6 +35,7 @@ protected: PipePaging *_paging; bool _writing; + l4_cap_idx_t _notifier = L4_INVALID_CAP; /* Helper methods. */ diff -r 9cdaf13d4f25 -r 4b10ee4a1045 libfsserver/lib/directories/directory_resource.cc --- a/libfsserver/lib/directories/directory_resource.cc Sat Feb 25 18:10:13 2023 +0100 +++ b/libfsserver/lib/directories/directory_resource.cc Sat Feb 25 22:11:08 2023 +0100 @@ -1,7 +1,7 @@ /* * A resource offering support for accessing directories. * - * Copyright (C) 2021, 2022 Paul Boddie + * Copyright (C) 2021, 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -125,14 +125,15 @@ long DirectoryResource::subscribe(l4_cap_idx_t notifier, notify_flags_t flags) { - return _provider->subscribe(notifier, flags, this, &_endpoint); + _notifier = notifier; + return _provider->subscribe(notifier, flags); } /* Unsubscribe from notifications. */ long DirectoryResource::unsubscribe() { - _provider->unsubscribe(_endpoint, this); + _provider->unsubscribe(_notifier); return L4_EOK; } diff -r 9cdaf13d4f25 -r 4b10ee4a1045 libfsserver/lib/files/file_pager.cc --- a/libfsserver/lib/files/file_pager.cc Sat Feb 25 18:10:13 2023 +0100 +++ b/libfsserver/lib/files/file_pager.cc Sat Feb 25 22:11:08 2023 +0100 @@ -52,7 +52,7 @@ { /* Notify other users of the file and unsubscribe. */ - _provider->notify_others(_endpoint, NOTIFY_PEER_CLOSED, NOTIFY_VALUES_NULL); + _provider->notify_others(_notifier, NOTIFY_PEER_CLOSED, NOTIFY_VALUES_NULL); unsubscribe(); /* Detach the pager, potentially removing the file provider. */ @@ -70,7 +70,7 @@ if (_resized) { - _provider->notify_others(_endpoint, NOTIFY_CONTENT_AVAILABLE, NOTIFY_VALUES_NULL); + _provider->notify_others(_notifier, NOTIFY_CONTENT_AVAILABLE, NOTIFY_VALUES_NULL); _resized = false; } @@ -153,14 +153,16 @@ /* Readers can subscribe to new data (flush) and file closed events. Writers can subscribe to file closed events. */ - return _provider->subscribe(notifier, flags, this, &_endpoint); + _notifier = notifier; + + return _provider->subscribe(notifier, flags); } /* Unsubscribe from notifications. */ long FilePager::unsubscribe() { - _provider->unsubscribe(_endpoint, this); + _provider->unsubscribe(_notifier); return L4_EOK; } diff -r 9cdaf13d4f25 -r 4b10ee4a1045 libfsserver/lib/generic/notification.cc --- a/libfsserver/lib/generic/notification.cc Sat Feb 25 18:10:13 2023 +0100 +++ b/libfsserver/lib/generic/notification.cc Sat Feb 25 22:11:08 2023 +0100 @@ -40,11 +40,28 @@ { } +/* Return an endpoint number, removing the mapping from the given notifier if + indicated. */ + +long NotificationSupport::_get_endpoint(l4_cap_idx_t notifier, bool remove, unsigned int *endpoint) +{ + NotifierEndpointMap::iterator itp = _subscribers.find(notifier); + + if (itp == _subscribers.end()) + return -L4_ENOENT; + + *endpoint = itp->second; + + if (remove) + _subscribers.erase(itp); + + return L4_EOK; +} + /* Subscribe to notifications using a notification object, returning the endpoint number. */ -long NotificationSupport::subscribe(l4_cap_idx_t notifier, notify_flags_t flags, - void *subscriber, unsigned int *endpoint_number) +long NotificationSupport::subscribe(l4_cap_idx_t notifier, notify_flags_t flags) { std::lock_guard guard(_lock); @@ -59,15 +76,14 @@ _endpoints[endpoint].deferred_values = _deferred_values; } - *endpoint_number = endpoint; - return _subscribe(endpoint, notifier, flags, subscriber); + return _subscribe(endpoint, notifier, flags); } /* Subscribe to a specific endpoint's notifications using a notification object. */ long NotificationSupport::subscribe(unsigned int endpoint, l4_cap_idx_t notifier, - notify_flags_t flags, void *subscriber) + notify_flags_t flags) { std::lock_guard guard(_lock); @@ -82,22 +98,22 @@ _endpoints[endpoint].deferred_values = _deferred_values; } - return _subscribe(endpoint, notifier, flags, subscriber); + return _subscribe(endpoint, notifier, flags); } /* Unsubscribe from an endpoint's notifications. */ -void NotificationSupport::unsubscribe(unsigned int endpoint, void *subscriber) +void NotificationSupport::unsubscribe(l4_cap_idx_t notifier) { std::lock_guard guard(_lock); - _unsubscribe(endpoint, subscriber); + _unsubscribe(notifier); } /* Common subscription functionality. */ long NotificationSupport::_subscribe(unsigned int endpoint, l4_cap_idx_t notifier, - notify_flags_t flags, void *subscriber) + notify_flags_t flags) { /* Record details of the notifier itself. */ @@ -115,28 +131,22 @@ ep.deferred_values = NOTIFY_VALUES_NULL; } - /* Record the subscriber's notifier. */ + /* Record the notifier's endpoint. */ - _subscribers[subscriber] = notifier; + _subscribers[notifier] = endpoint; return L4_EOK; } -void NotificationSupport::_unsubscribe(unsigned int endpoint, void *subscriber) +void NotificationSupport::_unsubscribe(l4_cap_idx_t notifier) { - if (endpoint >= _endpoints.size()) - return; - - /* Find and remove the subscriber's notifier. */ + /* Find and remove the notifier endpoint record. */ - SubscriberNotifierMap::iterator itp = _subscribers.find(subscriber); - l4_cap_idx_t notifier; + unsigned int endpoint; + long err = _get_endpoint(notifier, true, &endpoint); - if (itp == _subscribers.end()) + if (err) return; - notifier = itp->second; - _subscribers.erase(itp); - /* Release the notifier. */ NotificationEndpoint &ep = _endpoints[endpoint]; @@ -220,6 +230,29 @@ { std::lock_guard guard(_lock); + _notify_others(endpoint, flags, values); +} + +/* Notify the other endpoints given a notifier. */ + +void NotificationSupport::notify_others(l4_cap_idx_t notifier, notify_flags_t flags, + notify_values_t values) +{ + std::lock_guard guard(_lock); + + unsigned int endpoint; + long err = _get_endpoint(notifier, false, &endpoint); + + if (err) + return; + + _notify_others(endpoint, flags, values); +} + +void NotificationSupport::_notify_others(unsigned int endpoint, + notify_flags_t flags, + notify_values_t values) +{ for (unsigned int i = 0; i < _endpoints.size(); i++) if (i != endpoint) _notify(i, flags, values); diff -r 9cdaf13d4f25 -r 4b10ee4a1045 libfsserver/lib/pipes/pipe_pager.cc --- a/libfsserver/lib/pipes/pipe_pager.cc Sat Feb 25 18:10:13 2023 +0100 +++ b/libfsserver/lib/pipes/pipe_pager.cc Sat Feb 25 22:11:08 2023 +0100 @@ -1,7 +1,7 @@ /* * A pipe pager providing access to pipe content and navigation support. * - * Copyright (C) 2021, 2022 Paul Boddie + * Copyright (C) 2021, 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -185,16 +185,17 @@ /* Readers can subscribe to new data (at end), and pipe closed events. Writers can subscribe to new space and pipe closed events. */ + _notifier = notifier; + return _paging->subscribe(_writing ? PipePaging::WRITER : PipePaging::READER, - notifier, flags, this); + notifier, flags); } /* Unsubscribe from notifications. */ long PipePager::unsubscribe() { - _paging->unsubscribe(_writing ? PipePaging::WRITER : PipePaging::READER, - this); + _paging->unsubscribe(_notifier); return L4_EOK; }