summaryrefslogtreecommitdiffstats
path: root/components/nacl/renderer/pnacl_translation_resource_host.cc
diff options
context:
space:
mode:
Diffstat (limited to 'components/nacl/renderer/pnacl_translation_resource_host.cc')
-rw-r--r--components/nacl/renderer/pnacl_translation_resource_host.cc168
1 files changed, 168 insertions, 0 deletions
diff --git a/components/nacl/renderer/pnacl_translation_resource_host.cc b/components/nacl/renderer/pnacl_translation_resource_host.cc
new file mode 100644
index 0000000..0546c75
--- /dev/null
+++ b/components/nacl/renderer/pnacl_translation_resource_host.cc
@@ -0,0 +1,168 @@
+// Copyright 2013 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.
+
+#include "pnacl_translation_resource_host.h"
+
+#ifndef DISABLE_NACL
+#include "components/nacl/common/nacl_host_messages.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+
+using ppapi::TrackedCallback;
+using ppapi::PpapiGlobals;
+
+PnaclTranslationResourceHost::CacheRequestInfo::CacheRequestInfo(
+ PP_Bool* hit,
+ PP_FileHandle* handle,
+ scoped_refptr<TrackedCallback> cb)
+ : is_hit(hit), file_handle(handle), callback(cb) {}
+
+PnaclTranslationResourceHost::CacheRequestInfo::~CacheRequestInfo() {}
+
+PnaclTranslationResourceHost::PnaclTranslationResourceHost(
+ const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
+ : io_message_loop_(io_message_loop), channel_(NULL) {}
+
+PnaclTranslationResourceHost::~PnaclTranslationResourceHost() {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ CleanupCacheRequests();
+}
+
+void PnaclTranslationResourceHost::OnFilterAdded(IPC::Channel* channel) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ channel_ = channel;
+}
+
+void PnaclTranslationResourceHost::OnFilterRemoved() {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ channel_ = NULL;
+}
+
+void PnaclTranslationResourceHost::OnChannelClosing() {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ channel_ = NULL;
+}
+
+bool PnaclTranslationResourceHost::OnMessageReceived(
+ const IPC::Message& message) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(PnaclTranslationResourceHost, message)
+ IPC_MESSAGE_HANDLER(NaClViewMsg_NexeTempFileReply, OnNexeTempFileReply)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void PnaclTranslationResourceHost::RequestNexeFd(
+ int render_view_id,
+ PP_Instance instance,
+ const nacl::PnaclCacheInfo& cache_info,
+ PP_Bool* is_hit,
+ PP_FileHandle* file_handle,
+ scoped_refptr<TrackedCallback> callback) {
+ DCHECK(PpapiGlobals::Get()->
+ GetMainThreadMessageLoop()->BelongsToCurrentThread());
+ io_message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&PnaclTranslationResourceHost::SendRequestNexeFd,
+ this,
+ render_view_id,
+ instance,
+ cache_info,
+ is_hit,
+ file_handle,
+ callback));
+ return;
+}
+
+void PnaclTranslationResourceHost::SendRequestNexeFd(
+ int render_view_id,
+ PP_Instance instance,
+ const nacl::PnaclCacheInfo& cache_info,
+ PP_Bool* is_hit,
+ PP_FileHandle* file_handle,
+ scoped_refptr<TrackedCallback> callback) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ if (!channel_ || !channel_->Send(new NaClHostMsg_NexeTempFileRequest(
+ render_view_id, instance, cache_info))) {
+ PpapiGlobals::Get()->GetMainThreadMessageLoop()
+ ->PostTask(FROM_HERE,
+ base::Bind(&TrackedCallback::Run,
+ callback,
+ static_cast<int32_t>(PP_ERROR_FAILED)));
+ return;
+ }
+ pending_cache_requests_.insert(std::make_pair(
+ instance, CacheRequestInfo(is_hit, file_handle, callback)));
+}
+
+void PnaclTranslationResourceHost::ReportTranslationFinished(
+ PP_Instance instance,
+ PP_Bool success) {
+ DCHECK(PpapiGlobals::Get()->
+ GetMainThreadMessageLoop()->BelongsToCurrentThread());
+ io_message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&PnaclTranslationResourceHost::SendReportTranslationFinished,
+ this,
+ instance,
+ success));
+ return;
+}
+
+void PnaclTranslationResourceHost::SendReportTranslationFinished(
+ PP_Instance instance,
+ PP_Bool success) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ // If the channel is closed or we have been detached, we are probably shutting
+ // down, so just don't send anything.
+ if (!channel_)
+ return;
+ DCHECK(pending_cache_requests_.count(instance) == 0);
+ channel_->Send(new NaClHostMsg_ReportTranslationFinished(instance,
+ PP_ToBool(success)));
+}
+
+void PnaclTranslationResourceHost::OnNexeTempFileReply(
+ PP_Instance instance,
+ bool is_hit,
+ IPC::PlatformFileForTransit file) {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ CacheRequestInfoMap::iterator it = pending_cache_requests_.find(instance);
+ int32_t status = PP_ERROR_FAILED;
+ // Handle the expected successful case first.
+ if (it != pending_cache_requests_.end() &&
+ !(file == IPC::InvalidPlatformFileForTransit()) &&
+ TrackedCallback::IsPending(it->second.callback)) {
+ *it->second.is_hit = PP_FromBool(is_hit);
+ *it->second.file_handle = IPC::PlatformFileForTransitToPlatformFile(file);
+ status = PP_OK;
+ }
+ if (it == pending_cache_requests_.end()) {
+ DLOG(ERROR) << "Could not find pending request for reply";
+ } else {
+ PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
+ FROM_HERE,
+ base::Bind(&TrackedCallback::Run, it->second.callback, status));
+ pending_cache_requests_.erase(it);
+ }
+ if (file == IPC::InvalidPlatformFileForTransit()) {
+ DLOG(ERROR) << "Got invalid platformfilefortransit";
+ } else if (status != PP_OK) {
+ base::ClosePlatformFile(IPC::PlatformFileForTransitToPlatformFile(file));
+ }
+}
+
+void PnaclTranslationResourceHost::CleanupCacheRequests() {
+ DCHECK(io_message_loop_->BelongsToCurrentThread());
+ for (CacheRequestInfoMap::iterator it = pending_cache_requests_.begin();
+ it != pending_cache_requests_.end();
+ ++it) {
+ it->second.callback->PostAbort();
+ }
+ pending_cache_requests_.clear();
+}
+
+#endif // DISABLE_NACL