| Index: ppapi/native_client/src/shared/ppapi_proxy/browser_callback.cc
|
| ===================================================================
|
| --- ppapi/native_client/src/shared/ppapi_proxy/browser_callback.cc (revision 0)
|
| +++ ppapi/native_client/src/shared/ppapi_proxy/browser_callback.cc (revision 0)
|
| @@ -0,0 +1,152 @@
|
| +// Copyright (c) 2011 The Native Client 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 "native_client/src/shared/ppapi_proxy/browser_callback.h"
|
| +
|
| +#include <new>
|
| +
|
| +#include "native_client/src/include/nacl_macros.h"
|
| +#include "native_client/src/include/nacl_scoped_ptr.h"
|
| +#include "native_client/src/shared/platform/nacl_check.h"
|
| +#include "native_client/src/shared/ppapi_proxy/browser_globals.h"
|
| +#include "native_client/src/shared/ppapi_proxy/browser_ppp.h"
|
| +#include "native_client/src/shared/ppapi_proxy/utility.h"
|
| +#include "native_client/src/shared/srpc/nacl_srpc.h"
|
| +#include "ppapi/c/pp_completion_callback.h"
|
| +#include "native_client/src/trusted/plugin/plugin.h"
|
| +#include "srpcgen/ppp_rpc.h"
|
| +
|
| +namespace ppapi_proxy {
|
| +
|
| +namespace {
|
| +
|
| +bool BytesWereRead(int32_t num_bytes) {
|
| + return (num_bytes > 0);
|
| +}
|
| +
|
| +nacl_abi_size_t CastToNaClAbiSize(int32_t result) {
|
| + return static_cast<nacl_abi_size_t>(result);
|
| +}
|
| +
|
| +// Data structure used on the browser side to invoke a completion callback
|
| +// on the plugin side.
|
| +//
|
| +// A plugin-side callback is proxied over to the browser side using
|
| +// a |callback_id|. This id is then paired with an |srpc_channel| listened to
|
| +// by the nexe that supplied the callback.
|
| +//
|
| +// |read_buffer| is used with callbacks that are invoked on byte reads.
|
| +// |check_result_func| is a pointer to a function used to check the
|
| +// result of the operation. The semantics of the result value may be different
|
| +// depending on how the callback operation was initiated, and
|
| +// |check_result_func| provides an abstraction to the semantics.
|
| +// |get_size_read_func| is a pointer to a function used to get the
|
| +// number of bytes read. The way the number of bytes read
|
| +// retrieved/calculated may be different depending on how the callback was
|
| +// initiated, and |get_size_read_func| provides the indirection.
|
| +struct RemoteCallbackInfo {
|
| + NaClSrpcChannel* srpc_channel;
|
| + int32_t callback_id;
|
| + char* read_buffer;
|
| + CheckResultFunc check_result_func;
|
| + GetReadSizeFunc get_size_read_func;
|
| +};
|
| +
|
| +// Calls the remote implementation of a callback on the plugin side.
|
| +// Implements a PP_CompletionCallback_Func type that can be used along with an
|
| +// instance of a RemoteCallbackInfo as |user_data| to provide a
|
| +// PP_CompletionCallback to browser functions.
|
| +//
|
| +// |remote_callback| is a pointer to a RemoteCallbackInfo,
|
| +// deleted after rpc via scoped_ptr. The associated |read_buffer| is also
|
| +// deleted.
|
| +// |result| is passed by the callback invoker to indicate success or error.
|
| +// It is passed as-is to the plugin side callback.
|
| +void RunRemoteCallback(void* user_data, int32_t result) {
|
| + CHECK(PPBCoreInterface()->IsMainThread());
|
| + DebugPrintf("RunRemoteCallback: result=%"NACL_PRId32"\n", result);
|
| + nacl::scoped_ptr<RemoteCallbackInfo> remote_callback(
|
| + reinterpret_cast<RemoteCallbackInfo*>(user_data));
|
| + nacl::scoped_array<char> read_buffer(remote_callback->read_buffer);
|
| +
|
| + // If the proxy is down, the channel is no longer usable for remote calls.
|
| + PP_Instance instance =
|
| + LookupInstanceIdForSrpcChannel(remote_callback->srpc_channel);
|
| + if (LookupBrowserPppForInstance(instance) == NULL) {
|
| + DebugPrintf("RunRemoteCallback: proxy=NULL\n", result);
|
| + return;
|
| + }
|
| +
|
| + nacl_abi_size_t read_buffer_size = 0;
|
| + CheckResultFunc check_result_func = remote_callback->check_result_func;
|
| + GetReadSizeFunc get_size_read_func = remote_callback->get_size_read_func;
|
| + if ((*check_result_func)(result) && remote_callback->read_buffer != NULL)
|
| + read_buffer_size = (*get_size_read_func)(result);
|
| +
|
| + NaClSrpcError srpc_result =
|
| + CompletionCallbackRpcClient::RunCompletionCallback(
|
| + remote_callback->srpc_channel,
|
| + remote_callback->callback_id,
|
| + result,
|
| + read_buffer_size,
|
| + read_buffer.get());
|
| + DebugPrintf("RunRemoteCallback: %s\n",
|
| + NaClSrpcErrorString(srpc_result));
|
| + if (srpc_result == NACL_SRPC_RESULT_INTERNAL)
|
| + CleanUpAfterDeadNexe(instance);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// Builds a RemoteCallbackInfo and returns PP_CompletionCallback corresponding
|
| +// to RunRemoteCallback or NULL on failure.
|
| +struct PP_CompletionCallback MakeRemoteCompletionCallback(
|
| + NaClSrpcChannel* srpc_channel,
|
| + int32_t callback_id,
|
| + int32_t bytes_to_read,
|
| + char** buffer,
|
| + CheckResultFunc check_result_func,
|
| + GetReadSizeFunc get_size_read_func) {
|
| + RemoteCallbackInfo* remote_callback = new(std::nothrow) RemoteCallbackInfo;
|
| + if (remote_callback == NULL) // new failed.
|
| + return PP_BlockUntilComplete();
|
| + remote_callback->srpc_channel = srpc_channel;
|
| + remote_callback->callback_id = callback_id;
|
| + remote_callback->read_buffer = NULL;
|
| + remote_callback->check_result_func = check_result_func;
|
| + remote_callback->get_size_read_func = get_size_read_func;
|
| +
|
| + if (bytes_to_read > 0 && buffer != NULL) {
|
| + *buffer = new(std::nothrow) char[bytes_to_read];
|
| + if (*buffer == NULL) // new failed.
|
| + return PP_BlockUntilComplete();
|
| + remote_callback->read_buffer = *buffer;
|
| + }
|
| +
|
| + return PP_MakeOptionalCompletionCallback(
|
| + RunRemoteCallback, remote_callback);
|
| +}
|
| +
|
| +struct PP_CompletionCallback MakeRemoteCompletionCallback(
|
| + NaClSrpcChannel* srpc_channel,
|
| + int32_t callback_id,
|
| + int32_t bytes_to_read,
|
| + char** buffer) {
|
| + return MakeRemoteCompletionCallback(srpc_channel, callback_id, bytes_to_read,
|
| + buffer, BytesWereRead, CastToNaClAbiSize);
|
| +}
|
| +
|
| +struct PP_CompletionCallback MakeRemoteCompletionCallback(
|
| + NaClSrpcChannel* srpc_channel,
|
| + int32_t callback_id) {
|
| + return MakeRemoteCompletionCallback(srpc_channel, callback_id, 0, NULL);
|
| +}
|
| +
|
| +void DeleteRemoteCallbackInfo(struct PP_CompletionCallback callback) {
|
| + nacl::scoped_ptr<RemoteCallbackInfo> remote_callback(
|
| + reinterpret_cast<RemoteCallbackInfo*>(callback.user_data));
|
| + nacl::scoped_array<char> read_buffer(remote_callback->read_buffer);
|
| +}
|
| +
|
| +} // namespace ppapi_proxy
|
|
|