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 #include "mojo/public/cpp/bindings/sync_handle_watcher.h" 6 7 #include "base/logging.h" 8 9 namespace mojo { 10 11 SyncHandleWatcher::SyncHandleWatcher( 12 const Handle& handle, 13 MojoHandleSignals handle_signals, 14 const SyncHandleRegistry::HandleCallback& callback) 15 : handle_(handle), 16 handle_signals_(handle_signals), 17 callback_(callback), 18 registered_(false), 19 register_request_count_(0), 20 registry_(SyncHandleRegistry::current()), 21 destroyed_(new base::RefCountedData<bool>(false)) {} 22 23 SyncHandleWatcher::~SyncHandleWatcher() { 24 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 25 if (registered_) 26 registry_->UnregisterHandle(handle_); 27 28 destroyed_->data = true; 29 } 30 31 void SyncHandleWatcher::AllowWokenUpBySyncWatchOnSameThread() { 32 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 33 IncrementRegisterCount(); 34 } 35 36 bool SyncHandleWatcher::SyncWatch(const bool* should_stop) { 37 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 38 IncrementRegisterCount(); 39 if (!registered_) { 40 DecrementRegisterCount(); 41 return false; 42 } 43 44 // This object may be destroyed during the Wait() call. So we have to preserve 45 // the boolean that Wait uses. 46 auto destroyed = destroyed_; 47 const bool* should_stop_array[] = {should_stop, &destroyed->data}; 48 bool result = registry_->Wait(should_stop_array, 2); 49 50 // This object has been destroyed. 51 if (destroyed->data) 52 return false; 53 54 DecrementRegisterCount(); 55 return result; 56 } 57 58 void SyncHandleWatcher::IncrementRegisterCount() { 59 register_request_count_++; 60 if (!registered_) { 61 registered_ = 62 registry_->RegisterHandle(handle_, handle_signals_, callback_); 63 } 64 } 65 66 void SyncHandleWatcher::DecrementRegisterCount() { 67 DCHECK_GT(register_request_count_, 0u); 68 69 register_request_count_--; 70 if (register_request_count_ == 0 && registered_) { 71 registry_->UnregisterHandle(handle_); 72 registered_ = false; 73 } 74 } 75 76 } // namespace mojo 77