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_WATCH_H_ |
| 6 #define MOJO_EDK_SYSTEM_WATCH_H_ |
| 7 |
| 8 #include "base/macros.h" |
| 9 #include "base/memory/ref_counted.h" |
| 10 #include "base/synchronization/lock.h" |
| 11 #include "mojo/edk/system/atomic_flag.h" |
| 12 #include "mojo/edk/system/handle_signals_state.h" |
| 13 |
| 14 namespace mojo { |
| 15 namespace edk { |
| 16 |
| 17 class Dispatcher; |
| 18 class WatcherDispatcher; |
| 19 |
| 20 // Encapsulates the state associated with a single watch context within a |
| 21 // watcher. |
| 22 // |
| 23 // Every Watch has its own cancellation state, and is captured by RequestContext |
| 24 // notification finalizers to avoid redundant context resolution during |
| 25 // finalizer execution. |
| 26 class Watch : public base::RefCountedThreadSafe<Watch> { |
| 27 public: |
| 28 // Constructs a Watch which represents a watch within |watcher| associated |
| 29 // with |context|, watching |dispatcher| for |signals|. |
| 30 Watch(const scoped_refptr<WatcherDispatcher>& watcher, |
| 31 const scoped_refptr<Dispatcher>& dispatcher, |
| 32 uintptr_t context, |
| 33 MojoHandleSignals signals); |
| 34 |
| 35 // Notifies the Watch of a potential state change. |
| 36 // |
| 37 // If |allowed_to_call_callback| is true, this may add a notification |
| 38 // finalizer to the current RequestContext to invoke the watcher's callback |
| 39 // with this watch's context. See return values below. |
| 40 // |
| 41 // This is called directly by WatcherDispatcher on all relevant Watch |
| 42 // instances whenever the watched Dispatcher notifies the WatcherDispatcher of |
| 43 // a state change. |
| 44 // |
| 45 // Returns: |
| 46 // |MOJO_RESULT_OK| if the watch would notify given |state| on its handle, |
| 47 // regardless of whether it actually does notify here (see above.) If |
| 48 // |allowed_to_call_callback| is |true| this return value indicates that |
| 49 // a notification finalizer was added to the current RequestContext. |
| 50 // |MOJO_RESULT_FAILED_PRECONDITION| if the watch would notify of permanent |
| 51 // unsatisfiability given |state| on its handle, regardless of whether |
| 52 // it actually does notify here (see above.) If |
| 53 // |allowed_to_call_callback| is |true| this return value indicates that |
| 54 // a notification finalizer was added to the current RequestContext. |
| 55 // |MOJO_RESULT_SHOULD_WAIT| if the watch would not notify given |state| on |
| 56 // its handle. In this case, no notification finalizer is ever added to |
| 57 // the current RequestContext. |
| 58 MojoResult NotifyState(const HandleSignalsState& state, |
| 59 bool allowed_to_call_callback); |
| 60 |
| 61 // Notifies the watch of cancellation ASAP. This will always be the last |
| 62 // notification sent for the watch. |
| 63 void Cancel(); |
| 64 |
| 65 // Finalizer method for RequestContexts. This method is invoked once for every |
| 66 // notification finalizer added to a RequestContext by this object. This calls |
| 67 // down into the WatcherDispatcher to do the actual notification call. |
| 68 void InvokeCallback(MojoResult result, |
| 69 const HandleSignalsState& state, |
| 70 MojoWatcherNotificationFlags flags); |
| 71 |
| 72 const scoped_refptr<Dispatcher>& dispatcher() const { return dispatcher_; } |
| 73 |
| 74 private: |
| 75 friend class base::RefCountedThreadSafe<Watch>; |
| 76 |
| 77 ~Watch(); |
| 78 |
| 79 const scoped_refptr<WatcherDispatcher> watcher_; |
| 80 const scoped_refptr<Dispatcher> dispatcher_; |
| 81 const uintptr_t context_; |
| 82 const MojoHandleSignals signals_; |
| 83 |
| 84 // Guards |is_cancelled_| below and mutually excludes individual watch |
| 85 // notification executions for this same watch context. |
| 86 // |
| 87 // Note that this should only be acquired from a RequestContext finalizer to |
| 88 // ensure that no other internal locks are already held. |
| 89 base::Lock notification_lock_; |
| 90 |
| 91 // Guarded by |notification_lock_|. |
| 92 bool is_cancelled_ = false; |
| 93 |
| 94 DISALLOW_COPY_AND_ASSIGN(Watch); |
| 95 }; |
| 96 |
| 97 } // namespace edk |
| 98 } // namespace mojo |
| 99 |
| 100 #endif // MOJO_EDK_SYSTEM_WATCH_H_ |
OLD | NEW |