// Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/synchronization/waitable_event_watcher.h" #include <utility> #include "base/check.h" #include "base/functional/bind.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" namespace base { // ----------------------------------------------------------------------------- // WaitableEventWatcher (async waits). // // The basic design is that we add an AsyncWaiter to the wait-list of the event. // That AsyncWaiter has a pointer to SequencedTaskRunner, and a Task to be // posted to it. The task ends up calling the callback when it runs on the // sequence. // // Since the wait can be canceled, we have a thread-safe Flag object which is // set when the wait has been canceled. At each stage in the above, we check the // flag before going onto the next stage. Since the wait may only be canceled in // the sequence which runs the Task, we are assured that the callback cannot be // called after canceling... // ----------------------------------------------------------------------------- // A thread-safe, reference-counted, write-once flag. // ----------------------------------------------------------------------------- class Flag : public RefCountedThreadSafe<Flag> { … }; // ----------------------------------------------------------------------------- // This is an asynchronous waiter which posts a task to a SequencedTaskRunner // when fired. An AsyncWaiter may only be in a single wait-list. // ----------------------------------------------------------------------------- class AsyncWaiter : public WaitableEvent::Waiter { … }; // ----------------------------------------------------------------------------- // For async waits we need to run a callback on a sequence. We do this by // posting an AsyncCallbackHelper task, which calls the callback and keeps track // of when the event is canceled. // ----------------------------------------------------------------------------- void AsyncCallbackHelper(Flag* flag, WaitableEventWatcher::EventCallback callback, WaitableEvent* event) { … } WaitableEventWatcher::WaitableEventWatcher() { … } WaitableEventWatcher::~WaitableEventWatcher() { … } // ----------------------------------------------------------------------------- // The Handle is how the user cancels a wait. After deleting the Handle we // insure that the delegate cannot be called. // ----------------------------------------------------------------------------- bool WaitableEventWatcher::StartWatching( WaitableEvent* event, EventCallback callback, scoped_refptr<SequencedTaskRunner> task_runner) { … } void WaitableEventWatcher::StopWatching() { … } } // namespace base