# HG changeset patch # User Paul Boddie # Date 1647276281 -3600 # Node ID 0914519a072965c1f7571c276fed35e1ecec2179 # Parent 37d3f21edd8becbef502b41e41f74e1cb48c39ff Simplified the unsubscribing mechanism, employing the inherent association between pagers/resources and notifiers to identify the notifier to be released when an unsubscribe operation is issued via a pager or resource. diff -r 37d3f21edd8b -r 0914519a0729 libfsclient/include/fsclient/notifier.h --- a/libfsclient/include/fsclient/notifier.h Mon Mar 14 01:33:25 2022 +0100 +++ b/libfsclient/include/fsclient/notifier.h Mon Mar 14 17:44:41 2022 +0100 @@ -49,10 +49,6 @@ l4_cap_idx_t endpoint = L4_INVALID_CAP; - /* Server endpoint for unsubscribing. */ - - l4_cap_idx_t peer = L4_INVALID_CAP; - bool is_null() { return l4_is_invalid_cap(endpoint); } }; diff -r 37d3f21edd8b -r 0914519a0729 libfsclient/lib/src/Makefile --- a/libfsclient/lib/src/Makefile Mon Mar 14 01:33:25 2022 +0100 +++ b/libfsclient/lib/src/Makefile Mon Mar 14 17:44:41 2022 +0100 @@ -16,7 +16,7 @@ # Individual interfaces. CLIENT_INTERFACES_CC = dataspace directory file filesystem flush \ - mapped_file notification notifier_peer opener \ + mapped_file notification opener \ opener_context pipe pipe_opener # Generated and plain source files. diff -r 37d3f21edd8b -r 0914519a0729 libfsclient/lib/src/notifier.cc --- a/libfsclient/lib/src/notifier.cc Mon Mar 14 01:33:25 2022 +0100 +++ b/libfsclient/lib/src/notifier.cc Mon Mar 14 17:44:41 2022 +0100 @@ -30,7 +30,6 @@ #include "notification_client.h" #include "notifier.h" -#include "notifier_peer_client.h" @@ -205,12 +204,11 @@ return err; } - /* Subscribe, sending the notification endpoint and obtaining a peer endpoint - for unsubscribing. */ + /* Subscribe, sending the notification endpoint. */ client_Notification notify(file->ref); - err = notify.subscribe(state.endpoint, flags, &state.peer); + err = notify.subscribe(state.endpoint, flags); if (err) { @@ -235,14 +233,13 @@ if (state.is_null()) return -L4_EINVAL; - /* Unsubscribe via the peer endpoint. */ + /* Unsubscribe via the notification interface. */ - client_NotifierPeer peer(state.peer); + client_Notification notify(file->ref); - peer.unsubscribe(); + notify.unsubscribe(); ipc_cap_free_um(state.endpoint); - ipc_cap_free_um(state.peer); _state.erase(file); diff -r 37d3f21edd8b -r 0914519a0729 libfsserver/include/fsserver/directory_resource.h --- a/libfsserver/include/fsserver/directory_resource.h Mon Mar 14 01:33:25 2022 +0100 +++ b/libfsserver/include/fsserver/directory_resource.h Mon Mar 14 17:44:41 2022 +0100 @@ -63,8 +63,9 @@ /* Notification methods. */ - virtual long subscribe(l4_cap_idx_t endpoint, notify_flags_t flags, - l4_cap_idx_t *peer); + virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags); + + virtual long unsubscribe(); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r 37d3f21edd8b -r 0914519a0729 libfsserver/include/fsserver/file_pager.h --- a/libfsserver/include/fsserver/file_pager.h Mon Mar 14 01:33:25 2022 +0100 +++ b/libfsserver/include/fsserver/file_pager.h Mon Mar 14 17:44:41 2022 +0100 @@ -74,8 +74,9 @@ /* Notification methods. */ - virtual long subscribe(l4_cap_idx_t endpoint, notify_flags_t flags, - l4_cap_idx_t *peer); + virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags); + + virtual long unsubscribe(); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r 37d3f21edd8b -r 0914519a0729 libfsserver/include/fsserver/notification.h --- a/libfsserver/include/fsserver/notification.h Mon Mar 14 01:33:25 2022 +0100 +++ b/libfsserver/include/fsserver/notification.h Mon Mar 14 17:44:41 2022 +0100 @@ -37,7 +37,7 @@ /* Collection data types. */ typedef std::set NotifierSet; -typedef std::map NotifierPeerMap; +typedef std::map SubscriberNotifierMap; /* Notification endpoint details. */ @@ -68,9 +68,9 @@ NotificationEndpointList _endpoints; - /* Notifier peer details. */ + /* Notifier subscriber details. */ - NotifierPeerMap _peers; + SubscriberNotifierMap _subscribers; /* Deferred notifications for new endpoints. */ @@ -81,9 +81,9 @@ virtual void _notify(unsigned int endpoint, notify_flags_t flags); virtual long _subscribe(unsigned int endpoint, l4_cap_idx_t notifier, - notify_flags_t flags, l4_cap_idx_t *peer); + notify_flags_t flags, void *subscriber); - virtual void _unsubscribe(unsigned int endpoint, l4_cap_idx_t notifier); + virtual void _unsubscribe(unsigned int endpoint, void *subscriber); public: explicit NotificationSupport(unsigned int endpoints=0); @@ -97,12 +97,12 @@ virtual void notify_others(unsigned int endpoint, notify_flags_t flags); virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags, - l4_cap_idx_t *peer, unsigned int *endpoint_number); + void *subscriber, unsigned int *endpoint_number); virtual long subscribe(unsigned int endpoint, l4_cap_idx_t notifier, - notify_flags_t flags, l4_cap_idx_t *peer); + notify_flags_t flags, void *subscriber); - virtual void unsubscribe(unsigned int endpoint, l4_cap_idx_t notifier); + virtual void unsubscribe(unsigned int endpoint, void *subscriber); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r 37d3f21edd8b -r 0914519a0729 libfsserver/include/fsserver/notifier_peer_endpoint.h --- a/libfsserver/include/fsserver/notifier_peer_endpoint.h Mon Mar 14 01:33:25 2022 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Notification unsubscribing support. - * - * Copyright (C) 2021, 2022 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 - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - */ - -#pragma once - -#include -#include -#include - - - -/* A notifier endpoint peer for unsubscribing from notifications. */ - -class NotifierPeerEndpoint : public Resource, public NotifierPeer -{ -protected: - NotificationSupport *_notification; - unsigned int _endpoint; - l4_cap_idx_t _notifier; - -public: - explicit NotifierPeerEndpoint(NotificationSupport *notification, - unsigned int endpoint, l4_cap_idx_t notifier); - - virtual ~NotifierPeerEndpoint(); - - /* Server details. */ - - int expected_items(); - - ipc_server_handler_type handler(); - - void *interface() - { return static_cast(this); } - - /* Operations. */ - - virtual long unsubscribe(); -}; - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r 37d3f21edd8b -r 0914519a0729 libfsserver/include/fsserver/pipe_pager.h --- a/libfsserver/include/fsserver/pipe_pager.h Mon Mar 14 01:33:25 2022 +0100 +++ b/libfsserver/include/fsserver/pipe_pager.h Mon Mar 14 17:44:41 2022 +0100 @@ -76,8 +76,9 @@ /* Notification methods. */ - virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags, - l4_cap_idx_t *peer); + virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags); + + virtual long unsubscribe(); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r 37d3f21edd8b -r 0914519a0729 libfsserver/lib/Makefile --- a/libfsserver/lib/Makefile Mon Mar 14 01:33:25 2022 +0100 +++ b/libfsserver/lib/Makefile Mon Mar 14 17:44:41 2022 +0100 @@ -36,7 +36,7 @@ CLIENT_INTERFACES_CC = notifier -SERVER_INTERFACES_CC = notifier_peer opener pipe_opener $(call common_interfaces,$(COMP_INTERFACES_CC)) +SERVER_INTERFACES_CC = opener pipe_opener $(call common_interfaces,$(COMP_INTERFACES_CC)) # Generated and plain source files. @@ -71,7 +71,6 @@ generic/provider_registry.cc \ generic/resource_registry.cc \ generic/notification.cc \ - generic/notifier_peer_endpoint.cc \ generic/pager.cc \ generic/provider.cc \ generic/resource_server.cc \ diff -r 37d3f21edd8b -r 0914519a0729 libfsserver/lib/directories/directory_resource.cc --- a/libfsserver/lib/directories/directory_resource.cc Mon Mar 14 01:33:25 2022 +0100 +++ b/libfsserver/lib/directories/directory_resource.cc Mon Mar 14 17:44:41 2022 +0100 @@ -128,10 +128,17 @@ /* Subscribe to notifications. */ -long DirectoryResource::subscribe(l4_cap_idx_t endpoint, notify_flags_t flags, - l4_cap_idx_t *peer) +long DirectoryResource::subscribe(l4_cap_idx_t notifier, notify_flags_t flags) { - return _provider->subscribe(endpoint, flags, peer, &_endpoint); + return _provider->subscribe(notifier, flags, this, &_endpoint); +} + +/* Unsubscribe from notifications. */ + +long DirectoryResource::unsubscribe() +{ + _provider->unsubscribe(_endpoint, this); + return L4_EOK; } // vim: tabstop=4 expandtab shiftwidth=4 diff -r 37d3f21edd8b -r 0914519a0729 libfsserver/lib/files/file_pager.cc --- a/libfsserver/lib/files/file_pager.cc Mon Mar 14 01:33:25 2022 +0100 +++ b/libfsserver/lib/files/file_pager.cc Mon Mar 14 17:44:41 2022 +0100 @@ -111,13 +111,20 @@ /* Subscribe to notifications. */ -long FilePager::subscribe(l4_cap_idx_t endpoint, notify_flags_t flags, - l4_cap_idx_t *peer) +long FilePager::subscribe(l4_cap_idx_t notifier, notify_flags_t flags) { /* Readers can subscribe to new data (flush) and file closed events. Writers can subscribe to file closed events. */ - return _provider->subscribe(endpoint, flags, peer, &_endpoint); + return _provider->subscribe(notifier, flags, this, &_endpoint); +} + +/* Unsubscribe from notifications. */ + +long FilePager::unsubscribe() +{ + _provider->unsubscribe(_endpoint, this); + return L4_EOK; } // vim: tabstop=4 expandtab shiftwidth=4 diff -r 37d3f21edd8b -r 0914519a0729 libfsserver/lib/generic/notification.cc --- a/libfsserver/lib/generic/notification.cc Mon Mar 14 01:33:25 2022 +0100 +++ b/libfsserver/lib/generic/notification.cc Mon Mar 14 17:44:41 2022 +0100 @@ -23,7 +23,6 @@ #include "notification.h" #include "notifier_client.h" -#include "notifier_peer_endpoint.h" #include "resource_server.h" @@ -45,7 +44,7 @@ endpoint number. */ long NotificationSupport::subscribe(l4_cap_idx_t notifier, notify_flags_t flags, - l4_cap_idx_t *peer, unsigned int *endpoint_number) + void *subscriber, unsigned int *endpoint_number) { std::lock_guard guard(_lock); @@ -58,14 +57,14 @@ _endpoints[endpoint].deferred = _deferred; *endpoint_number = endpoint; - return _subscribe(endpoint, notifier, flags, peer); + return _subscribe(endpoint, notifier, flags, subscriber); } /* 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, l4_cap_idx_t *peer) + notify_flags_t flags, void *subscriber) { std::lock_guard guard(_lock); @@ -79,22 +78,22 @@ _endpoints[endpoint].deferred = _deferred; } - return _subscribe(endpoint, notifier, flags, peer); + return _subscribe(endpoint, notifier, flags, subscriber); } /* Unsubscribe from an endpoint's notifications. */ -void NotificationSupport::unsubscribe(unsigned int endpoint, l4_cap_idx_t notifier) +void NotificationSupport::unsubscribe(unsigned int endpoint, void *subscriber) { std::lock_guard guard(_lock); - _unsubscribe(endpoint, notifier); + _unsubscribe(endpoint, subscriber); } /* Common subscription functionality. */ long NotificationSupport::_subscribe(unsigned int endpoint, l4_cap_idx_t notifier, - notify_flags_t flags, l4_cap_idx_t *peer) + notify_flags_t flags, void *subscriber) { /* Record details of the notifier itself. */ @@ -111,25 +110,30 @@ ep.deferred = 0; } - /* Create a notifier peer for unsubscribing. */ - - NotifierPeerEndpoint *peer_ep = new NotifierPeerEndpoint(this, endpoint, notifier); - - _peers[notifier] = peer_ep; + /* Record the subscriber's notifier. */ - long err = ResourceServer(peer_ep).start_thread(peer); - - if (err) - _unsubscribe(endpoint, notifier); - - return err; + _subscribers[subscriber] = notifier; + return L4_EOK; } -void NotificationSupport::_unsubscribe(unsigned int endpoint, l4_cap_idx_t notifier) +void NotificationSupport::_unsubscribe(unsigned int endpoint, void *subscriber) { if (endpoint >= _endpoints.size()) return; + /* Find and remove the subscriber's notifier. */ + + SubscriberNotifierMap::iterator itp = _subscribers.find(subscriber); + l4_cap_idx_t notifier; + + if (itp == _subscribers.end()) + return; + + notifier = itp->second; + _subscribers.erase(itp); + + /* Release the notifier. */ + NotificationEndpoint &ep = _endpoints[endpoint]; NotifierSet::iterator it = ep.notifiers.find(notifier); @@ -144,13 +148,6 @@ ep.deferred = 0; } } - - /* Remove the notifier peer. */ - - NotifierPeerMap::iterator itp = _peers.find(notifier); - - if (itp != _peers.end()) - _peers.erase(itp); } /* Notify a particular endpoint. */ diff -r 37d3f21edd8b -r 0914519a0729 libfsserver/lib/generic/notifier_peer_endpoint.cc --- a/libfsserver/lib/generic/notifier_peer_endpoint.cc Mon Mar 14 01:33:25 2022 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Notification support. - * - * Copyright (C) 2021, 2022 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 - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - */ - -#include "notifier_peer_endpoint.h" -#include "notifier_peer_server.h" - - - -/* Notifier peer endpoint. */ - -NotifierPeerEndpoint::NotifierPeerEndpoint(NotificationSupport *notification, - unsigned int endpoint, - l4_cap_idx_t notifier) -: _notification(notification), _endpoint(endpoint), _notifier(notifier) -{ -} - -NotifierPeerEndpoint::~NotifierPeerEndpoint() -{ -} - -/* Server methods. */ - -int NotifierPeerEndpoint::expected_items() -{ - return NotifierPeer_expected_items; -} - -ipc_server_handler_type NotifierPeerEndpoint::handler() -{ - return (ipc_server_handler_type) handle_NotifierPeer; -} - -/* Unsubscribe a notifier via this peer. */ - -long NotifierPeerEndpoint::unsubscribe() -{ - _notification->unsubscribe(_endpoint, _notifier); - return L4_EOK; -} - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r 37d3f21edd8b -r 0914519a0729 libfsserver/lib/pipes/pipe_pager.cc --- a/libfsserver/lib/pipes/pipe_pager.cc Mon Mar 14 01:33:25 2022 +0100 +++ b/libfsserver/lib/pipes/pipe_pager.cc Mon Mar 14 17:44:41 2022 +0100 @@ -182,14 +182,22 @@ /* Subscribe to notifications. */ -long PipePager::subscribe(l4_cap_idx_t notifier, notify_flags_t flags, - l4_cap_idx_t *peer) +long PipePager::subscribe(l4_cap_idx_t notifier, notify_flags_t flags) { /* Readers can subscribe to new data (at end), and pipe closed events. Writers can subscribe to new space and pipe closed events. */ return _paging->subscribe(_writing ? PipePaging::WRITER : PipePaging::READER, - notifier, flags, peer); + notifier, flags, this); +} + +/* Unsubscribe from notifications. */ + +long PipePager::unsubscribe() +{ + _paging->unsubscribe(_writing ? PipePaging::WRITER : PipePaging::READER, + this); + return L4_EOK; } // vim: tabstop=4 expandtab shiftwidth=4 diff -r 37d3f21edd8b -r 0914519a0729 libsystypes/idl/notification.idl --- a/libsystypes/idl/notification.idl Mon Mar 14 01:33:25 2022 +0100 +++ b/libsystypes/idl/notification.idl Mon Mar 14 17:44:41 2022 +0100 @@ -2,9 +2,12 @@ interface Notification { - /* Subscribe to events. Unsubscribing is done via the peer returned by the - operation. */ + /* Subscribe to events, providing the given notifier to receive notifications + according to the given flags. */ + + [opcode(23)] void subscribe(in cap notifier, in notify_flags_t flags); - [opcode(23)] void subscribe(in cap notifier, in notify_flags_t flags, - out cap peer); + /* Unsubscribe from events. */ + + [opcode(24)] void unsubscribe(); }; diff -r 37d3f21edd8b -r 0914519a0729 libsystypes/idl/notifier_peer.idl --- a/libsystypes/idl/notifier_peer.idl Mon Mar 14 01:33:25 2022 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -interface NotifierPeer -{ - /* Unsubscribe from events. */ - - [opcode(24)] void unsubscribe(); -};