watcher_dispatcher.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright 2017 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. #ifndef MOJO_CORE_WATCHER_DISPATCHER_H_
  5. #define MOJO_CORE_WATCHER_DISPATCHER_H_
  6. #include <stdint.h>
  7. #include <set>
  8. #include "base/containers/flat_map.h"
  9. #include "base/memory/ref_counted.h"
  10. #include "base/synchronization/lock.h"
  11. #include "mojo/core/dispatcher.h"
  12. #include "mojo/core/handle_signals_state.h"
  13. #include "mojo/core/system_impl_export.h"
  14. #include "mojo/public/c/system/trap.h"
  15. namespace mojo {
  16. namespace core {
  17. class Watch;
  18. // The dispatcher type which backs watcher handles.
  19. class WatcherDispatcher : public Dispatcher {
  20. public:
  21. // Constructs a new WatcherDispatcher which invokes |handler| when a
  22. // registered watch observes some relevant state change.
  23. explicit WatcherDispatcher(MojoTrapEventHandler handler);
  24. WatcherDispatcher(const WatcherDispatcher&) = delete;
  25. WatcherDispatcher& operator=(const WatcherDispatcher&) = delete;
  26. // Methods used by watched dispatchers to notify watchers of events.
  27. void NotifyHandleState(Dispatcher* dispatcher,
  28. const HandleSignalsState& state);
  29. void NotifyHandleClosed(Dispatcher* dispatcher);
  30. // Method used by RequestContext (indirectly, via Watch) to complete
  31. // notification operations from a safe stack frame to avoid reentrancy.
  32. void InvokeWatchCallback(uintptr_t context,
  33. MojoResult result,
  34. const HandleSignalsState& state,
  35. MojoTrapEventFlags flags);
  36. // Dispatcher:
  37. Type GetType() const override;
  38. MojoResult Close() override;
  39. MojoResult WatchDispatcher(scoped_refptr<Dispatcher> dispatcher,
  40. MojoHandleSignals signals,
  41. MojoTriggerCondition condition,
  42. uintptr_t context) override;
  43. MojoResult CancelWatch(uintptr_t context) override;
  44. MojoResult Arm(uint32_t* num_blocking_events,
  45. MojoTrapEvent* blocking_events) override;
  46. private:
  47. friend class Watch;
  48. using WatchSet = std::set<const Watch*>;
  49. ~WatcherDispatcher() override;
  50. const MojoTrapEventHandler handler_;
  51. // Guards access to the fields below.
  52. //
  53. // NOTE: This may be acquired while holding another dispatcher's lock, as
  54. // watched dispatchers call into WatcherDispatcher methods which lock this
  55. // when issuing state change notifications. WatcherDispatcher must therefore
  56. // take caution to NEVER acquire other dispatcher locks while this is held.
  57. base::Lock lock_;
  58. bool armed_ = false;
  59. bool closed_ = false;
  60. // A mapping from context to Watch.
  61. base::flat_map<uintptr_t, scoped_refptr<Watch>> watches_;
  62. // A mapping from watched dispatcher to Watch.
  63. base::flat_map<Dispatcher*, scoped_refptr<Watch>> watched_handles_;
  64. // The set of all Watch instances which are currently ready to signal. This is
  65. // used for efficient arming behavior, as it allows for O(1) discovery of
  66. // whether or not arming can succeed and quick determination of who's
  67. // responsible if it can't.
  68. WatchSet ready_watches_;
  69. // Tracks the last Watch whose state was returned by Arm(). This is used to
  70. // ensure consistent round-robin behavior in the event that multiple Watches
  71. // remain ready over the span of several Arm() attempts.
  72. //
  73. // NOTE: This can point toward a deleted Watch, so it must never be
  74. // dereferenced. This is only used to do arithmetical comparisons in the
  75. // |ready_watches_| set, so it is represented by a uintptr_t. Using a raw_ptr
  76. // would force the allocator to quarantine the allocation and delay its reuse.
  77. uintptr_t last_watch_to_block_arming_ = 0;
  78. };
  79. } // namespace core
  80. } // namespace mojo
  81. #endif // MOJO_CORE_WATCHER_DISPATCHER_H_