Home | History | Annotate | Download | only in lib
      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(thread_checker_.CalledOnValidThread());
     25   if (registered_)
     26     registry_->UnregisterHandle(handle_);
     27 
     28   destroyed_->data = true;
     29 }
     30 
     31 void SyncHandleWatcher::AllowWokenUpBySyncWatchOnSameThread() {
     32   DCHECK(thread_checker_.CalledOnValidThread());
     33   IncrementRegisterCount();
     34 }
     35 
     36 bool SyncHandleWatcher::SyncWatch(const bool* should_stop) {
     37   DCHECK(thread_checker_.CalledOnValidThread());
     38   IncrementRegisterCount();
     39   if (!registered_) {
     40     DecrementRegisterCount();
     41     return false;
     42   }
     43 
     44   // This object may be destroyed during the WatchAllHandles() call. So we have
     45   // to preserve the boolean that WatchAllHandles uses.
     46   auto destroyed = destroyed_;
     47   const bool* should_stop_array[] = {should_stop, &destroyed->data};
     48   bool result = registry_->WatchAllHandles(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