15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* -*- c++ -*- */
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2011 The Chromium Authors. All rights reserved.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * found in the LICENSE file.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// EXAMPLE USAGE
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class PluginReverseInterface {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  public:
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   PluginReverseInterface(...) : anchor_(new nacl::WeakRefAnchor);
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   ~PluginReverseInterface() { anchor_->Abandon(); }
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void Log(nacl::string message) {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     LogContinuation* continuation = new LogContinuation(message);
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     plugin::WeakRefCallOnMainThread(anchor_, 0 /* ms delay */,
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                     this, &PluginReverseInterface::Log_cont,
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                     continuation);
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void Log_cont(LogContinuation* cont, int32_t result) {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     plugin_->browser_interface()->AddToConsole(plugin_->instance_id(),
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                                cont->message);
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     delete cont;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  private:
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   nacl::WeakRefAnchor* anchor_;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// }
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NATIVE_CLIENT_SRC_TRUSTED_WEAK_REF_CALL_ON_MAIN_THREAD_H_
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NATIVE_CLIENT_SRC_TRUSTED_WEAK_REF_CALL_ON_MAIN_THREAD_H_
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/trusted/weak_ref/weak_ref.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/include/nacl_scoped_ptr.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/include/nacl_compiler_annotations.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/include/portability.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h"  // for PP_OK
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/completion_callback.h"  // for pp::CompletionCallback
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/core.h"  // for pp::
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h"  // for pp::Module
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace plugin {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A typesafe utility to schedule a completion callback using weak
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// references.  The callback function callback_fn is invoked
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// regardless of whether the anchor has been abandoned, since
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// callback_fn takes a WeakRef<R>* as argument.  The intention is that
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// such callbacks, even deprived of any of its arguments (which has
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// been deleted), may wish to do some cleanup / log a message.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char const* const kPpWeakRefModuleName = "pp_weak_ref";
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename R> pp::CompletionCallback WeakRefNewCallback(
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nacl::WeakRefAnchor* anchor,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void callback_fn(nacl::WeakRef<R>* weak_data, int32_t err),
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    R* raw_data) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nacl::WeakRef<R>* wp = anchor->MakeWeakRef<R>(raw_data);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(bsy): explore using another template to eliminate the
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // following cast, making things completely typesafe.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::CompletionCallback cc_nrvo(
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<void (*)(void*, int32_t)>(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          callback_fn),
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<void*>(wp));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cc_nrvo;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename R> void WeakRefCallOnMainThread(
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nacl::WeakRefAnchor* anchor,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t delay_in_milliseconds,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void callback_fn(nacl::WeakRef<R>* weak_data, int32_t err),
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    R* raw_data) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::CompletionCallback cc =
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WeakRefNewCallback(anchor, callback_fn, raw_data, &cc);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::Module::Get()->core()->CallOnMainThread(
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delay_in_milliseconds,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cc,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PP_OK);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename R> class WeakRefAutoAbandonWrapper {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WeakRefAutoAbandonWrapper(void (*callback_fn)(R* raw_data,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                int32_t err),
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            R* raw_data)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : orig_callback_fn(callback_fn),
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        orig_data(raw_data) {}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void (*orig_callback_fn)(R* raw_data, int32_t err);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nacl::scoped_ptr<R> orig_data;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * It would be nice if the function had the right type signature,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * i.e., void WeakRefAutoAbandoner(void *wr_data, int32_t) but then
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the formal argument list would not use the typename template
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * argument R, making template resolution impossible.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename R> void WeakRefAutoAbandoner(
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nacl::WeakRef<WeakRefAutoAbandonWrapper<R> >* wr,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t err) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nacl::scoped_ptr<WeakRefAutoAbandonWrapper<R> > p;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wr->ReleaseAndUnref(&p);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (p == NULL) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NaClLog2(kPpWeakRefModuleName, 4,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WeakRefAutoAbandoner: weak ref NULL, anchor was abandoned\n");
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NaClLog2(kPpWeakRefModuleName, 4,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           "WeakRefAutoAbandoner: weak ref okay, invoking callback\n");
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*p->orig_callback_fn)(p->orig_data.get(), err);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A typesafe utility to schedule a completion callback using weak
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// references.  The callback function raw_callback_fn takes an R* as
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// argument, and is not invoked if the anchor has been abandoned.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename R> pp::CompletionCallback WeakRefNewCallback(
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nacl::WeakRefAnchor* anchor,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void (*raw_callback_fn)(R* raw_data, int32_t err),
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    R* raw_data) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WeakRefAutoAbandonWrapper<R>* wref_auto_wrapper =
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new WeakRefAutoAbandonWrapper<R>(raw_callback_fn, raw_data);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(wref_auto_wrapper != NULL);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nacl::WeakRef<WeakRefAutoAbandonWrapper<R> >* wp =
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      anchor->MakeWeakRef<WeakRefAutoAbandonWrapper<R> >(
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          wref_auto_wrapper);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void (*weak_ref_auto_abandoner_ptr)(
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      nacl::WeakRef<WeakRefAutoAbandonWrapper<R> >* wr,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int32_t err) = WeakRefAutoAbandoner<R>;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(bsy): see above
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::CompletionCallback cc_nrvo(
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<void (*)(void*, int32_t)>(weak_ref_auto_abandoner_ptr),
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<void*>(wp));
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return cc_nrvo;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename R> void WeakRefCallOnMainThread(
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nacl::WeakRefAnchor* anchor,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t delay_in_milliseconds,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void raw_callback_fn(R* raw_data, int32_t err),
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    R* raw_data) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::CompletionCallback cc =
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WeakRefNewCallback(anchor, raw_callback_fn, raw_data, &cc);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::Module::Get()->core()->CallOnMainThread(
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delay_in_milliseconds,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cc,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PP_OK);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename R, typename E>
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WeakRefMemberFuncBinder {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WeakRefMemberFuncBinder(E* object,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          void (E::*raw_callback_fn)(R* raw_data,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     int32_t err),
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          R* raw_data)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : object_(object),
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        raw_callback_fn_(raw_callback_fn),
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        data_(raw_data) {}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Invoke(int32_t err) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NaClLog2(kPpWeakRefModuleName, 4,
168bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch             ("WeakRefMemberFuncBinder: Invoke obj 0x%" NACL_PRIxPTR
169bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch              ", err%" NACL_PRId32 "\n"),
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             reinterpret_cast<uintptr_t>(object_), err);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (object_->*raw_callback_fn_)(data_.get(), err);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NaClLog2(kPpWeakRefModuleName, 4,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WeakRefMemberFuncBinder: done\n");
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  E* object_;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void (E::*raw_callback_fn_)(R* raw_data, int32_t err);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nacl::scoped_ptr<R> data_;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename R, typename E>
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WeakRefMemberFuncInvoker(
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WeakRefMemberFuncBinder<R, E> *binder, int32_t err) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NaClLog2(kPpWeakRefModuleName, 4,
185bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch           "WeakRefMemberFuncInvoker: %" NACL_PRIxPTR " %" NACL_PRId32 "\n",
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           (uintptr_t) binder,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           err);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  binder->Invoke(err);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // delete binder not needed, since WeakRefAutoAbandoner holds binder
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in a scoped_ptr and will automatically delete on scope exit.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A typesafe utility to schedule a completion callback using weak
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// references, where the callback function is a member function.  The
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// member function must take only a raw argument data pointer and a
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// completion status as formal parameters.  The lifetime of the
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |object| and |raw_callback_fn| must be at least that of |anchor|.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Typically |object| is just the object that controls the |anchor|,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// though it may be some sub-object that is contained within the
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// actual controlling object.  If the |anchor| is abandoned, the
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |raw_data| argument is deleted and the |raw_callback_fn| will not
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be invoked.
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename R, typename E>
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)pp::CompletionCallback WeakRefNewCallback(
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nacl::WeakRefAnchor* anchor,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    E* object,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void (E::*raw_callback_fn)(R* raw_data, int32_t err),
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    R* raw_data) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NaClLog2(kPpWeakRefModuleName, 4,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           "Entered WeakRefNewCallback\n");
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NaClLog2(kPpWeakRefModuleName, 4,
213bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch           "object 0x%" NACL_PRIxPTR "\n",
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           reinterpret_cast<uintptr_t>(object));
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WeakRefMemberFuncBinder<R, E>* binder =
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new WeakRefMemberFuncBinder<R, E>(object,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        raw_callback_fn,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        raw_data);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(binder != NULL);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NaClLog2(kPpWeakRefModuleName, 4,
221bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch           "WeakRefNewCallback: binder %" NACL_PRIxPTR "\n",
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           (uintptr_t) binder);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void (*weak_ref_member_func_invoker_ptr)(
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WeakRefMemberFuncBinder<R, E>* binder,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int32_t err) = WeakRefMemberFuncInvoker<R, E>;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return WeakRefNewCallback(anchor, weak_ref_member_func_invoker_ptr,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             binder);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename R, typename E> void WeakRefCallOnMainThread(
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nacl::WeakRefAnchor* anchor,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t delay_in_milliseconds,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    E* object,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void (E::*raw_callback_fn)(R* raw_data, int32_t err),
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    R* raw_data) {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NaClLog2(kPpWeakRefModuleName, 4,
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           "Entered WeakRefCallOnMainThread\n");
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::CompletionCallback cc =
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WeakRefNewCallback(anchor, object, raw_callback_fn, raw_data);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NaClLog2(kPpWeakRefModuleName, 4,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           "WeakRefCallOnMainThread: got cc\n");
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::Module::Get()->core()->CallOnMainThread(
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delay_in_milliseconds,
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cc,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PP_OK);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NaClLog2(kPpWeakRefModuleName, 4,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           "WeakRefCallOnMainThread: invoked PP_CallOnMainThread\n");
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace plugin
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
253