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_PUBLIC_CPP_BINDINGS_SYNC_HANDLE_WATCHER_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_SYNC_HANDLE_WATCHER_H_ 7 8 #include "base/macros.h" 9 #include "base/memory/ref_counted.h" 10 #include "base/threading/thread_checker.h" 11 #include "mojo/public/cpp/bindings/sync_handle_registry.h" 12 #include "mojo/public/cpp/system/core.h" 13 14 namespace mojo { 15 16 // SyncHandleWatcher supports watching a handle synchronously. It also supports 17 // registering the handle with a thread-local storage (SyncHandleRegistry), so 18 // that when other SyncHandleWatcher instances on the same thread perform sync 19 // handle watching, this handle will be watched together. 20 // 21 // SyncHandleWatcher is used for sync methods. While a sync call is waiting for 22 // response, we would like to block the thread. On the other hand, we need 23 // incoming sync method requests on the same thread to be able to reenter. We 24 // also need master interface endpoints to continue dispatching messages for 25 // associated endpoints on different threads. 26 // 27 // This class is not thread safe. 28 class SyncHandleWatcher { 29 public: 30 // Note: |handle| must outlive this object. 31 SyncHandleWatcher(const Handle& handle, 32 MojoHandleSignals handle_signals, 33 const SyncHandleRegistry::HandleCallback& callback); 34 35 ~SyncHandleWatcher(); 36 37 // Registers |handle_| with SyncHandleRegistry, so that when others perform 38 // sync handle watching on the same thread, |handle_| will be watched 39 // together. 40 void AllowWokenUpBySyncWatchOnSameThread(); 41 42 // Waits on |handle_| plus all handles registered with SyncHandleRegistry and 43 // runs callbacks synchronously for those ready handles. 44 // This method: 45 // - returns true when |should_stop| is set to true; 46 // - return false when any error occurs, including this object being 47 // destroyed during a callback. 48 bool SyncWatch(const bool* should_stop); 49 50 private: 51 void IncrementRegisterCount(); 52 void DecrementRegisterCount(); 53 54 const Handle handle_; 55 const MojoHandleSignals handle_signals_; 56 SyncHandleRegistry::HandleCallback callback_; 57 58 // Whether |handle_| has been registered with SyncHandleRegistry. 59 bool registered_; 60 // If non-zero, |handle_| should be registered with SyncHandleRegistry. 61 size_t register_request_count_; 62 63 scoped_refptr<SyncHandleRegistry> registry_; 64 65 scoped_refptr<base::RefCountedData<bool>> destroyed_; 66 67 base::ThreadChecker thread_checker_; 68 69 DISALLOW_COPY_AND_ASSIGN(SyncHandleWatcher); 70 }; 71 72 } // namespace mojo 73 74 #endif // MOJO_PUBLIC_CPP_BINDINGS_SYNC_HANDLE_WATCHER_H_ 75