LCOV - code coverage report
Current view: directory - src/trusted/weak_ref - call_on_main_thread.h (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 41 0 0.0 %
Date: 2012-02-16 Functions: 0 0 -

       1                 : /* -*- c++ -*- */
       2                 : /*
       3                 :  * Copyright (c) 2011 The Native Client Authors. All rights reserved.
       4                 :  * Use of this source code is governed by a BSD-style license that can be
       5                 :  * found in the LICENSE file.
       6                 :  */
       7                 : 
       8                 : // EXAMPLE USAGE
       9                 : //
      10                 : // class PluginReverseInterface {
      11                 : //  public:
      12                 : //   PluginReverseInterface(...) : anchor_(new nacl::WeakRefAnchor);
      13                 : //   ~PluginReverseInterface() { anchor_->Abandon(); }
      14                 : //   void Log(nacl::string message) {
      15                 : //     LogContinuation* continuation = new LogContinuation(message);
      16                 : //     plugin::WeakRefCallOnMainThread(anchor_, 0 /* ms delay */,
      17                 : //                                     this, &PluginReverseInterface::Log_cont,
      18                 : //                                     continuation);
      19                 : //   }
      20                 : //   void Log_cont(LogContinuation* cont, int32_t result) {
      21                 : //     plugin_->browser_interface()->AddToConsole(plugin_->instance_id(),
      22                 : //                                                cont->message);
      23                 : //     delete cont;
      24                 : //   }
      25                 : //  private:
      26                 : //   nacl::WeakRefAnchor* anchor_;
      27                 : // }
      28                 : 
      29                 : #ifndef NATIVE_CLIENT_SRC_TRUSTED_WEAK_REF_CALL_ON_MAIN_THREAD_H_
      30                 : #define NATIVE_CLIENT_SRC_TRUSTED_WEAK_REF_CALL_ON_MAIN_THREAD_H_
      31                 : 
      32                 : #include "native_client/src/trusted/weak_ref/weak_ref.h"
      33                 : 
      34                 : #include "native_client/src/include/nacl_scoped_ptr.h"
      35                 : #include "native_client/src/include/nacl_compiler_annotations.h"
      36                 : #include "native_client/src/include/portability.h"
      37                 : 
      38                 : #include "ppapi/c/pp_errors.h"  // for PP_OK
      39                 : #include "ppapi/cpp/completion_callback.h"  // for pp::CompletionCallback
      40                 : #include "ppapi/cpp/core.h"  // for pp::
      41                 : #include "ppapi/cpp/module.h"  // for pp::Module
      42                 : 
      43                 : namespace plugin {
      44                 : 
      45                 : // A typesafe utility to schedule a completion callback using weak
      46                 : // references.  The callback function callback_fn is invoked
      47                 : // regardless of whether the anchor has been abandoned, since
      48                 : // callback_fn takes a WeakRef<R>* as argument.  The intention is that
      49                 : // such callbacks, even deprived of any of its arguments (which has
      50                 : // been deleted), may wish to do some cleanup / log a message.
      51                 : 
      52                 : static char const* const kPpWeakRefModuleName = "pp_weak_ref";
      53                 : 
      54                 : template <typename R> pp::CompletionCallback WeakRefNewCallback(
      55                 :     nacl::WeakRefAnchor* anchor,
      56                 :     void callback_fn(nacl::WeakRef<R>* weak_data, int32_t err),
      57                 :     R* raw_data) {
      58                 :   nacl::WeakRef<R>* wp = anchor->MakeWeakRef<R>(raw_data);
      59                 :   // TODO(bsy): explore using another template to eliminate the
      60                 :   // following cast, making things completely typesafe.
      61                 :   pp::CompletionCallback cc_nrvo(
      62                 :       reinterpret_cast<void (*)(void*, int32_t)>(
      63                 :           callback_fn),
      64                 :       reinterpret_cast<void*>(wp));
      65                 :   return cc_nrvo;
      66                 : }
      67                 : 
      68                 : template <typename R> void WeakRefCallOnMainThread(
      69                 :     nacl::WeakRefAnchor* anchor,
      70                 :     int32_t delay_in_milliseconds,
      71                 :     void callback_fn(nacl::WeakRef<R>* weak_data, int32_t err),
      72                 :     R* raw_data) {
      73                 :   pp::CompletionCallback cc =
      74                 :       WeakRefNewCallback(anchor, callback_fn, raw_data, &cc);
      75                 : 
      76                 :   pp::Module::Get()->core()->CallOnMainThread(
      77                 :       delay_in_milliseconds,
      78                 :       cc,
      79                 :       PP_OK);
      80                 : }
      81                 : 
      82               0 : template <typename R> class WeakRefAutoAbandonWrapper {
      83                 :  public:
      84                 :   WeakRefAutoAbandonWrapper(void (*callback_fn)(R* raw_data,
      85                 :                                                 int32_t err),
      86               0 :                             R* raw_data)
      87                 :       : orig_callback_fn(callback_fn),
      88               0 :         orig_data(raw_data) {}
      89                 : 
      90                 :   void (*orig_callback_fn)(R* raw_data, int32_t err);
      91                 :   nacl::scoped_ptr<R> orig_data;
      92                 : };
      93                 : 
      94                 : /*
      95                 :  * It would be nice if the function had the right type signature,
      96                 :  * i.e., void WeakRefAutoAbandoner(void *wr_data, int32_t) but then
      97                 :  * the formal argument list would not use the typename template
      98                 :  * argument R, making template resolution impossible.
      99                 :  */
     100                 : template <typename R> void WeakRefAutoAbandoner(
     101                 :     nacl::WeakRef<WeakRefAutoAbandonWrapper<R> >* wr,
     102               0 :     int32_t err) {
     103               0 :   nacl::scoped_ptr<WeakRefAutoAbandonWrapper<R> > p;
     104               0 :   wr->ReleaseAndUnref(&p);
     105               0 :   if (p == NULL) {
     106               0 :     NaClLog2(kPpWeakRefModuleName, 4,
     107                 :              "WeakRefAutoAbandoner: weak ref NULL, anchor was abandoned\n");
     108                 :     return;
     109                 :   }
     110               0 :   NaClLog2(kPpWeakRefModuleName, 4,
     111                 :            "WeakRefAutoAbandoner: weak ref okay, invoking callback\n");
     112               0 :   (*p->orig_callback_fn)(p->orig_data.get(), err);
     113               0 :   return;
     114                 : }
     115                 : 
     116                 : // A typesafe utility to schedule a completion callback using weak
     117                 : // references.  The callback function raw_callback_fn takes an R* as
     118                 : // argument, and is not invoked if the anchor has been abandoned.
     119                 : template <typename R> pp::CompletionCallback WeakRefNewCallback(
     120                 :     nacl::WeakRefAnchor* anchor,
     121                 :     void (*raw_callback_fn)(R* raw_data, int32_t err),
     122               0 :     R* raw_data) {
     123                 : 
     124                 :   WeakRefAutoAbandonWrapper<R>* wref_auto_wrapper =
     125               0 :       new WeakRefAutoAbandonWrapper<R>(raw_callback_fn, raw_data);
     126                 : 
     127               0 :   CHECK(wref_auto_wrapper != NULL);
     128                 : 
     129                 :   nacl::WeakRef<WeakRefAutoAbandonWrapper<R> >* wp =
     130                 :       anchor->MakeWeakRef<WeakRefAutoAbandonWrapper<R> >(
     131               0 :           wref_auto_wrapper);
     132                 :   void (*weak_ref_auto_abandoner_ptr)(
     133                 :       nacl::WeakRef<WeakRefAutoAbandonWrapper<R> >* wr,
     134               0 :       int32_t err) = WeakRefAutoAbandoner<R>;
     135                 :   // TODO(bsy): see above
     136                 :   pp::CompletionCallback cc_nrvo(
     137                 :       reinterpret_cast<void (*)(void*, int32_t)>(weak_ref_auto_abandoner_ptr),
     138               0 :       reinterpret_cast<void*>(wp));
     139                 :   return cc_nrvo;
     140                 : }
     141                 : 
     142                 : template <typename R> void WeakRefCallOnMainThread(
     143                 :     nacl::WeakRefAnchor* anchor,
     144                 :     int32_t delay_in_milliseconds,
     145                 :     void raw_callback_fn(R* raw_data, int32_t err),
     146                 :     R* raw_data) {
     147                 :   pp::CompletionCallback cc =
     148                 :       WeakRefNewCallback(anchor, raw_callback_fn, raw_data, &cc);
     149                 :   pp::Module::Get()->core()->CallOnMainThread(
     150                 :       delay_in_milliseconds,
     151                 :       cc,
     152                 :       PP_OK);
     153                 : }
     154                 : 
     155                 : 
     156                 : template <typename R, typename E>
     157               0 : class WeakRefMemberFuncBinder {
     158                 :  public:
     159                 :   WeakRefMemberFuncBinder(E* object,
     160                 :                           void (E::*raw_callback_fn)(R* raw_data,
     161                 :                                                      int32_t err),
     162               0 :                           R* raw_data)
     163                 :       : object_(object),
     164                 :         raw_callback_fn_(raw_callback_fn),
     165               0 :         data_(raw_data) {}
     166               0 :   void Invoke(int32_t err) {
     167               0 :     NaClLog2(kPpWeakRefModuleName, 4,
     168                 :              ("WeakRefMemberFuncBinder: Invoke obj 0x%"NACL_PRIxPTR
     169                 :               ", err%"NACL_PRId32"\n"),
     170                 :              reinterpret_cast<uintptr_t>(object_), err);
     171               0 :     (object_->*raw_callback_fn_)(data_.get(), err);
     172               0 :     NaClLog2(kPpWeakRefModuleName, 4,
     173                 :              "WeakRefMemberFuncBinder: done\n");
     174                 :   }
     175                 :  private:
     176                 :   E* object_;
     177                 :   void (E::*raw_callback_fn_)(R* raw_data, int32_t err);
     178                 :   nacl::scoped_ptr<R> data_;
     179                 : };
     180                 : 
     181                 : template <typename R, typename E>
     182                 : void WeakRefMemberFuncInvoker(
     183               0 :     WeakRefMemberFuncBinder<R, E> *binder, int32_t err) {
     184               0 :   NaClLog2(kPpWeakRefModuleName, 4,
     185                 :            "WeakRefMemberFuncInvoker: %"NACL_PRIxPTR" %"NACL_PRId32"\n",
     186                 :            (uintptr_t) binder,
     187                 :            err);
     188               0 :   binder->Invoke(err);
     189                 :   // delete binder not needed, since WeakRefAutoAbandoner holds binder
     190                 :   // in a scoped_ptr and will automatically delete on scope exit.
     191                 : }
     192                 : 
     193                 : 
     194                 : // A typesafe utility to schedule a completion callback using weak
     195                 : // references, where the callback function is a member function.  The
     196                 : // member function must take only a raw argument data pointer and a
     197                 : // completion status as formal parameters.  The lifetime of the
     198                 : // |object| and |raw_callback_fn| must be at least that of |anchor|.
     199                 : // Typically |object| is just the object that controls the |anchor|,
     200                 : // though it may be some sub-object that is contained within the
     201                 : // actual controlling object.  If the |anchor| is abandoned, the
     202                 : // |raw_data| argument is deleted and the |raw_callback_fn| will not
     203                 : // be invoked.
     204                 : template <typename R, typename E>
     205                 : pp::CompletionCallback WeakRefNewCallback(
     206                 :     nacl::WeakRefAnchor* anchor,
     207                 :     E* object,
     208                 :     void (E::*raw_callback_fn)(R* raw_data, int32_t err),
     209               0 :     R* raw_data) {
     210               0 :   NaClLog2(kPpWeakRefModuleName, 4,
     211                 :            "Entered WeakRefNewCallback\n");
     212               0 :   NaClLog2(kPpWeakRefModuleName, 4,
     213                 :            "object 0x%"NACL_PRIxPTR"\n",
     214                 :            reinterpret_cast<uintptr_t>(object));
     215                 :   WeakRefMemberFuncBinder<R, E>* binder =
     216                 :       new WeakRefMemberFuncBinder<R, E>(object,
     217                 :                                         raw_callback_fn,
     218               0 :                                         raw_data);
     219               0 :   CHECK(binder != NULL);
     220               0 :   NaClLog2(kPpWeakRefModuleName, 4,
     221                 :            "WeakRefNewCallback: binder %"NACL_PRIxPTR"\n",
     222                 :            (uintptr_t) binder);
     223                 :   void (*weak_ref_member_func_invoker_ptr)(
     224                 :       WeakRefMemberFuncBinder<R, E>* binder,
     225               0 :       int32_t err) = WeakRefMemberFuncInvoker<R, E>;
     226                 :   return WeakRefNewCallback(anchor, weak_ref_member_func_invoker_ptr,
     227               0 :                              binder);
     228                 : }
     229                 : 
     230                 : template <typename R, typename E> void WeakRefCallOnMainThread(
     231                 :     nacl::WeakRefAnchor* anchor,
     232                 :     int32_t delay_in_milliseconds,
     233                 :     E* object,
     234                 :     void (E::*raw_callback_fn)(R* raw_data, int32_t err),
     235               0 :     R* raw_data) {
     236               0 :   NaClLog2(kPpWeakRefModuleName, 4,
     237                 :            "Entered WeakRefCallOnMainThread\n");
     238                 :   pp::CompletionCallback cc =
     239               0 :       WeakRefNewCallback(anchor, object, raw_callback_fn, raw_data);
     240               0 :   NaClLog2(kPpWeakRefModuleName, 4,
     241                 :            "WeakRefCallOnMainThread: got cc\n");
     242               0 :   pp::Module::Get()->core()->CallOnMainThread(
     243                 :       delay_in_milliseconds,
     244                 :       cc,
     245                 :       PP_OK);
     246               0 :   NaClLog2(kPpWeakRefModuleName, 4,
     247                 :            "WeakRefCallOnMainThread: invoked PP_CallOnMainThread\n");
     248                 : }
     249                 : 
     250                 : }  // namespace plugin
     251                 : 
     252                 : #endif

Generated by: LCOV version 1.7