15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/audio/scoped_task_runner_observer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ScopedTaskRunnerObserver::ScopedTaskRunnerObserver(
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : task_runner_(task_runner) {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObserveLoopDestruction(true, NULL);
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ScopedTaskRunnerObserver::~ScopedTaskRunnerObserver() {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObserveLoopDestruction(false, NULL);
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ScopedTaskRunnerObserver::ObserveLoopDestruction(
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool enable,
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::WaitableEvent* done) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: |done| may be NULL.
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (task_runner_->BelongsToCurrentThread()) {
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::MessageLoop* loop = base::MessageLoop::current();
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (enable) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      loop->AddDestructionObserver(this);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      loop->RemoveDestructionObserver(this);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::WaitableEvent event(false, false);
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (task_runner_->PostTask(FROM_HERE,
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            base::Bind(&ScopedTaskRunnerObserver::ObserveLoopDestruction,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       base::Unretained(this), enable, &event))) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event.Wait();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The message loop's thread has already terminated, so no need to wait.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (done)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    done->Signal();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media.
49