ppb_flash_message_loop_impl.cc revision 58e6fbe4ee35d65e14b626c557d37565bf8ad179
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)
5bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/ppb_flash_message_loop_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::thunk::PPB_Flash_MessageLoop_API;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochnamespace content {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPB_Flash_MessageLoop_Impl::State
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public base::RefCounted<PPB_Flash_MessageLoop_Impl::State> {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State() : result_(PP_OK), run_called_(false), quit_called_(false) {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t result() const { return result_; }
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_result(int32_t result) { result_ = result; }
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool run_called() const { return run_called_; }
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_run_called() { run_called_ = true; }
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool quit_called() const { return quit_called_; }
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_quit_called() { quit_called_ = true; }
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const RunFromHostProxyCallback& run_callback() const { return run_callback_; }
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_run_callback(const RunFromHostProxyCallback& run_callback) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    run_callback_ = run_callback;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
36bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  friend class base::RefCounted<State>;
37bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  virtual ~State() {}
38bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t result_;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool run_called_;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool quit_called_;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunFromHostProxyCallback run_callback_;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Flash_MessageLoop_Impl::PPB_Flash_MessageLoop_Impl(PP_Instance instance)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Resource(::ppapi::OBJECT_IS_IMPL, instance),
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      state_(new State()) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Flash_MessageLoop_Impl::~PPB_Flash_MessageLoop_Impl() {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It is a no-op if either Run() hasn't been called or Quit() has been called
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to balance the call to Run().
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InternalQuit(PP_ERROR_ABORTED);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Resource PPB_Flash_MessageLoop_Impl::Create(PP_Instance instance) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (new PPB_Flash_MessageLoop_Impl(instance))->GetReference();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Flash_MessageLoop_API*
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PPB_Flash_MessageLoop_Impl::AsPPB_Flash_MessageLoop_API() {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PPB_Flash_MessageLoop_Impl::Run() {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return InternalRun(RunFromHostProxyCallback());
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_Flash_MessageLoop_Impl::RunFromHostProxy(
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const RunFromHostProxyCallback& callback) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InternalRun(callback);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_Flash_MessageLoop_Impl::Quit() {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InternalQuit(PP_OK);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PPB_Flash_MessageLoop_Impl::InternalRun(
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const RunFromHostProxyCallback& callback) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state_->run_called()) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!callback.is_null())
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(PP_ERROR_FAILED);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_FAILED;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state_->set_run_called();
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state_->set_run_callback(callback);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It is possible that the PPB_Flash_MessageLoop_Impl object has been
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // destroyed when the nested message loop exits.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<State> state_protector(state_);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::ScopedNestableTaskAllower allow(
94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        base::MessageLoop::current());
95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->Run();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't access data members of the class below.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return state_protector->result();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_Flash_MessageLoop_Impl::InternalQuit(int32_t result) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!state_->run_called() || state_->quit_called())
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state_->set_quit_called();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state_->set_result(result);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->QuitNow();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!state_->run_callback().is_null())
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state_->run_callback().Run(result);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch}  // namespace content
115