1.1 --- a/libfsclient/lib/src/notifier.cc Fri Jul 09 00:15:29 2021 +0200
1.2 +++ b/libfsclient/lib/src/notifier.cc Fri Jul 09 23:52:49 2021 +0200
1.3 @@ -85,11 +85,15 @@
1.4 if (l4_is_invalid_cap(file->notifier))
1.5 return -L4_EINVAL;
1.6
1.7 - ipc_cap_free_um(file->notifier);
1.8 -
1.9 client_Notification notify(file->ref);
1.10
1.11 - return notify.unsubscribe();
1.12 + long err = notify.unsubscribe(file->notifier);
1.13 +
1.14 + if (err)
1.15 + return err;
1.16 +
1.17 + ipc_cap_free_um(file->notifier);
1.18 + return L4_EOK;
1.19 }
1.20
1.21 /* Handle a notification event for a file. Ideally, this would be invoked by the
2.1 --- a/libfsserver/include/fsserver/pipe_pager.h Fri Jul 09 00:15:29 2021 +0200
2.2 +++ b/libfsserver/include/fsserver/pipe_pager.h Fri Jul 09 23:52:49 2021 +0200
2.3 @@ -78,7 +78,7 @@
2.4
2.5 virtual long subscribe(l4_cap_idx_t notifier, notify_flags_t flags);
2.6
2.7 - virtual long unsubscribe();
2.8 + virtual long unsubscribe(l4_cap_idx_t notifier);
2.9 };
2.10
2.11 // vim: tabstop=4 expandtab shiftwidth=4
3.1 --- a/libfsserver/include/fsserver/pipe_paging.h Fri Jul 09 00:15:29 2021 +0200
3.2 +++ b/libfsserver/include/fsserver/pipe_paging.h Fri Jul 09 23:52:49 2021 +0200
3.3 @@ -21,6 +21,8 @@
3.4
3.5 #pragma once
3.6
3.7 +#include <set>
3.8 +
3.9 #include <fsserver/page_mapper.h>
3.10 #include <fsserver/pages.h>
3.11 #include <fsserver/pipe_accessor.h>
3.12 @@ -56,7 +58,7 @@
3.13
3.14 /* Notification endpoints. */
3.15
3.16 - l4_cap_idx_t _notifiers[2];
3.17 + std::set<l4_cap_idx_t> _notifiers[2];
3.18 notify_flags_t _flags[2], _deferred[2];
3.19
3.20 /* Common functionality. */
3.21 @@ -77,7 +79,7 @@
3.22
3.23 virtual void subscribe(bool writing, l4_cap_idx_t notifier, notify_flags_t flags);
3.24
3.25 - virtual void unsubscribe(bool writing);
3.26 + virtual void unsubscribe(bool writing, l4_cap_idx_t notifier);
3.27
3.28 /* Region management. */
3.29
4.1 --- a/libfsserver/lib/pipes/pipe_pager.cc Fri Jul 09 00:15:29 2021 +0200
4.2 +++ b/libfsserver/lib/pipes/pipe_pager.cc Fri Jul 09 23:52:49 2021 +0200
4.3 @@ -174,9 +174,9 @@
4.4 return L4_EOK;
4.5 }
4.6
4.7 -long PipePager::unsubscribe()
4.8 +long PipePager::unsubscribe(l4_cap_idx_t notifier)
4.9 {
4.10 - _paging->unsubscribe(_writing);
4.11 + _paging->unsubscribe(_writing, notifier);
4.12 return L4_EOK;
4.13 }
4.14
5.1 --- a/libfsserver/lib/pipes/pipe_paging.cc Fri Jul 09 00:15:29 2021 +0200
5.2 +++ b/libfsserver/lib/pipes/pipe_paging.cc Fri Jul 09 23:52:49 2021 +0200
5.3 @@ -47,7 +47,6 @@
5.4
5.5 for (unsigned int i = 0; i < 2; i++)
5.6 {
5.7 - _notifiers[i] = L4_INVALID_CAP;
5.8 _flags[i] = 0;
5.9 _deferred[i] = 0;
5.10 }
5.11 @@ -59,10 +58,7 @@
5.12 {
5.13 int i = writing ? 1 : 0;
5.14
5.15 - if (l4_is_valid_cap(_notifiers[i]))
5.16 - unsubscribe(writing);
5.17 -
5.18 - _notifiers[i] = notifier;
5.19 + _notifiers[i].insert(notifier);
5.20 _flags[i] = flags;
5.21
5.22 /* Send deferred conditions on behalf of the other endpoint held before
5.23 @@ -77,16 +73,17 @@
5.24
5.25 /* Unsubscribe from an endpoint's notifications. */
5.26
5.27 -void PipePaging::unsubscribe(bool writing)
5.28 +void PipePaging::unsubscribe(bool writing, l4_cap_idx_t notifier)
5.29 {
5.30 int i = writing ? 1 : 0;
5.31 + std::set<l4_cap_idx_t>::iterator it = _notifiers[i].find(notifier);
5.32
5.33 - if (l4_is_valid_cap(_notifiers[i]))
5.34 + if (it != _notifiers[i].end())
5.35 {
5.36 - ipc_cap_free_um(_notifiers[i]);
5.37 - _notifiers[i] = L4_INVALID_CAP;
5.38 + _notifiers[i].erase(it);
5.39 _flags[i] = 0;
5.40 _deferred[i] = 0;
5.41 + ipc_cap_free_um(notifier);
5.42 }
5.43 }
5.44
5.45 @@ -101,13 +98,18 @@
5.46 /* Notify the other endpoint or hold any notification for potential future
5.47 subscription. */
5.48
5.49 - if (l4_is_valid_cap(_notifiers[i]))
5.50 + if (!_notifiers[i].empty())
5.51 {
5.52 if (flags & _flags[i])
5.53 {
5.54 - client_Notifier notifier(_notifiers[i]);
5.55 + std::set<l4_cap_idx_t>::iterator it;
5.56
5.57 - notifier.notify(flags & _flags[i]);
5.58 + for (it = _notifiers[i].begin(); it != _notifiers[i].end(); it++)
5.59 + {
5.60 + client_Notifier notifier(*it);
5.61 +
5.62 + notifier.notify(flags & _flags[i]);
5.63 + }
5.64 }
5.65 }
5.66 else
5.67 @@ -156,11 +158,12 @@
5.68
5.69 for (unsigned int i = 0; i < 2; i++)
5.70 {
5.71 - if (l4_is_valid_cap(_notifiers[i]))
5.72 - {
5.73 - ipc_cap_free_um(_notifiers[i]);
5.74 - _notifiers[i] = L4_INVALID_CAP;
5.75 - }
5.76 + std::set<l4_cap_idx_t>::iterator it;
5.77 +
5.78 + for (it = _notifiers[i].begin(); it != _notifiers[i].end(); it++)
5.79 + ipc_cap_free_um(*it);
5.80 +
5.81 + _notifiers[i].clear();
5.82 }
5.83
5.84 /* Delete the page collection and related objects. */