• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SyncHandleWatcher(const Handle & handle,MojoHandleSignals handle_signals,const SyncHandleRegistry::HandleCallback & callback)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 
~SyncHandleWatcher()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 
AllowWokenUpBySyncWatchOnSameThread()31 void SyncHandleWatcher::AllowWokenUpBySyncWatchOnSameThread() {
32   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
33   IncrementRegisterCount();
34 }
35 
SyncWatch(const bool * should_stop)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 
IncrementRegisterCount()58 void SyncHandleWatcher::IncrementRegisterCount() {
59   register_request_count_++;
60   if (!registered_) {
61     registered_ =
62         registry_->RegisterHandle(handle_, handle_signals_, callback_);
63   }
64 }
65 
DecrementRegisterCount()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