scoped_task_runner_observer.cc 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. // Copyright (c) 2012 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. #include "media/audio/scoped_task_runner_observer.h"
  5. #include "base/bind.h"
  6. #include "base/synchronization/waitable_event.h"
  7. namespace media {
  8. ScopedTaskRunnerObserver::ScopedTaskRunnerObserver(
  9. const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
  10. : task_runner_(task_runner) {
  11. ObserveLoopDestruction(true, NULL);
  12. }
  13. ScopedTaskRunnerObserver::~ScopedTaskRunnerObserver() {
  14. ObserveLoopDestruction(false, NULL);
  15. }
  16. void ScopedTaskRunnerObserver::ObserveLoopDestruction(
  17. bool enable,
  18. base::WaitableEvent* done) {
  19. // Note: |done| may be NULL.
  20. if (task_runner_->BelongsToCurrentThread()) {
  21. base::CurrentThread loop = base::CurrentThread::Get();
  22. if (enable) {
  23. loop->AddDestructionObserver(this);
  24. } else {
  25. loop->RemoveDestructionObserver(this);
  26. }
  27. } else {
  28. base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
  29. base::WaitableEvent::InitialState::NOT_SIGNALED);
  30. if (task_runner_->PostTask(
  31. FROM_HERE,
  32. base::BindOnce(&ScopedTaskRunnerObserver::ObserveLoopDestruction,
  33. base::Unretained(this), enable, &event))) {
  34. event.Wait();
  35. } else {
  36. // The message loop's thread has already terminated, so no need to wait.
  37. }
  38. }
  39. if (done)
  40. done->Signal();
  41. }
  42. } // namespace media.