| Index: ppapi/native_client/src/trusted/plugin/service_runtime.cc
|
| diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.cc b/ppapi/native_client/src/trusted/plugin/service_runtime.cc
|
| index 131f9ae98238c71a6b7b7251def743ce9ad00280..b808ee1b60c3f95eee38e67458f0f0f6e40b73cd 100644
|
| --- a/ppapi/native_client/src/trusted/plugin/service_runtime.cc
|
| +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.cc
|
| @@ -56,6 +56,42 @@
|
| #include "ppapi/native_client/src/trusted/weak_ref/call_on_main_thread.h"
|
|
|
| namespace plugin {
|
| +
|
| +class OpenManifestEntryAsyncCallback {
|
| + public:
|
| + OpenManifestEntryAsyncCallback(PP_OpenResourceCompletionCallback callback,
|
| + void* callback_user_data)
|
| + : callback_(callback), callback_user_data_(callback_user_data) {
|
| + }
|
| +
|
| + ~OpenManifestEntryAsyncCallback() {
|
| + if (callback_)
|
| + callback_(callback_user_data_, PP_kInvalidFileHandle);
|
| + }
|
| +
|
| + void Run(int32_t pp_error) {
|
| +#if defined(OS_WIN)
|
| + // Currently, this is used only for non-SFI mode, and now the mode is not
|
| + // supported on windows.
|
| + // TODO(hidehiko): Support it on Windows when we switch to use
|
| + // ManifestService also in SFI-mode.
|
| + NACL_NOTREACHED();
|
| +#elif defined(OS_POSIX)
|
| + // On posix, PlatformFile is the file descriptor.
|
| + callback_(callback_user_data_, (pp_error == PP_OK) ? info_.desc : -1);
|
| + callback_ = NULL;
|
| +#endif
|
| + }
|
| +
|
| + NaClFileInfo* mutable_info() { return &info_; }
|
| +
|
| + private:
|
| + NaClFileInfo info_;
|
| + PP_OpenResourceCompletionCallback callback_;
|
| + void* callback_user_data_;
|
| + DISALLOW_COPY_AND_ASSIGN(OpenManifestEntryAsyncCallback);
|
| +};
|
| +
|
| namespace {
|
|
|
| // For doing crude quota enforcement on writes to temp files.
|
| @@ -92,6 +128,25 @@ class ManifestService {
|
| return true;
|
| }
|
|
|
| + bool OpenResource(const char* entry_key,
|
| + PP_OpenResourceCompletionCallback callback,
|
| + void* callback_user_data) {
|
| + // Release this instance if the ServiceRuntime is already destructed.
|
| + if (anchor_->is_abandoned()) {
|
| + callback(callback_user_data, PP_kInvalidFileHandle);
|
| + delete this;
|
| + return false;
|
| + }
|
| +
|
| + OpenManifestEntryAsyncCallback* open_manifest_callback =
|
| + new OpenManifestEntryAsyncCallback(callback, callback_user_data);
|
| + plugin_reverse_->OpenManifestEntryAsync(
|
| + entry_key,
|
| + open_manifest_callback->mutable_info(),
|
| + open_manifest_callback);
|
| + return true;
|
| + }
|
| +
|
| static PP_Bool QuitTrampoline(void* user_data) {
|
| return PP_FromBool(static_cast<ManifestService*>(user_data)->Quit());
|
| }
|
| @@ -101,6 +156,15 @@ class ManifestService {
|
| StartupInitializationComplete());
|
| }
|
|
|
| + static PP_Bool OpenResourceTrampoline(
|
| + void* user_data,
|
| + const char* entry_key,
|
| + PP_OpenResourceCompletionCallback callback,
|
| + void* callback_user_data) {
|
| + return PP_FromBool(static_cast<ManifestService*>(user_data)->OpenResource(
|
| + entry_key, callback, callback_user_data));
|
| + }
|
| +
|
| private:
|
| // Weak reference to check if plugin_reverse is legally accessible or not.
|
| nacl::WeakRefAnchor* anchor_;
|
| @@ -110,13 +174,27 @@ class ManifestService {
|
| };
|
|
|
| // Vtable to pass functions to LaunchSelLdr.
|
| -const PP_ManifestService kManifestServiceVTable = {
|
| +const PPP_ManifestService kManifestServiceVTable = {
|
| &ManifestService::QuitTrampoline,
|
| &ManifestService::StartupInitializationCompleteTrampoline,
|
| + &ManifestService::OpenResourceTrampoline,
|
| };
|
|
|
| } // namespace
|
|
|
| +OpenManifestEntryResource::~OpenManifestEntryResource() {
|
| + MaybeRunCallback(PP_ERROR_ABORTED);
|
| +}
|
| +
|
| +void OpenManifestEntryResource::MaybeRunCallback(int32_t pp_error) {
|
| + if (!callback)
|
| + return;
|
| +
|
| + callback->Run(pp_error);
|
| + delete callback;
|
| + callback = NULL;
|
| +}
|
| +
|
| PluginReverseInterface::PluginReverseInterface(
|
| nacl::WeakRefAnchor* anchor,
|
| Plugin* plugin,
|
| @@ -195,7 +273,7 @@ bool PluginReverseInterface::OpenManifestEntry(nacl::string url_key,
|
| // the main thread before this function can return. The pointers it contains
|
| // to stack variables will not leak.
|
| OpenManifestEntryResource* to_open =
|
| - new OpenManifestEntryResource(url_key, info, &op_complete);
|
| + new OpenManifestEntryResource(url_key, info, &op_complete, NULL);
|
| CHECK(to_open != NULL);
|
| NaClLog(4, "PluginReverseInterface::OpenManifestEntry: %s\n",
|
| url_key.c_str());
|
| @@ -245,6 +323,16 @@ bool PluginReverseInterface::OpenManifestEntry(nacl::string url_key,
|
| return true;
|
| }
|
|
|
| +void PluginReverseInterface::OpenManifestEntryAsync(
|
| + const nacl::string& entry_key,
|
| + struct NaClFileInfo* info,
|
| + OpenManifestEntryAsyncCallback* callback) {
|
| + bool op_complete = false;
|
| + OpenManifestEntryResource to_open(
|
| + entry_key, info, &op_complete, callback);
|
| + OpenManifestEntry_MainThreadContinuation(&to_open, PP_OK);
|
| +}
|
| +
|
| // Transfer point from OpenManifestEntry() which runs on the main thread
|
| // (Some PPAPI actions -- like StreamAsFile -- can only run on the main thread).
|
| // OpenManifestEntry() is waiting on a condvar for this continuation to
|
| @@ -271,10 +359,13 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation(
|
| error_info.message().c_str());
|
| // Failed, and error_info has the details on what happened. Wake
|
| // up requesting thread -- we are done.
|
| - nacl::MutexLocker take(&mu_);
|
| - *p->op_complete_ptr = true; // done...
|
| - p->file_info->desc = -1; // but failed.
|
| - NaClXCondVarBroadcast(&cv_);
|
| + {
|
| + nacl::MutexLocker take(&mu_);
|
| + *p->op_complete_ptr = true; // done...
|
| + p->file_info->desc = -1; // but failed.
|
| + NaClXCondVarBroadcast(&cv_);
|
| + }
|
| + p->MaybeRunCallback(PP_OK);
|
| return;
|
| }
|
| NaClLog(4,
|
| @@ -287,10 +378,13 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation(
|
| NaClLog(4,
|
| "OpenManifestEntry_MainThreadContinuation: "
|
| "Requires PNaCl translation -- not supported\n");
|
| - nacl::MutexLocker take(&mu_);
|
| - *p->op_complete_ptr = true; // done...
|
| - p->file_info->desc = -1; // but failed.
|
| - NaClXCondVarBroadcast(&cv_);
|
| + {
|
| + nacl::MutexLocker take(&mu_);
|
| + *p->op_complete_ptr = true; // done...
|
| + p->file_info->desc = -1; // but failed.
|
| + NaClXCondVarBroadcast(&cv_);
|
| + }
|
| + p->MaybeRunCallback(PP_OK);
|
| return;
|
| }
|
|
|
| @@ -308,14 +402,17 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation(
|
| "OpenManifestEntry_MainThreadContinuation: "
|
| "GetReadonlyPnaclFd failed\n");
|
| }
|
| - nacl::MutexLocker take(&mu_);
|
| - *p->op_complete_ptr = true; // done!
|
| - // TODO(ncbray): enable the fast loading and validation paths for this
|
| - // type of file.
|
| - p->file_info->desc = fd;
|
| - NaClXCondVarBroadcast(&cv_);
|
| + {
|
| + nacl::MutexLocker take(&mu_);
|
| + *p->op_complete_ptr = true; // done!
|
| + // TODO(ncbray): enable the fast loading and validation paths for this
|
| + // type of file.
|
| + p->file_info->desc = fd;
|
| + NaClXCondVarBroadcast(&cv_);
|
| + }
|
| NaClLog(4,
|
| "OpenManifestEntry_MainThreadContinuation: GetPnaclFd okay\n");
|
| + p->MaybeRunCallback(PP_OK);
|
| return;
|
| }
|
|
|
| @@ -325,6 +422,9 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation(
|
| // to create another instance.
|
| OpenManifestEntryResource* open_cont = new OpenManifestEntryResource(*p);
|
| open_cont->url = mapped_url;
|
| + // Callback is now delegated from p to open_cont. So, here we manually clear
|
| + // complete callback.
|
| + p->callback = NULL;
|
| pp::CompletionCallback stream_cc = WeakRefNewCallback(
|
| anchor_,
|
| this,
|
| @@ -352,22 +452,26 @@ void PluginReverseInterface::StreamAsFile_MainThreadContinuation(
|
| NaClLog(4,
|
| "Entered StreamAsFile_MainThreadContinuation\n");
|
|
|
| - nacl::MutexLocker take(&mu_);
|
| - if (result == PP_OK) {
|
| - NaClLog(4, "StreamAsFile_MainThreadContinuation: GetFileInfo(%s)\n",
|
| - p->url.c_str());
|
| - *p->file_info = plugin_->GetFileInfo(p->url);
|
| + {
|
| + nacl::MutexLocker take(&mu_);
|
| + if (result == PP_OK) {
|
| + NaClLog(4, "StreamAsFile_MainThreadContinuation: GetFileInfo(%s)\n",
|
| + p->url.c_str());
|
| + *p->file_info = plugin_->GetFileInfo(p->url);
|
|
|
| - NaClLog(4,
|
| - "StreamAsFile_MainThreadContinuation: PP_OK, desc %d\n",
|
| - p->file_info->desc);
|
| - } else {
|
| - NaClLog(4,
|
| - "StreamAsFile_MainThreadContinuation: !PP_OK, setting desc -1\n");
|
| - p->file_info->desc = -1;
|
| + NaClLog(4,
|
| + "StreamAsFile_MainThreadContinuation: PP_OK, desc %d\n",
|
| + p->file_info->desc);
|
| + } else {
|
| + NaClLog(
|
| + 4,
|
| + "StreamAsFile_MainThreadContinuation: !PP_OK, setting desc -1\n");
|
| + p->file_info->desc = -1;
|
| + }
|
| + *p->op_complete_ptr = true;
|
| + NaClXCondVarBroadcast(&cv_);
|
| }
|
| - *p->op_complete_ptr = true;
|
| - NaClXCondVarBroadcast(&cv_);
|
| + p->MaybeRunCallback(PP_OK);
|
| }
|
|
|
| bool PluginReverseInterface::CloseManifestEntry(int32_t desc) {
|
|
|