summaryrefslogtreecommitdiff
path: root/mojo/public/cpp/bindings/lib/sync_handle_watcher.cc
diff options
context:
space:
mode:
Diffstat (limited to 'mojo/public/cpp/bindings/lib/sync_handle_watcher.cc')
-rw-r--r--mojo/public/cpp/bindings/lib/sync_handle_watcher.cc76
1 files changed, 76 insertions, 0 deletions
diff --git a/mojo/public/cpp/bindings/lib/sync_handle_watcher.cc b/mojo/public/cpp/bindings/lib/sync_handle_watcher.cc
new file mode 100644
index 0000000000..f20af56b20
--- /dev/null
+++ b/mojo/public/cpp/bindings/lib/sync_handle_watcher.cc
@@ -0,0 +1,76 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/public/cpp/bindings/sync_handle_watcher.h"
+
+#include "base/logging.h"
+
+namespace mojo {
+
+SyncHandleWatcher::SyncHandleWatcher(
+ const Handle& handle,
+ MojoHandleSignals handle_signals,
+ const SyncHandleRegistry::HandleCallback& callback)
+ : handle_(handle),
+ handle_signals_(handle_signals),
+ callback_(callback),
+ registered_(false),
+ register_request_count_(0),
+ registry_(SyncHandleRegistry::current()),
+ destroyed_(new base::RefCountedData<bool>(false)) {}
+
+SyncHandleWatcher::~SyncHandleWatcher() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (registered_)
+ registry_->UnregisterHandle(handle_);
+
+ destroyed_->data = true;
+}
+
+void SyncHandleWatcher::AllowWokenUpBySyncWatchOnSameThread() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ IncrementRegisterCount();
+}
+
+bool SyncHandleWatcher::SyncWatch(const bool* should_stop) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ IncrementRegisterCount();
+ if (!registered_) {
+ DecrementRegisterCount();
+ return false;
+ }
+
+ // This object may be destroyed during the Wait() call. So we have to preserve
+ // the boolean that Wait uses.
+ auto destroyed = destroyed_;
+ const bool* should_stop_array[] = {should_stop, &destroyed->data};
+ bool result = registry_->Wait(should_stop_array, 2);
+
+ // This object has been destroyed.
+ if (destroyed->data)
+ return false;
+
+ DecrementRegisterCount();
+ return result;
+}
+
+void SyncHandleWatcher::IncrementRegisterCount() {
+ register_request_count_++;
+ if (!registered_) {
+ registered_ =
+ registry_->RegisterHandle(handle_, handle_signals_, callback_);
+ }
+}
+
+void SyncHandleWatcher::DecrementRegisterCount() {
+ DCHECK_GT(register_request_count_, 0u);
+
+ register_request_count_--;
+ if (register_request_count_ == 0 && registered_) {
+ registry_->UnregisterHandle(handle_);
+ registered_ = false;
+ }
+}
+
+} // namespace mojo