| // Copyright (c) 2011 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. |
| // |
| // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING |
| // |
| // This is an early draft of background thread support. |
| // Until it is complete, we assume that all proxy functions |
| // (except CallOnMainThread) are called on the main PPAPI thread. |
| // |
| // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING |
| |
| #include "native_client/src/shared/ppapi_proxy/plugin_upcall.h" |
| |
| #include <pthread.h> |
| #include <map> |
| |
| #include "native_client/src/include/nacl_macros.h" |
| #include "native_client/src/include/portability.h" |
| #include "native_client/src/shared/ppapi_proxy/plugin_callback.h" |
| #include "native_client/src/shared/ppapi_proxy/plugin_globals.h" |
| #include "native_client/src/shared/ppapi_proxy/utility.h" |
| #include "native_client/src/shared/srpc/nacl_srpc.h" |
| #include "ppapi/c/pp_errors.h" |
| #include "srpcgen/ppp_rpc.h" |
| #include "srpcgen/upcall.h" |
| |
| using ppapi_proxy::CompletionCallbackTable; |
| |
| namespace ppapi_proxy { |
| |
| namespace { |
| |
| class CallOnMainThreadCriticalSection { |
| static pthread_mutex_t mutex_; |
| public: |
| CallOnMainThreadCriticalSection() { pthread_mutex_lock(&mutex_); } |
| ~CallOnMainThreadCriticalSection() { pthread_mutex_unlock(&mutex_); } |
| }; |
| |
| pthread_mutex_t CallOnMainThreadCriticalSection::mutex_ = |
| PTHREAD_MUTEX_INITIALIZER; |
| |
| } // namespace |
| |
| // The call on main thread is implemented via an RPC to the browser side on the |
| // upcall channel, instead of locally to the plugin. This is to ensure that |
| // when the callback runs (and potentially calls one of the PPB_ methods |
| // over RPC), the browser-side is listening. |
| void PluginUpcallCoreCallOnMainThread(int32_t delay_in_milliseconds, |
| PP_CompletionCallback callback, |
| int32_t result) { |
| // Force PluginUpcallCoreCallOnMainThread, from multiple threads, to occur |
| // one at a time. |
| CallOnMainThreadCriticalSection guard; |
| NaClSrpcChannel* upcall_channel = GetUpcallSrpcChannel(); |
| if (upcall_channel == NULL) { |
| DebugPrintf("PluginUpcallCoreCallOnMainThread: NULL channel.\n"); |
| return; |
| } |
| int32_t callback_id = |
| ppapi_proxy::CompletionCallbackTable::Get()->AddCallback(callback); |
| if (callback_id == 0) { |
| DebugPrintf("PluginUpcallCoreCallOnMainThread: NULL callback.\n"); |
| return; |
| } |
| (void) PppUpcallRpcClient::PPB_Core_CallOnMainThread( |
| upcall_channel, delay_in_milliseconds, callback_id, result); |
| } |
| |
| } // namespace ppapi_proxy |