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