1.1 --- a/libfsclient/lib/src/notifier.cc Wed Jul 07 00:28:19 2021 +0200
1.2 +++ b/libfsclient/lib/src/notifier.cc Fri Jul 09 00:15:29 2021 +0200
1.3 @@ -100,10 +100,18 @@
1.4 {
1.5 std::unique_lock<std::mutex> guard(_lock);
1.6
1.7 - /* Record the flags for the file object. */
1.8 + /* Record the flags for the file object. Where no flags are already recorded,
1.9 + the new flags will be recorded and the file object queued. Otherwise, the
1.10 + new flags will be combined with the recorded flags. */
1.11 +
1.12 + notify_flags_t recorded = _affected_flags[file];
1.13
1.14 - _affected_flags[file] = _affected_flags[file] | flags;
1.15 - _affected.push_back(file);
1.16 + _affected_flags[file] = recorded | flags;
1.17 +
1.18 + /* Add a file queue entry for any files without recorded notifications. */
1.19 +
1.20 + if (!recorded)
1.21 + _affected.push_back(file);
1.22
1.23 /* Notify any waiting caller. */
1.24
1.25 @@ -195,17 +203,53 @@
1.26
1.27 while (1)
1.28 {
1.29 - if (!_affected.empty())
1.30 + /* Obtain queued files until one is found that still has events recorded
1.31 + for it. (Waiting for events specific to one file will remove recorded
1.32 + events but not any file queue entries.) */
1.33 +
1.34 + while (!_affected.empty())
1.35 {
1.36 *file = _affected.front();
1.37 _affected.pop_front();
1.38
1.39 - (*file)->notifications = _affected_flags[*file];
1.40 - _affected_flags.erase(*file);
1.41 + notify_flags_t recorded = _affected_flags[*file];
1.42 +
1.43 + if (recorded)
1.44 + {
1.45 + (*file)->notifications = recorded;
1.46 + _affected_flags.erase(*file);
1.47 + return L4_EOK;
1.48 + }
1.49 + }
1.50 +
1.51 + /* No queued events. */
1.52 +
1.53 + _notified.wait(guard);
1.54 + }
1.55 +
1.56 + return L4_EOK;
1.57 +}
1.58 +
1.59 +/* Wait for notifications from a single file. */
1.60 +
1.61 +long FileNotifier::wait_file(file_t *file)
1.62 +{
1.63 + std::unique_lock<std::mutex> guard(_lock);
1.64 +
1.65 + while (1)
1.66 + {
1.67 + notify_flags_t recorded = _affected_flags[file];
1.68 +
1.69 + if (recorded)
1.70 + {
1.71 + file->notifications = recorded;
1.72 + _affected_flags.erase(file);
1.73 return L4_EOK;
1.74 }
1.75 - else
1.76 - _notified.wait(guard);
1.77 +
1.78 + /* No recorded events for the file. */
1.79 +
1.80 + _notified.wait(guard);
1.81 }
1.82
1.83 return L4_EOK;