// Copyright (c) 2011 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 "remoting/base/scoped_thread_proxy.h" #include "base/bind.h" namespace remoting { class ScopedThreadProxy::Core : public base::RefCountedThreadSafe { public: Core(base::MessageLoopProxy* message_loop) : message_loop_(message_loop), canceled_(false) { } void PostTask(const tracked_objects::Location& from_here, const base::Closure& closure) { if (!canceled_) message_loop_->PostTask(from_here, Wrap(closure)); } void PostDelayedTask( const tracked_objects::Location& from_here, const base::Closure& closure, int64 delay_ms) { if (!canceled_) { message_loop_->PostDelayedTask(from_here, Wrap(closure), delay_ms); } } void Detach() { DCHECK(message_loop_->BelongsToCurrentThread()); canceled_ = true; } private: friend class base::RefCountedThreadSafe; ~Core() { DCHECK(canceled_); } base::Closure Wrap(const base::Closure& closure) { return base::Bind(&Core::CallClosure, this, closure); } void CallClosure(const base::Closure& closure) { DCHECK(message_loop_->BelongsToCurrentThread()); if (!canceled_) closure.Run(); } scoped_refptr message_loop_; bool canceled_; DISALLOW_COPY_AND_ASSIGN(Core); }; ScopedThreadProxy::ScopedThreadProxy(base::MessageLoopProxy* message_loop) : core_(new Core(message_loop)) { } ScopedThreadProxy::~ScopedThreadProxy() { Detach(); } void ScopedThreadProxy::PostTask(const tracked_objects::Location& from_here, const base::Closure& closure) { core_->PostTask(from_here, closure); } void ScopedThreadProxy::PostDelayedTask( const tracked_objects::Location& from_here, const base::Closure& closure, int64 delay_ms) { core_->PostDelayedTask(from_here, closure, delay_ms); } void ScopedThreadProxy::Detach() { core_->Detach(); } } // namespace remoting