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 7406e797a6b06217522fdc7f6b024e946febf2eb..d7c8683148f2d11a57b9f1003efc1b2811dac4c5 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 |
@@ -265,10 +353,13 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation( |
NaClLog(4, "OpenManifestEntry_MainThreadContinuation: ResolveKey failed\n"); |
// 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, |
@@ -281,10 +372,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; |
} |
@@ -302,14 +396,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; |
} |
@@ -319,6 +416,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, |
@@ -346,22 +446,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) { |