Commit 420ade41 authored by bbudge@chromium.org's avatar bbudge@chromium.org

Modify the PPB_Audio_Shared code for NaCl.

BUG=116317
TEST=none

This adds code for the NaCl untrusted build of the PPAPI proxy. The NaCl IRT can't
create threads that call back into user code, so the Audio thread must be created
using a special NaCl API.
Review URL: https://chromiumcodereview.appspot.com/10809079

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148423 0039d316-1c4b-4281-b951-d872f2087c98
parent cb017d1e
......@@ -23,6 +23,7 @@
#include "ppapi/c/ppp_instance.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_globals.h"
#include "ppapi/shared_impl/ppb_audio_shared.h"
#if defined(IPC_MESSAGE_LOG_ENABLED)
#define IPC_MESSAGE_MACROS_LOG_ENABLED
......@@ -38,8 +39,6 @@ using ppapi::proxy::PluginGlobals;
namespace {
struct PP_ThreadFunctions thread_funcs;
// Copied from src/content/ppapi_plugin/ppapi_thread. This is a minimal
// implementation to get us started.
class PluginDispatcherDelegate : public PluginDispatcher::PluginDelegate {
......@@ -101,8 +100,10 @@ class PluginDispatcherDelegate : public PluginDispatcher::PluginDelegate {
} // namespace
void PpapiPluginRegisterThreadCreator(
const struct PP_ThreadFunctions* new_funcs) {
thread_funcs = *new_funcs;
const struct PP_ThreadFunctions* thread_functions) {
// Initialize all classes that need to create threads that call back into
// user code.
ppapi::PPB_Audio_Shared::SetThreadFunctions(thread_functions);
}
int IrtInit() {
......
......@@ -5,6 +5,9 @@ include_rules = [
"+skia",
"+webkit/glue",
# The untrusted build references the NaCl integrated runtime (IRT).
"+native_client/src/untrusted/irt",
# Since this is used by the implementation in /webkit, we don't want it to
# depend on IPC.
"-ipc",
......
......@@ -11,6 +11,13 @@ using base::subtle::Atomic32;
namespace ppapi {
#if defined(OS_NACL)
namespace {
// Because this is static, the function pointers will be NULL initially.
PP_ThreadFunctions thread_functions;
}
#endif // defined(OS_NACL)
// FIXME: The following two functions (TotalSharedMemorySizeInBytes,
// SetActualDataSizeInBytes) are copied from audio_util.cc.
// Remove these functions once a minimal media library is provided for them.
......@@ -37,6 +44,10 @@ const int PPB_Audio_Shared::kPauseMark = -1;
PPB_Audio_Shared::PPB_Audio_Shared()
: playing_(false),
shared_memory_size_(0),
#if defined(OS_NACL)
thread_id_(0),
thread_active_(false),
#endif
callback_(NULL),
user_data_(NULL) {
}
......@@ -53,8 +64,11 @@ void PPB_Audio_Shared::SetCallback(PPB_Audio_Callback callback,
void PPB_Audio_Shared::SetStartPlaybackState() {
DCHECK(!playing_);
#if !defined(OS_NACL)
DCHECK(!audio_thread_.get());
#else
DCHECK(!thread_active_);
#endif
// If the socket doesn't exist, that means that the plugin has started before
// the browser has had a chance to create all the shared memory info and
// notify us. This is a common case. In this case, we just set the playing_
......@@ -91,21 +105,61 @@ void PPB_Audio_Shared::StartThread() {
// Don't start the thread unless all our state is set up correctly.
if (!playing_ || !callback_ || !socket_.get() || !shared_memory_->memory())
return;
// Clear contents of shm buffer before starting audio thread. This will
// prevent a burst of static if for some reason the audio thread doesn't
// start up quickly enough.
memset(shared_memory_->memory(), 0, shared_memory_size_);
#if !defined(OS_NACL)
DCHECK(!audio_thread_.get());
audio_thread_.reset(new base::DelegateSimpleThread(
this, "plugin_audio_thread"));
audio_thread_->Start();
#else
// Use NaCl's special API for IRT code that creates threads that call back
// into user code.
if (NULL == thread_functions.thread_create ||
NULL == thread_functions.thread_join)
return;
int result = thread_functions.thread_create(&thread_id_, CallRun, this);
DCHECK_EQ(result, 0);
thread_active_ = true;
#endif
}
void PPB_Audio_Shared::StopThread() {
// Shut down the socket to escape any hanging |Receive|s.
if (socket_.get())
socket_->Shutdown();
#if !defined(OS_NACL)
if (audio_thread_.get()) {
audio_thread_->Join();
audio_thread_.reset();
}
#else
if (thread_active_) {
int result = thread_functions.thread_join(thread_id_);
DCHECK_EQ(0, result);
thread_active_ = false;
}
#endif
}
#if defined(OS_NACL)
// static
void PPB_Audio_Shared::SetThreadFunctions(
const struct PP_ThreadFunctions* functions) {
DCHECK(thread_functions.thread_create == NULL);
DCHECK(thread_functions.thread_join == NULL);
thread_functions = *functions;
}
// static
void PPB_Audio_Shared::CallRun(void* self) {
PPB_Audio_Shared* audio = static_cast<PPB_Audio_Shared*>(self);
audio->Run();
}
#endif
void PPB_Audio_Shared::Run() {
int pending_data;
......
......@@ -13,6 +13,10 @@
#include "ppapi/shared_impl/resource.h"
#include "ppapi/thunk/ppb_audio_api.h"
#if defined(OS_NACL)
#include "native_client/src/untrusted/irt/irt_ppapi.h"
#endif
namespace ppapi {
// Implements the logic to map shared memory and run the audio thread signaled
......@@ -54,6 +58,11 @@ class PPAPI_SHARED_EXPORT PPB_Audio_Shared
size_t shared_memory_size,
base::SyncSocket::Handle socket_handle);
#if defined(OS_NACL)
// NaCl has a special API for IRT code to create threads that can call back
// into user code.
static void SetThreadFunctions(const struct PP_ThreadFunctions* functions);
#endif
private:
// Starts execution of the audio thread.
void StartThread();
......@@ -79,8 +88,15 @@ class PPAPI_SHARED_EXPORT PPB_Audio_Shared
// The size of the sample buffer in bytes.
size_t shared_memory_size_;
#if !defined(OS_NACL)
// When the callback is set, this thread is spawned for calling it.
scoped_ptr<base::DelegateSimpleThread> audio_thread_;
#else
uintptr_t thread_id_;
bool thread_active_;
static void CallRun(void* self);
#endif
// Callback to call when audio is ready to accept new samples.
PPB_Audio_Callback callback_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment