• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "pnacl_translation_resource_host.h"
6 
7 #include "components/nacl/common/nacl_host_messages.h"
8 #include "ppapi/c/pp_errors.h"
9 #include "ppapi/shared_impl/ppapi_globals.h"
10 
11 using ppapi::TrackedCallback;
12 using ppapi::PpapiGlobals;
13 
CacheRequestInfo(PP_Bool * hit,PP_FileHandle * handle,scoped_refptr<TrackedCallback> cb)14 PnaclTranslationResourceHost::CacheRequestInfo::CacheRequestInfo(
15     PP_Bool* hit,
16     PP_FileHandle* handle,
17     scoped_refptr<TrackedCallback> cb)
18     : is_hit(hit), file_handle(handle), callback(cb) {}
19 
~CacheRequestInfo()20 PnaclTranslationResourceHost::CacheRequestInfo::~CacheRequestInfo() {}
21 
PnaclTranslationResourceHost(const scoped_refptr<base::MessageLoopProxy> & io_message_loop)22 PnaclTranslationResourceHost::PnaclTranslationResourceHost(
23     const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
24     : io_message_loop_(io_message_loop), sender_(NULL) {}
25 
~PnaclTranslationResourceHost()26 PnaclTranslationResourceHost::~PnaclTranslationResourceHost() {
27   DCHECK(io_message_loop_->BelongsToCurrentThread());
28   CleanupCacheRequests();
29 }
30 
OnFilterAdded(IPC::Sender * sender)31 void PnaclTranslationResourceHost::OnFilterAdded(IPC::Sender* sender) {
32   DCHECK(io_message_loop_->BelongsToCurrentThread());
33   sender_ = sender;
34 }
35 
OnFilterRemoved()36 void PnaclTranslationResourceHost::OnFilterRemoved() {
37   DCHECK(io_message_loop_->BelongsToCurrentThread());
38   sender_ = NULL;
39 }
40 
OnChannelClosing()41 void PnaclTranslationResourceHost::OnChannelClosing() {
42   DCHECK(io_message_loop_->BelongsToCurrentThread());
43   sender_ = NULL;
44 }
45 
OnMessageReceived(const IPC::Message & message)46 bool PnaclTranslationResourceHost::OnMessageReceived(
47     const IPC::Message& message) {
48   DCHECK(io_message_loop_->BelongsToCurrentThread());
49   bool handled = true;
50   IPC_BEGIN_MESSAGE_MAP(PnaclTranslationResourceHost, message)
51     IPC_MESSAGE_HANDLER(NaClViewMsg_NexeTempFileReply, OnNexeTempFileReply)
52     IPC_MESSAGE_UNHANDLED(handled = false)
53   IPC_END_MESSAGE_MAP()
54   return handled;
55 }
56 
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)57 void PnaclTranslationResourceHost::RequestNexeFd(
58     int render_view_id,
59     PP_Instance instance,
60     const nacl::PnaclCacheInfo& cache_info,
61     PP_Bool* is_hit,
62     PP_FileHandle* file_handle,
63     scoped_refptr<TrackedCallback> callback) {
64   DCHECK(PpapiGlobals::Get()->
65          GetMainThreadMessageLoop()->BelongsToCurrentThread());
66   io_message_loop_->PostTask(
67       FROM_HERE,
68       base::Bind(&PnaclTranslationResourceHost::SendRequestNexeFd,
69                  this,
70                  render_view_id,
71                  instance,
72                  cache_info,
73                  is_hit,
74                  file_handle,
75                  callback));
76   return;
77 }
78 
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)79 void PnaclTranslationResourceHost::SendRequestNexeFd(
80     int render_view_id,
81     PP_Instance instance,
82     const nacl::PnaclCacheInfo& cache_info,
83     PP_Bool* is_hit,
84     PP_FileHandle* file_handle,
85     scoped_refptr<TrackedCallback> callback) {
86   DCHECK(io_message_loop_->BelongsToCurrentThread());
87   if (!sender_ || !sender_->Send(new NaClHostMsg_NexeTempFileRequest(
88           render_view_id, instance, cache_info))) {
89     PpapiGlobals::Get()->GetMainThreadMessageLoop()
90         ->PostTask(FROM_HERE,
91                    base::Bind(&TrackedCallback::Run,
92                               callback,
93                               static_cast<int32_t>(PP_ERROR_FAILED)));
94     return;
95   }
96   pending_cache_requests_.insert(std::make_pair(
97       instance, CacheRequestInfo(is_hit, file_handle, callback)));
98 }
99 
ReportTranslationFinished(PP_Instance instance,PP_Bool success)100 void PnaclTranslationResourceHost::ReportTranslationFinished(
101     PP_Instance instance,
102     PP_Bool success) {
103   DCHECK(PpapiGlobals::Get()->
104          GetMainThreadMessageLoop()->BelongsToCurrentThread());
105   io_message_loop_->PostTask(
106       FROM_HERE,
107       base::Bind(&PnaclTranslationResourceHost::SendReportTranslationFinished,
108                  this,
109                  instance,
110                  success));
111   return;
112 }
113 
SendReportTranslationFinished(PP_Instance instance,PP_Bool success)114 void PnaclTranslationResourceHost::SendReportTranslationFinished(
115     PP_Instance instance,
116     PP_Bool success) {
117   DCHECK(io_message_loop_->BelongsToCurrentThread());
118   // If the sender is closed or we have been detached, we are probably shutting
119   // down, so just don't send anything.
120   if (!sender_)
121     return;
122   DCHECK(pending_cache_requests_.count(instance) == 0);
123   sender_->Send(new NaClHostMsg_ReportTranslationFinished(instance,
124                                                           PP_ToBool(success)));
125 }
126 
OnNexeTempFileReply(PP_Instance instance,bool is_hit,IPC::PlatformFileForTransit file)127 void PnaclTranslationResourceHost::OnNexeTempFileReply(
128     PP_Instance instance,
129     bool is_hit,
130     IPC::PlatformFileForTransit file) {
131   DCHECK(io_message_loop_->BelongsToCurrentThread());
132   base::File base_file = IPC::PlatformFileForTransitToFile(file);
133   CacheRequestInfoMap::iterator it = pending_cache_requests_.find(instance);
134   int32_t status = PP_ERROR_FAILED;
135   // Handle the expected successful case first.
136   if (it != pending_cache_requests_.end() && base_file.IsValid() &&
137       TrackedCallback::IsPending(it->second.callback)) {
138     *it->second.is_hit = PP_FromBool(is_hit);
139     *it->second.file_handle = base_file.TakePlatformFile();
140     status = PP_OK;
141   }
142   if (it == pending_cache_requests_.end()) {
143     DLOG(ERROR) << "Could not find pending request for reply";
144   } else {
145     PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
146         FROM_HERE,
147         base::Bind(&TrackedCallback::Run, it->second.callback, status));
148     pending_cache_requests_.erase(it);
149   }
150   if (!base_file.IsValid()) {
151     DLOG(ERROR) << "Got invalid platformfilefortransit";
152   }
153 }
154 
CleanupCacheRequests()155 void PnaclTranslationResourceHost::CleanupCacheRequests() {
156   DCHECK(io_message_loop_->BelongsToCurrentThread());
157   for (CacheRequestInfoMap::iterator it = pending_cache_requests_.begin();
158        it != pending_cache_requests_.end();
159        ++it) {
160     it->second.callback->PostAbort();
161   }
162   pending_cache_requests_.clear();
163 }
164