# HG changeset patch # User Paul Boddie # Date 1679791936 -3600 # Node ID 2dd97d71e6273478226e3c982ec886cd30f2d69d # Parent 6e89c2c7fb49f65dbb790c626fa8ebc8fef65067 Removed the indicated notifier from unsubscribe operations since it cannot be trivially compared to any subscribed notifier. Thus, only a single notifier can be used with any given file, pipe, directory or process endpoint. diff -r 6e89c2c7fb49 -r 2dd97d71e627 libexec/include/exec/process_monitor.h --- a/libexec/include/exec/process_monitor.h Sun Mar 26 01:36:53 2023 +0100 +++ b/libexec/include/exec/process_monitor.h Sun Mar 26 01:52:16 2023 +0100 @@ -42,6 +42,10 @@ _task = L4_INVALID_CAP, _mapped_task = L4_INVALID_CAP, _thread = L4_INVALID_CAP, _mapped_thread = L4_INVALID_CAP; + /* Notification support. */ + + l4_cap_idx_t _notifier = L4_INVALID_CAP; + public: explicit ProcessMonitor(); @@ -75,7 +79,7 @@ virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags); - virtual long unsubscribe(l4_cap_idx_t notifier); + virtual long unsubscribe(); }; /* vim: tabstop=2 expandtab shiftwidth=2 diff -r 6e89c2c7fb49 -r 2dd97d71e627 libexec/lib/src/process_monitor.cc --- a/libexec/lib/src/process_monitor.cc Sun Mar 26 01:36:53 2023 +0100 +++ b/libexec/lib/src/process_monitor.cc Sun Mar 26 01:52:16 2023 +0100 @@ -144,14 +144,24 @@ long ProcessMonitor::subscribe(l4_cap_idx_t notifier, notify_flags_t flags) { - return NotificationSupport::subscribe(notifier, flags); + unsubscribe(); + + _notifier = notifier; + return NotificationSupport::subscribe(_notifier, flags); } /* Unsubscribe from notifications. */ -long ProcessMonitor::unsubscribe(l4_cap_idx_t notifier) +long ProcessMonitor::unsubscribe() { - return NotificationSupport::unsubscribe(notifier); + if (l4_is_valid_cap(_notifier)) + { + long err = NotificationSupport::unsubscribe(_notifier); + _notifier = L4_INVALID_CAP; + return err; + } + else + return L4_EOK; } /* vim: tabstop=2 expandtab shiftwidth=2 diff -r 6e89c2c7fb49 -r 2dd97d71e627 libfsserver/include/fsserver/directory_resource.h --- a/libfsserver/include/fsserver/directory_resource.h Sun Mar 26 01:36:53 2023 +0100 +++ b/libfsserver/include/fsserver/directory_resource.h Sun Mar 26 01:52:16 2023 +0100 @@ -63,7 +63,7 @@ virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags); - virtual long unsubscribe(l4_cap_idx_t notifier); + virtual long unsubscribe(); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r 6e89c2c7fb49 -r 2dd97d71e627 libfsserver/include/fsserver/file_pager.h --- a/libfsserver/include/fsserver/file_pager.h Sun Mar 26 01:36:53 2023 +0100 +++ b/libfsserver/include/fsserver/file_pager.h Sun Mar 26 01:52:16 2023 +0100 @@ -83,7 +83,7 @@ virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags); - virtual long unsubscribe(l4_cap_idx_t notifier); + virtual long unsubscribe(); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r 6e89c2c7fb49 -r 2dd97d71e627 libfsserver/include/fsserver/pipe_pager.h --- a/libfsserver/include/fsserver/pipe_pager.h Sun Mar 26 01:36:53 2023 +0100 +++ b/libfsserver/include/fsserver/pipe_pager.h Sun Mar 26 01:52:16 2023 +0100 @@ -77,7 +77,7 @@ virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags); - virtual long unsubscribe(l4_cap_idx_t notifier); + virtual long unsubscribe(); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r 6e89c2c7fb49 -r 2dd97d71e627 libfsserver/lib/directories/directory_resource.cc --- a/libfsserver/lib/directories/directory_resource.cc Sun Mar 26 01:36:53 2023 +0100 +++ b/libfsserver/lib/directories/directory_resource.cc Sun Mar 26 01:52:16 2023 +0100 @@ -52,7 +52,12 @@ appropriate. */ void DirectoryResource::close() -{ +{ + /* Notify other users of the file and unsubscribe. */ + + _provider->notify_others(_notifier, NOTIFY_PEER_CLOSED, NOTIFY_VALUES_NULL); + unsubscribe(); + /* Detach the resource, potentially removing the file provider. */ _provider->registry()->detach(fileid, _provider); @@ -125,15 +130,27 @@ long DirectoryResource::subscribe(l4_cap_idx_t notifier, notify_flags_t flags) { + /* A single notifier is recorded so that it may be unsubscribed when the + directory is closed. */ + + unsubscribe(); + _notifier = notifier; - return _provider->subscribe(notifier, flags); + return _provider->subscribe(_notifier, flags); } /* Unsubscribe from notifications. */ -long DirectoryResource::unsubscribe(l4_cap_idx_t notifier) +long DirectoryResource::unsubscribe() { - return _provider->unsubscribe(notifier); + if (l4_is_valid_cap(_notifier)) + { + long err = _provider->unsubscribe(_notifier); + _notifier = L4_INVALID_CAP; + return err; + } + else + return L4_EOK; } // vim: tabstop=4 expandtab shiftwidth=4 diff -r 6e89c2c7fb49 -r 2dd97d71e627 libfsserver/lib/files/file_pager.cc --- a/libfsserver/lib/files/file_pager.cc Sun Mar 26 01:36:53 2023 +0100 +++ b/libfsserver/lib/files/file_pager.cc Sun Mar 26 01:52:16 2023 +0100 @@ -53,7 +53,7 @@ /* Notify other users of the file and unsubscribe. */ _provider->notify_others(_notifier, NOTIFY_PEER_CLOSED, NOTIFY_VALUES_NULL); - unsubscribe(_notifier); + unsubscribe(); /* Detach the pager, potentially removing the file provider. */ @@ -155,18 +155,24 @@ /* A single notifier is recorded so that it may be unsubscribed when the file is closed. */ - if ((notifier != _notifier) && l4_is_valid_cap(_notifier)) - unsubscribe(_notifier); + unsubscribe(); _notifier = notifier; - return _provider->subscribe(notifier, flags); + return _provider->subscribe(_notifier, flags); } /* Unsubscribe from notifications. */ -long FilePager::unsubscribe(l4_cap_idx_t notifier) +long FilePager::unsubscribe() { - return _provider->unsubscribe(notifier); + if (l4_is_valid_cap(_notifier)) + { + long err = _provider->unsubscribe(_notifier); + _notifier = L4_INVALID_CAP; + return err; + } + else + return L4_EOK; } // vim: tabstop=4 expandtab shiftwidth=4 diff -r 6e89c2c7fb49 -r 2dd97d71e627 libfsserver/lib/pipes/pipe_pager.cc --- a/libfsserver/lib/pipes/pipe_pager.cc Sun Mar 26 01:36:53 2023 +0100 +++ b/libfsserver/lib/pipes/pipe_pager.cc Sun Mar 26 01:52:16 2023 +0100 @@ -62,7 +62,7 @@ _paging->notify_others(_writing ? PipePaging::WRITER : PipePaging::READER, NOTIFY_PEER_CLOSED, NOTIFY_VALUES_NULL); - unsubscribe(_notifier); + unsubscribe(); /* Deallocate the paging coordinator if no other endpoints are active. */ @@ -183,22 +183,27 @@ long PipePager::subscribe(l4_cap_idx_t notifier, notify_flags_t flags) { /* A single notifier is recorded so that it may be unsubscribed when the - file is closed. */ + endpoint is closed. */ - if ((notifier != _notifier) && l4_is_valid_cap(_notifier)) - unsubscribe(_notifier); + unsubscribe(); _notifier = notifier; - return _paging->subscribe(_writing ? PipePaging::WRITER : PipePaging::READER, - notifier, flags); + _notifier, flags); } /* Unsubscribe from notifications. */ -long PipePager::unsubscribe(l4_cap_idx_t notifier) +long PipePager::unsubscribe() { - return _paging->unsubscribe(notifier); + if (l4_is_valid_cap(_notifier)) + { + long err = _paging->unsubscribe(_notifier); + _notifier = L4_INVALID_CAP; + return err; + } + else + return L4_EOK; } // vim: tabstop=4 expandtab shiftwidth=4 diff -r 6e89c2c7fb49 -r 2dd97d71e627 libnotifier/lib/src/notifier.cc --- a/libnotifier/lib/src/notifier.cc Sun Mar 26 01:36:53 2023 +0100 +++ b/libnotifier/lib/src/notifier.cc Sun Mar 26 01:52:16 2023 +0100 @@ -187,6 +187,13 @@ state.endpoint = server.config()->server; } + /* Forbid repeated subscription. + NOTE: Could instead rely on being unsubscribed, releasing the existing + endpoint. */ + + else + return -L4_EEXIST; + /* Allow this object to be re-entered. This may occur because the subscribe operation can cause deferred notifications to be sent back to the subscribed notifier and to this object. */ @@ -218,7 +225,7 @@ client_Notification notify(object->base->ref); - notify.unsubscribe(state.endpoint); + notify.unsubscribe(); return remove_endpoint(object, state.endpoint); } diff -r 6e89c2c7fb49 -r 2dd97d71e627 libsystypes/idl/notification.idl --- a/libsystypes/idl/notification.idl Sun Mar 26 01:36:53 2023 +0100 +++ b/libsystypes/idl/notification.idl Sun Mar 26 01:52:16 2023 +0100 @@ -7,7 +7,8 @@ [opcode(23)] void subscribe(in cap notifier, in notify_flags_t flags); - /* Unsubscribe from events. */ + /* Unsubscribe from events. A notifier cannot be provided since it will be + considered distinct from any previously presented for subscription. */ - [opcode(24)] void unsubscribe(in cap notifier); + [opcode(24)] void unsubscribe(); };