watcher_set.cc 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "mojo/core/watcher_set.h"
  5. #include <utility>
  6. namespace mojo {
  7. namespace core {
  8. WatcherSet::WatcherSet(Dispatcher* owner) : owner_(owner) {}
  9. WatcherSet::~WatcherSet() = default;
  10. void WatcherSet::NotifyState(const HandleSignalsState& state) {
  11. // Avoid notifying watchers if they have already seen this state.
  12. if (last_known_state_.has_value() && state.equals(last_known_state_.value()))
  13. return;
  14. last_known_state_ = state;
  15. for (const auto& entry : watchers_)
  16. entry.first->NotifyHandleState(owner_, state);
  17. }
  18. void WatcherSet::NotifyClosed() {
  19. for (const auto& entry : watchers_)
  20. entry.first->NotifyHandleClosed(owner_);
  21. }
  22. MojoResult WatcherSet::Add(const scoped_refptr<WatcherDispatcher>& watcher,
  23. uintptr_t context,
  24. const HandleSignalsState& current_state) {
  25. auto it = watchers_.find(watcher.get());
  26. if (it == watchers_.end()) {
  27. auto result =
  28. watchers_.insert(std::make_pair(watcher.get(), Entry{watcher}));
  29. it = result.first;
  30. }
  31. if (!it->second.contexts.insert(context).second)
  32. return MOJO_RESULT_ALREADY_EXISTS;
  33. if (last_known_state_.has_value() &&
  34. !current_state.equals(last_known_state_.value())) {
  35. // This new state may be relevant to everyone, in which case we just
  36. // notify everyone.
  37. NotifyState(current_state);
  38. } else {
  39. // Otherwise only notify the newly added Watcher.
  40. watcher->NotifyHandleState(owner_, current_state);
  41. }
  42. return MOJO_RESULT_OK;
  43. }
  44. MojoResult WatcherSet::Remove(WatcherDispatcher* watcher, uintptr_t context) {
  45. auto it = watchers_.find(watcher);
  46. if (it == watchers_.end())
  47. return MOJO_RESULT_NOT_FOUND;
  48. ContextSet& contexts = it->second.contexts;
  49. auto context_it = contexts.find(context);
  50. if (context_it == contexts.end())
  51. return MOJO_RESULT_NOT_FOUND;
  52. contexts.erase(context_it);
  53. if (contexts.empty())
  54. watchers_.erase(it);
  55. return MOJO_RESULT_OK;
  56. }
  57. WatcherSet::Entry::Entry(const scoped_refptr<WatcherDispatcher>& dispatcher)
  58. : dispatcher(dispatcher) {}
  59. WatcherSet::Entry::Entry(Entry&& other) = default;
  60. WatcherSet::Entry::~Entry() = default;
  61. WatcherSet::Entry& WatcherSet::Entry::operator=(Entry&& other) = default;
  62. } // namespace core
  63. } // namespace mojo