OLD | NEW |
(Empty) | |
| 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 |
| 5 #ifndef MOJO_EDK_SYSTEM_WATCHER_H_ |
| 6 #define MOJO_EDK_SYSTEM_WATCHER_H_ |
| 7 |
| 8 #include "base/callback.h" |
| 9 #include "base/macros.h" |
| 10 #include "base/memory/ref_counted.h" |
| 11 #include "base/synchronization/lock.h" |
| 12 #include "mojo/public/c/system/functions.h" |
| 13 #include "mojo/public/c/system/types.h" |
| 14 |
| 15 namespace mojo { |
| 16 namespace edk { |
| 17 |
| 18 struct HandleSignalsState; |
| 19 |
| 20 // This object corresponds to a watch added by a single call to |MojoWatch()|. |
| 21 // |
| 22 // An event may occur at any time which should trigger a Watcher to run its |
| 23 // callback, but the callback needs to be deferred until all EDK locks are |
| 24 // released. At the same time, a watch may be cancelled at any time by |
| 25 // |MojoCancelWatch()| and it is not OK for the callback to be invoked after |
| 26 // that happens. |
| 27 // |
| 28 // Therefore a Watcher needs to have some associated thread-safe state to track |
| 29 // its cancellation, which is why it's ref-counted. |
| 30 class Watcher : public base::RefCountedThreadSafe<Watcher> { |
| 31 public: |
| 32 using WatchCallback = |
| 33 base::Callback<void(MojoResult, const HandleSignalsState&)>; |
| 34 |
| 35 // Constructs a new Watcher which watches for |signals| to be satisfied on a |
| 36 // handle and which invokes |callback| either when one such signal is |
| 37 // satisfied, or all such signals become unsatisfiable. |
| 38 Watcher(MojoHandleSignals signals, const WatchCallback& callback); |
| 39 |
| 40 // Runs the Watcher's callback with the given arguments if it hasn't been |
| 41 // cancelled yet. |
| 42 void MaybeInvokeCallback(MojoResult result, const HandleSignalsState& state); |
| 43 |
| 44 // Notifies the Watcher of a state change. This may result in the Watcher |
| 45 // adding a finalizer to the current RequestContext to invoke its callback, |
| 46 // cancellation notwithstanding. |
| 47 void NotifyForStateChange(const HandleSignalsState& signals_state); |
| 48 |
| 49 // Notifies the Watcher of handle closure. This always results in the Watcher |
| 50 // adding a finalizer to the current RequestContext to invoke its callback, |
| 51 // cancellation notwithstanding. |
| 52 void NotifyClosed(); |
| 53 |
| 54 // Explicitly cancels the watch, guaranteeing that its callback will never be |
| 55 // be invoked again. |
| 56 void Cancel(); |
| 57 |
| 58 private: |
| 59 friend class base::RefCountedThreadSafe<Watcher>; |
| 60 |
| 61 ~Watcher(); |
| 62 |
| 63 // The set of signals which are watched by this Watcher. |
| 64 const MojoHandleSignals signals_; |
| 65 |
| 66 // The callback to invoke with a result and signal state any time signals in |
| 67 // |signals_| are satisfied or become permanently unsatisfiable. |
| 68 const WatchCallback callback_; |
| 69 |
| 70 // Guards |is_cancelled_|. |
| 71 base::Lock lock_; |
| 72 |
| 73 // Indicates whether the watch has been cancelled. A |Watcher| may exist for a |
| 74 // brief period of time after being cancelled if it's been attached as a |
| 75 // RequestContext finalizer. In such cases the callback must not be invoked, |
| 76 // hence this flag. |
| 77 bool is_cancelled_ = false; |
| 78 |
| 79 DISALLOW_COPY_AND_ASSIGN(Watcher); |
| 80 }; |
| 81 |
| 82 } // namespace edk |
| 83 } // namespace mojo |
| 84 |
| 85 #endif // MOJO_EDK_SYSTEM_WATCHER_H_ |
OLD | NEW |