OLD | NEW |
| (Empty) |
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_EDK_SYSTEM_WATCHER_DISPATCHER_H_ | |
6 #define MOJO_EDK_SYSTEM_WATCHER_DISPATCHER_H_ | |
7 | |
8 #include <map> | |
9 #include <set> | |
10 | |
11 #include "base/macros.h" | |
12 #include "base/memory/ref_counted.h" | |
13 #include "base/synchronization/lock.h" | |
14 #include "mojo/edk/system/dispatcher.h" | |
15 #include "mojo/edk/system/handle_signals_state.h" | |
16 #include "mojo/edk/system/system_impl_export.h" | |
17 #include "mojo/public/c/system/watcher.h" | |
18 | |
19 namespace mojo { | |
20 namespace edk { | |
21 | |
22 class Watch; | |
23 | |
24 // The dispatcher type which backs watcher handles. | |
25 class WatcherDispatcher : public Dispatcher { | |
26 public: | |
27 // Constructs a new WatcherDispatcher which invokes |callback| when a | |
28 // registered watch observes some relevant state change. | |
29 explicit WatcherDispatcher(MojoWatcherCallback callback); | |
30 | |
31 // Methods used by watched dispatchers to notify watchers of events. | |
32 void NotifyHandleState(Dispatcher* dispatcher, | |
33 const HandleSignalsState& state); | |
34 void NotifyHandleClosed(Dispatcher* dispatcher); | |
35 | |
36 // Method used by RequestContext (indirectly, via Watch) to complete | |
37 // notification operations from a safe stack frame to avoid reentrancy. | |
38 void InvokeWatchCallback(uintptr_t context, | |
39 MojoResult result, | |
40 const HandleSignalsState& state, | |
41 MojoWatcherNotificationFlags flags); | |
42 | |
43 // Dispatcher: | |
44 Type GetType() const override; | |
45 MojoResult Close() override; | |
46 MojoResult WatchDispatcher(scoped_refptr<Dispatcher> dispatcher, | |
47 MojoHandleSignals signals, | |
48 uintptr_t context) override; | |
49 MojoResult CancelWatch(uintptr_t context) override; | |
50 MojoResult Arm(uint32_t* num_ready_contexts, | |
51 uintptr_t* ready_contexts, | |
52 MojoResult* ready_results, | |
53 MojoHandleSignalsState* ready_signals_states) override; | |
54 | |
55 private: | |
56 friend class Watch; | |
57 | |
58 ~WatcherDispatcher() override; | |
59 | |
60 const MojoWatcherCallback callback_; | |
61 | |
62 // Guards access to the fields below. | |
63 // | |
64 // NOTE: This may be acquired while holding another dispatcher's lock, as | |
65 // watched dispatchers call into WatcherDispatcher methods which lock this | |
66 // when issuing state change notifications. WatcherDispatcher must therefore | |
67 // take caution to NEVER acquire other dispatcher locks while this is held. | |
68 base::Lock lock_; | |
69 | |
70 bool armed_ = false; | |
71 bool closed_ = false; | |
72 | |
73 // A mapping from context to Watch. | |
74 std::map<uintptr_t, scoped_refptr<Watch>> watches_; | |
75 | |
76 // A mapping from watched dispatcher to Watch. | |
77 std::map<Dispatcher*, scoped_refptr<Watch>> watched_handles_; | |
78 | |
79 // The set of all Watch instances which are currently ready to signal. This is | |
80 // used for efficient arming behavior, as it allows for O(1) discovery of | |
81 // whether or not arming can succeed and quick determination of who's | |
82 // responsible if it can't. | |
83 std::set<Watch*> ready_watches_; | |
84 | |
85 DISALLOW_COPY_AND_ASSIGN(WatcherDispatcher); | |
86 }; | |
87 | |
88 } // namespace edk | |
89 } // namespace mojo | |
90 | |
91 #endif // MOJO_EDK_SYSTEM_WATCHER_DISPATCHER_H_ | |
OLD | NEW |