root/ppapi/cpp/completion_callback.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


// Copyright (c) 2012 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.

#ifndef PPAPI_CPP_COMPLETION_CALLBACK_H_
#define PPAPI_CPP_COMPLETION_CALLBACK_H_

#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/cpp/extensions/ext_output_traits.h"
#include "ppapi/cpp/logging.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/output_traits.h"

/// @file
/// This file defines the API to create and run a callback.
namespace pp {

/// This API enables you to implement and receive callbacks when
/// Pepper operations complete asynchronously.
///
/// You can create these objects yourself, but it is most common to use the
/// CompletionCallbackFactory to allow the callbacks to call class member
/// functions.
class CompletionCallback {
 public:
  /// The default constructor will create a blocking
  /// <code>CompletionCallback</code> that can be passed to a method to
  /// indicate that the calling thread should be blocked until the asynchronous
  /// operation corresponding to the method completes.
  ///
  /// <strong>Note:</strong> Blocking completion callbacks are only allowed from
  /// from background threads.
  CompletionCallback() {
    cc_ = PP_BlockUntilComplete();
  }

  /// A constructor for creating a <code>CompletionCallback</code>.
  ///
  /// @param[in] func The function to be called on completion.
  /// @param[in] user_data The user data to be passed to the callback function.
  /// This is optional and is typically used to help track state in case of
  /// multiple pending callbacks.
  CompletionCallback(PP_CompletionCallback_Func func, void* user_data) {
    cc_ = PP_MakeCompletionCallback(func, user_data);
  }

  /// A constructor for creating a <code>CompletionCallback</code> with
  /// specified flags.
  ///
  /// @param[in] func The function to be called on completion.
  /// @param[in] user_data The user data to be passed to the callback function.
  /// This is optional and is typically used to help track state in case of
  /// multiple pending callbacks.
  /// @param[in] flags Bit field combination of
  /// <code>PP_CompletionCallback_Flag</code> flags used to control how
  /// non-NULL callbacks are scheduled by asynchronous methods.
  CompletionCallback(PP_CompletionCallback_Func func, void* user_data,
                     int32_t flags) {
    cc_ = PP_MakeCompletionCallback(func, user_data);
    cc_.flags = flags;
  }

  /// The set_flags() function is used to set the flags used to control
  /// how non-NULL callbacks are scheduled by asynchronous methods.
  ///
  /// @param[in] flags Bit field combination of
  /// <code>PP_CompletionCallback_Flag</code> flags used to control how
  /// non-NULL callbacks are scheduled by asynchronous methods.
  void set_flags(int32_t flags) { cc_.flags = flags; }

  /// Run() is used to run the <code>CompletionCallback</code>.
  /// Normally, the system runs a <code>CompletionCallback</code> after an
  /// asynchronous operation completes, but programs may wish to run the
  /// <code>CompletionCallback</code> manually in order to reuse the same code
  /// paths.
  ///
  /// @param[in] result The result of the operation to be passed to the
  /// callback function. Non-positive values correspond to the error codes
  /// from <code>pp_errors.h</code> (excluding
  /// <code>PP_OK_COMPLETIONPENDING</code>). Positive values indicate
  /// additional information such as bytes read.
  void Run(int32_t result) {
    PP_DCHECK(cc_.func);
    PP_RunCompletionCallback(&cc_, result);
  }

  /// RunAndClear() is used to run the <code>CompletionCallback</code> and
  /// clear out the callback so that it cannot be run a second time.
  ///
  /// @param[in] result The result of the operation to be passed to the
  /// callback function. Non-positive values correspond to the error codes
  /// from <code>pp_errors.h</code> (excluding
  /// <code>PP_OK_COMPLETIONPENDING</code>). Positive values indicate
  /// additional information such as bytes read.
  void RunAndClear(int32_t result) {
    PP_DCHECK(cc_.func);
    PP_RunAndClearCompletionCallback(&cc_, result);
  }

  /// IsOptional() is used to determine the setting of the
  /// <code>PP_COMPLETIONCALLBACK_FLAG_OPTIONAL</code> flag. This flag allows
  /// any method taking such callback to complete synchronously
  /// and not call the callback if the operation would not block. This is useful
  /// when performance is an issue, and the operation bandwidth should not be
  /// limited to the processing speed of the message loop.
  ///
  /// On synchronous method completion, the completion result will be returned
  /// by the method itself. Otherwise, the method will return
  /// PP_OK_COMPLETIONPENDING, and the callback will be invoked asynchronously
  /// on the same thread where the PPB method was invoked.
  ///
  /// @return true if this callback is optional, otherwise false.
  bool IsOptional() const {
    return (cc_.func == NULL ||
            (cc_.flags & PP_COMPLETIONCALLBACK_FLAG_OPTIONAL) != 0);
  }

  /// The pp_completion_callback() function returns the underlying
  /// <code>PP_CompletionCallback</code>
  ///
  /// @return A <code>PP_CompletionCallback</code>.
  const PP_CompletionCallback& pp_completion_callback() const { return cc_; }

  /// The flags() function returns flags used to control how non-NULL callbacks
  /// are scheduled by asynchronous methods.
  ///
  /// @return An int32_t containing a bit field combination of
  /// <code>PP_CompletionCallback_Flag</code> flags.
  int32_t flags() const { return cc_.flags; }

  /// MayForce() is used when implementing functions taking callbacks.
  /// If the callback is required and <code>result</code> indicates that it has
  /// not been scheduled, it will be forced on the main thread.
  ///
  /// <strong>Example:</strong>
  ///
  /// @code
  ///
  /// int32_t OpenURL(pp::URLLoader* loader,
  ///                 pp::URLRequestInfo* url_request_info,
  ///                 const CompletionCallback& cc) {
  ///   if (loader == NULL || url_request_info == NULL)
  ///     return cc.MayForce(PP_ERROR_BADRESOURCE);
  ///   return loader->Open(*loader, *url_request_info, cc);
  /// }
  ///
  /// @endcode
  ///
  /// @param[in] result PP_OK_COMPLETIONPENDING or the result of the completed
  /// operation to be passed to the callback function. PP_OK_COMPLETIONPENDING
  /// indicates that the callback has already been scheduled. Other
  /// non-positive values correspond to error codes from
  /// <code>pp_errors.h</code>. Positive values indicate additional information
  /// such as bytes read.
  ///
  /// @return <code>PP_OK_COMPLETIONPENDING</code> if the callback has been
  /// forced, result parameter otherwise.
  int32_t MayForce(int32_t result) const {
    if (result == PP_OK_COMPLETIONPENDING || IsOptional())
      return result;
    // FIXME(dmichael): Use pp::MessageLoop here once it's out of Dev.
    Module::Get()->core()->CallOnMainThread(0, *this, result);
    return PP_OK_COMPLETIONPENDING;
  }

 protected:
  PP_CompletionCallback cc_;
};

namespace internal {

/// The base class of [Ext]CompletionCallbackWithOutput.
///
/// The template parameter Traits determines the storage type
/// (OutputStorageType), the output parameter type used by the browser
/// (APIArgType), and how to map OutputStorageType to APIArgType.
template <typename T, typename Traits>
class CompletionCallbackWithOutputBase : public CompletionCallback {
 public:
  typedef typename Traits::StorageType OutputStorageType;
  typedef typename Traits::APIArgType APIArgType;
  typedef Traits TraitsType;

  explicit CompletionCallbackWithOutputBase(OutputStorageType* output)
      : CompletionCallback(),
        output_(output) {
  }

  CompletionCallbackWithOutputBase(PP_CompletionCallback_Func func,
                                   void* user_data,
                                   OutputStorageType* output)
      : CompletionCallback(func, user_data),
        output_(output) {
  }

  CompletionCallbackWithOutputBase(PP_CompletionCallback_Func func,
                                   void* user_data,
                                   int32_t flags,
                                   OutputStorageType* output)
      : CompletionCallback(func, user_data, flags),
        output_(output) {
  }

  APIArgType output() const {
    return Traits::StorageToAPIArg(*output_);
  }

 private:
  OutputStorageType* output_;
};

}  // namespace internal

/// A CompletionCallbackWithOutput defines a completion callback that
/// additionally stores a pointer to some output data. Some C++ wrappers
/// take a CompletionCallbackWithOutput when the browser is returning a
/// bit of data as part of the function call. The "output" parameter
/// stored in the CompletionCallbackWithOutput will receive the data from
/// the browser.
///
/// You can create this yourself, but it is most common to use with the
/// CompletionCallbackFactory's NewCallbackWithOutput, which manages the
/// storage for the output parameter for you and passes it as an argument
/// to your callback function.
///
/// Note that this class doesn't actually do anything with the output data,
/// it just stores a pointer to it. C++ wrapper objects that accept a
/// CompletionCallbackWithOutput will retrieve this pointer and pass it to
/// the browser as the output parameter.
template <typename T>
class CompletionCallbackWithOutput
    : public internal::CompletionCallbackWithOutputBase<
        T, internal::CallbackOutputTraits<T> > {
 public:
  typedef internal::CompletionCallbackWithOutputBase<
      T, internal::CallbackOutputTraits<T> > BaseType;

  /// The default constructor will create a blocking
  /// <code>CompletionCallbackWithOutput</code> that references the given output
  /// data.
  ///
  /// @param[in] output A pointer to the data associated with the callback. The
  /// caller must ensure that this pointer outlives the completion callback.
  /// In the common case, <code>OutputStorageType</code> will be equal to the
  /// template parameter T (for example,
  /// <code>CompletionCallbackWithOutput<int></code> would obviously take an
  /// int*. However, resources are passed as PP_Resource, vars as PP_Var, and
  /// arrays as our special ArrayOutputAdapter object.
  /// <code>internal::CallbackOutputTraits</code> defines specializations for
  /// all of these cases.
  ///
  /// <strong>Note:</strong> Blocking completion callbacks are only allowed from
  /// background threads.
  explicit CompletionCallbackWithOutput(
      typename BaseType::OutputStorageType* output)
      : BaseType(output) {
  }

  /// A constructor for creating a <code>CompletionCallbackWithOutput</code>
  /// that references the given output data.
  ///
  /// @param[in] func The function to be called on completion.
  /// @param[in] user_data The user data to be passed to the callback function.
  /// This is optional and is typically used to help track state in case of
  /// multiple pending callbacks.
  /// @param[in] output A pointer to the data associated with the callback. The
  /// caller must ensure that this pointer outlives the completion callback.
  CompletionCallbackWithOutput(PP_CompletionCallback_Func func,
                               void* user_data,
                               typename BaseType::OutputStorageType* output)
      : BaseType(func, user_data, output) {
  }

  /// A constructor for creating a <code>CompletionCallbackWithOutput</code>
  /// that references the given output data.
  ///
  /// @param[in] func The function to be called on completion.
  ///
  /// @param[in] user_data The user data to be passed to the callback function.
  /// This is optional and is typically used to help track state in case of
  /// multiple pending callbacks.
  ///
  /// @param[in] flags Bit field combination of
  /// <code>PP_CompletionCallback_Flag</code> flags used to control how
  /// non-NULL callbacks are scheduled by asynchronous methods.
  ///
  /// @param[in] output A pointer to the data associated with the callback. The
  /// caller must ensure that this pointer outlives the completion callback.
  CompletionCallbackWithOutput(PP_CompletionCallback_Func func,
                               void* user_data,
                               int32_t flags,
                               typename BaseType::OutputStorageType* output)
      : BaseType(func, user_data, flags, output) {
  }
};

namespace ext {

/// ExtCompletionCallbackWithOutput is similar to CompletionCallbackWithOutput,
/// but used by APIs within the pp::ext namespace. Usually it is used with the
/// CompletionCallbackFactory's NewExtCallbackWithOutput.
template <typename T>
class ExtCompletionCallbackWithOutput
    : public ::pp::internal::CompletionCallbackWithOutputBase<
        T, internal::ExtCallbackOutputTraits<T> > {
 public:
  typedef ::pp::internal::CompletionCallbackWithOutputBase<
      T, internal::ExtCallbackOutputTraits<T> > BaseType;

  /// The default constructor will create a blocking
  /// <code>ExtCompletionCallbackWithOutput</code> that references the given
  /// output data.
  ///
  /// @param[in] output A pointer to the data associated with the callback. The
  /// caller must ensure that this pointer outlives the completion callback.
  /// <code>OutputStorageType</code> is either
  /// <code>ext::internal::ArrayVarOutputAdapterWithStorage<U></code> (if the
  /// template parameter T is of the form std::vector<U>) or
  /// <code>ext::internal::VarOutputAdapterWithStorage<T></code> (otherwise).
  ///
  /// <strong>Note:</strong> Blocking completion callbacks are only allowed from
  /// background threads.
  explicit ExtCompletionCallbackWithOutput(
      typename BaseType::OutputStorageType* output)
      : BaseType(output) {
  }

  /// A constructor for creating an <code>ExtCompletionCallbackWithOutput</code>
  /// that references the given output data.
  ///
  /// @param[in] func The function to be called on completion.
  /// @param[in] user_data The user data to be passed to the callback function.
  /// This is optional and is typically used to help track state in case of
  /// multiple pending callbacks.
  /// @param[in] output A pointer to the data associated with the callback. The
  /// caller must ensure that this pointer outlives the completion callback.
  ExtCompletionCallbackWithOutput(PP_CompletionCallback_Func func,
                                  void* user_data,
                                  typename BaseType::OutputStorageType* output)
      : BaseType(func, user_data, output) {
  }

  /// A constructor for creating an <code>ExtCompletionCallbackWithOutput</code>
  /// that references the given output data.
  ///
  /// @param[in] func The function to be called on completion.
  ///
  /// @param[in] user_data The user data to be passed to the callback function.
  /// This is optional and is typically used to help track state in case of
  /// multiple pending callbacks.
  ///
  /// @param[in] flags Bit field combination of
  /// <code>PP_CompletionCallback_Flag</code> flags used to control how
  /// non-NULL callbacks are scheduled by asynchronous methods.
  ///
  /// @param[in] output A pointer to the data associated with the callback. The
  /// caller must ensure that this pointer outlives the completion callback.
  ExtCompletionCallbackWithOutput(PP_CompletionCallback_Func func,
                                  void* user_data,
                                  int32_t flags,
                                  typename BaseType::OutputStorageType* output)
      : BaseType(func, user_data, flags, output) {
  }
};

}  // namespace ext

/// BlockUntilComplete() is used in place of an actual completion callback
/// to request blocking behavior. If specified, the calling thread will block
/// until the function completes. Blocking completion callbacks are only
/// allowed from background threads.
///
/// @return A <code>CompletionCallback</code> corresponding to a NULL callback.
inline CompletionCallback BlockUntilComplete() {
  // Note: Explicitly inlined to avoid link errors when included into
  // ppapi_proxy and ppapi_cpp_objects.
  return CompletionCallback();
}

}  // namespace pp

#endif  // PPAPI_CPP_COMPLETION_CALLBACK_H_

/* [<][>][^][v][top][bottom][index][help] */