| Index: ppapi/native_client/src/shared/ppapi_proxy/plugin_callback.cc
|
| ===================================================================
|
| --- ppapi/native_client/src/shared/ppapi_proxy/plugin_callback.cc (revision 0)
|
| +++ ppapi/native_client/src/shared/ppapi_proxy/plugin_callback.cc (revision 0)
|
| @@ -0,0 +1,95 @@
|
| +// 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/plugin_callback.h"
|
| +#include <string.h>
|
| +#include "native_client/src/shared/ppapi_proxy/utility.h"
|
| +#include "ppapi/c/pp_errors.h"
|
| +#include "srpcgen/ppp_rpc.h"
|
| +
|
| +namespace ppapi_proxy {
|
| +
|
| +int32_t MayForceCallback(PP_CompletionCallback callback, int32_t result) {
|
| + if (result == PP_OK_COMPLETIONPENDING)
|
| + return result;
|
| +
|
| + if (callback.func == NULL ||
|
| + (callback.flags & PP_COMPLETIONCALLBACK_FLAG_OPTIONAL) != 0)
|
| + return result;
|
| +
|
| + PPBCoreInterface()->CallOnMainThread(0, callback, result);
|
| + return PP_OK_COMPLETIONPENDING;
|
| +}
|
| +
|
| +// Initialize static mutex used as critical section for all callback tables.
|
| +pthread_mutex_t CompletionCallbackTable::mutex_ = PTHREAD_MUTEX_INITIALIZER;
|
| +
|
| +int32_t CompletionCallbackTable::AddCallback(
|
| + const PP_CompletionCallback& callback,
|
| + void* read_buffer) {
|
| + CallbackTableCriticalSection guard;
|
| + if (callback.func == NULL) {
|
| + DebugPrintf("CompletionCallbackTable attempted to add NULL func!!\n");
|
| + return 0;
|
| + }
|
| + int32_t callback_id = next_id_;
|
| + ++next_id_;
|
| + CallbackInfo info = { callback, read_buffer };
|
| + table_.insert(std::pair<int32_t, CallbackInfo>(callback_id, info));
|
| + return callback_id;
|
| +}
|
| +
|
| +int32_t CompletionCallbackTable::AddCallback(
|
| + const PP_CompletionCallback& callback) {
|
| + return AddCallback(callback, NULL);
|
| +}
|
| +
|
| +PP_CompletionCallback CompletionCallbackTable::RemoveCallback(
|
| + int32_t callback_id, void** read_buffer) {
|
| + CallbackTableCriticalSection guard;
|
| + CallbackTable::iterator it = table_.find(callback_id);
|
| + DebugPrintf("CompletionCallbackTable::RemoveCallback id: %"NACL_PRId32"\n",
|
| + callback_id);
|
| + if (table_.end() != it) {
|
| + CallbackInfo info = it->second;
|
| + table_.erase(it);
|
| + if (read_buffer != NULL)
|
| + *read_buffer = info.read_buffer;
|
| + return info.callback;
|
| + }
|
| + *read_buffer = NULL;
|
| + return PP_BlockUntilComplete();
|
| +}
|
| +
|
| +} // namespace ppapi_proxy
|
| +
|
| +// SRPC-abstraction wrapper around a PP_CompletionCallback.
|
| +void CompletionCallbackRpcServer::RunCompletionCallback(
|
| + NaClSrpcRpc* rpc,
|
| + NaClSrpcClosure* done,
|
| + // inputs
|
| + int32_t callback_id,
|
| + int32_t result,
|
| + // TODO(polina): use shm for read buffer
|
| + nacl_abi_size_t read_buffer_size, char* read_buffer) {
|
| + NaClSrpcClosureRunner runner(done);
|
| + rpc->result = NACL_SRPC_RESULT_APP_ERROR;
|
| +
|
| + void* user_buffer;
|
| + PP_CompletionCallback callback =
|
| + ppapi_proxy::CompletionCallbackTable::Get()->RemoveCallback(
|
| + callback_id, &user_buffer);
|
| + if (callback.func == NULL) {
|
| + ppapi_proxy::DebugPrintf(
|
| + "CompletionCallbackRpcServer: id of %"NACL_PRId32" is NULL callback!\n",
|
| + callback_id);
|
| + return;
|
| + }
|
| +
|
| + if (user_buffer != NULL && read_buffer_size > 0)
|
| + memcpy(user_buffer, read_buffer, read_buffer_size);
|
| + PP_RunCompletionCallback(&callback, result);
|
| +
|
| + rpc->result = NACL_SRPC_RESULT_OK;
|
| +}
|
|
|