OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "pnacl_translation_resource_host.h" | 5 #include "pnacl_translation_resource_host.h" |
6 | 6 |
7 #ifndef DISABLE_NACL | 7 #ifndef DISABLE_NACL |
8 #include "components/nacl/common/nacl_host_messages.h" | 8 #include "components/nacl/common/nacl_host_messages.h" |
9 #include "ppapi/c/pp_errors.h" | 9 #include "ppapi/c/pp_errors.h" |
10 #include "ppapi/shared_impl/ppapi_globals.h" | 10 #include "ppapi/shared_impl/ppapi_globals.h" |
11 | 11 |
12 using ppapi::TrackedCallback; | 12 using ppapi::TrackedCallback; |
13 using ppapi::PpapiGlobals; | 13 using ppapi::PpapiGlobals; |
14 | 14 |
15 PnaclTranslationResourceHost::CacheRequestInfo::CacheRequestInfo( | 15 PnaclTranslationResourceHost::CacheRequestInfo::CacheRequestInfo( |
16 PP_Bool* hit, | 16 PP_Bool* hit, |
17 PP_FileHandle* handle, | 17 PP_FileHandle* handle, |
18 scoped_refptr<TrackedCallback> cb) | 18 scoped_refptr<TrackedCallback> cb) |
19 : is_hit(hit), file_handle(handle), callback(cb) {} | 19 : is_hit(hit), file_handle(handle), callback(cb) {} |
20 | 20 |
21 PnaclTranslationResourceHost::CacheRequestInfo::~CacheRequestInfo() {} | 21 PnaclTranslationResourceHost::CacheRequestInfo::~CacheRequestInfo() {} |
22 | 22 |
23 PnaclTranslationResourceHost::PnaclTranslationResourceHost( | 23 PnaclTranslationResourceHost::PnaclTranslationResourceHost( |
24 const scoped_refptr<base::MessageLoopProxy>& io_message_loop) | 24 const scoped_refptr<base::MessageLoopProxy>& io_message_loop) |
25 : io_message_loop_(io_message_loop), channel_(NULL) {} | 25 : io_message_loop_(io_message_loop), channel_(NULL) {} |
26 | 26 |
27 PnaclTranslationResourceHost::~PnaclTranslationResourceHost() { | 27 PnaclTranslationResourceHost::~PnaclTranslationResourceHost() { |
| 28 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
28 CleanupCacheRequests(); | 29 CleanupCacheRequests(); |
| 30 CleanupEnsurePnaclRequests(); |
29 } | 31 } |
30 | 32 |
31 void PnaclTranslationResourceHost::OnFilterAdded(IPC::Channel* channel) { | 33 void PnaclTranslationResourceHost::OnFilterAdded(IPC::Channel* channel) { |
32 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 34 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
33 channel_ = channel; | 35 channel_ = channel; |
34 } | 36 } |
35 | 37 |
36 void PnaclTranslationResourceHost::OnFilterRemoved() { | 38 void PnaclTranslationResourceHost::OnFilterRemoved() { |
37 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 39 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
38 channel_ = NULL; | 40 channel_ = NULL; |
39 } | 41 } |
40 | 42 |
41 void PnaclTranslationResourceHost::OnChannelClosing() { | 43 void PnaclTranslationResourceHost::OnChannelClosing() { |
42 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 44 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
43 channel_ = NULL; | 45 channel_ = NULL; |
44 } | 46 } |
45 | 47 |
46 bool PnaclTranslationResourceHost::OnMessageReceived( | 48 bool PnaclTranslationResourceHost::OnMessageReceived( |
47 const IPC::Message& message) { | 49 const IPC::Message& message) { |
48 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 50 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
49 bool handled = true; | 51 bool handled = true; |
50 IPC_BEGIN_MESSAGE_MAP(PnaclTranslationResourceHost, message) | 52 IPC_BEGIN_MESSAGE_MAP(PnaclTranslationResourceHost, message) |
51 IPC_MESSAGE_HANDLER(NaClViewMsg_NexeTempFileReply, OnNexeTempFileReply) | 53 IPC_MESSAGE_HANDLER(NaClViewMsg_NexeTempFileReply, OnNexeTempFileReply) |
| 54 IPC_MESSAGE_HANDLER(NaClViewMsg_EnsurePnaclInstalledReply, |
| 55 OnEnsurePnaclInstalledReply) |
52 IPC_MESSAGE_UNHANDLED(handled = false) | 56 IPC_MESSAGE_UNHANDLED(handled = false) |
53 IPC_END_MESSAGE_MAP() | 57 IPC_END_MESSAGE_MAP() |
54 return handled; | 58 return handled; |
55 } | 59 } |
56 | 60 |
57 void PnaclTranslationResourceHost::RequestNexeFd( | 61 void PnaclTranslationResourceHost::RequestNexeFd( |
58 int render_view_id, | 62 int render_view_id, |
59 PP_Instance instance, | 63 PP_Instance instance, |
60 const nacl::PnaclCacheInfo& cache_info, | 64 const nacl::PnaclCacheInfo& cache_info, |
61 PP_Bool* is_hit, | 65 PP_Bool* is_hit, |
62 PP_FileHandle* file_handle, | 66 PP_FileHandle* file_handle, |
63 scoped_refptr<TrackedCallback> callback) { | 67 scoped_refptr<TrackedCallback> callback) { |
| 68 DCHECK(PpapiGlobals::Get()-> |
| 69 GetMainThreadMessageLoop()->BelongsToCurrentThread()); |
| 70 io_message_loop_->PostTask( |
| 71 FROM_HERE, |
| 72 base::Bind(&PnaclTranslationResourceHost::SendRequestNexeFd, |
| 73 this, |
| 74 render_view_id, |
| 75 instance, |
| 76 cache_info, |
| 77 is_hit, |
| 78 file_handle, |
| 79 callback)); |
| 80 return; |
| 81 } |
64 | 82 |
65 if (!io_message_loop_->BelongsToCurrentThread()) { | 83 void PnaclTranslationResourceHost::SendRequestNexeFd( |
66 io_message_loop_->PostTask( | 84 int render_view_id, |
67 FROM_HERE, | 85 PP_Instance instance, |
68 base::Bind(&PnaclTranslationResourceHost::RequestNexeFd, | 86 const nacl::PnaclCacheInfo& cache_info, |
69 this, | 87 PP_Bool* is_hit, |
70 render_view_id, | 88 PP_FileHandle* file_handle, |
71 instance, | 89 scoped_refptr<TrackedCallback> callback) { |
72 cache_info, | 90 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
73 is_hit, | |
74 file_handle, | |
75 callback)); | |
76 return; | |
77 } | |
78 if (!channel_ || !channel_->Send(new NaClHostMsg_NexeTempFileRequest( | 91 if (!channel_ || !channel_->Send(new NaClHostMsg_NexeTempFileRequest( |
79 render_view_id, instance, cache_info))) { | 92 render_view_id, instance, cache_info))) { |
80 PpapiGlobals::Get()->GetMainThreadMessageLoop() | 93 PpapiGlobals::Get()->GetMainThreadMessageLoop() |
81 ->PostTask(FROM_HERE, | 94 ->PostTask(FROM_HERE, |
82 base::Bind(&TrackedCallback::Run, | 95 base::Bind(&TrackedCallback::Run, |
83 callback, | 96 callback, |
84 static_cast<int32_t>(PP_ERROR_FAILED))); | 97 static_cast<int32_t>(PP_ERROR_FAILED))); |
85 return; | 98 return; |
86 } | 99 } |
87 pending_cache_requests_.insert(std::make_pair( | 100 pending_cache_requests_.insert(std::make_pair( |
88 instance, CacheRequestInfo(is_hit, file_handle, callback))); | 101 instance, CacheRequestInfo(is_hit, file_handle, callback))); |
89 } | 102 } |
90 | 103 |
91 void PnaclTranslationResourceHost::ReportTranslationFinished( | 104 void PnaclTranslationResourceHost::ReportTranslationFinished( |
92 PP_Instance instance) { | 105 PP_Instance instance) { |
93 if (!io_message_loop_->BelongsToCurrentThread()) { | 106 DCHECK(PpapiGlobals::Get()-> |
94 io_message_loop_->PostTask( | 107 GetMainThreadMessageLoop()->BelongsToCurrentThread()); |
95 FROM_HERE, | 108 io_message_loop_->PostTask( |
96 base::Bind(&PnaclTranslationResourceHost::ReportTranslationFinished, | 109 FROM_HERE, |
97 this, | 110 base::Bind(&PnaclTranslationResourceHost::SendReportTranslationFinished, |
98 instance)); | 111 this, |
99 return; | 112 instance)); |
100 } | 113 return; |
| 114 } |
| 115 |
| 116 void PnaclTranslationResourceHost::SendReportTranslationFinished( |
| 117 PP_Instance instance) { |
| 118 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
101 // If the channel is closed or we have been detached, we are probably shutting | 119 // If the channel is closed or we have been detached, we are probably shutting |
102 // down, so just don't send anything. | 120 // down, so just don't send anything. |
103 if (!channel_) | 121 if (!channel_) |
104 return; | 122 return; |
105 DCHECK(pending_cache_requests_.count(instance) == 0); | 123 DCHECK(pending_cache_requests_.count(instance) == 0); |
106 channel_->Send(new NaClHostMsg_ReportTranslationFinished(instance)); | 124 channel_->Send(new NaClHostMsg_ReportTranslationFinished(instance)); |
107 } | 125 } |
108 | 126 |
109 void PnaclTranslationResourceHost::OnNexeTempFileReply( | 127 void PnaclTranslationResourceHost::OnNexeTempFileReply( |
110 PP_Instance instance, | 128 PP_Instance instance, |
111 bool is_hit, | 129 bool is_hit, |
112 IPC::PlatformFileForTransit file) { | 130 IPC::PlatformFileForTransit file) { |
| 131 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
113 CacheRequestInfoMap::iterator it = pending_cache_requests_.find(instance); | 132 CacheRequestInfoMap::iterator it = pending_cache_requests_.find(instance); |
114 int32_t status = PP_ERROR_FAILED; | 133 int32_t status = PP_ERROR_FAILED; |
115 // Handle the expected successful case first. | 134 // Handle the expected successful case first. |
116 if (it != pending_cache_requests_.end() && | 135 if (it != pending_cache_requests_.end() && |
117 !(file == IPC::InvalidPlatformFileForTransit()) && | 136 !(file == IPC::InvalidPlatformFileForTransit()) && |
118 TrackedCallback::IsPending(it->second.callback)) { | 137 TrackedCallback::IsPending(it->second.callback)) { |
119 *it->second.is_hit = PP_FromBool(is_hit); | 138 *it->second.is_hit = PP_FromBool(is_hit); |
120 *it->second.file_handle = IPC::PlatformFileForTransitToPlatformFile(file); | 139 *it->second.file_handle = IPC::PlatformFileForTransitToPlatformFile(file); |
121 status = PP_OK; | 140 status = PP_OK; |
122 } | 141 } |
123 if (it == pending_cache_requests_.end()) { | 142 if (it == pending_cache_requests_.end()) { |
124 DLOG(ERROR) << "Could not find pending request for reply"; | 143 DLOG(ERROR) << "Could not find pending request for reply"; |
125 } else { | 144 } else { |
126 PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | 145 PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
127 FROM_HERE, | 146 FROM_HERE, |
128 base::Bind(&TrackedCallback::Run, it->second.callback, status)); | 147 base::Bind(&TrackedCallback::Run, it->second.callback, status)); |
129 pending_cache_requests_.erase(it); | 148 pending_cache_requests_.erase(it); |
130 } | 149 } |
131 if (file == IPC::InvalidPlatformFileForTransit()) { | 150 if (file == IPC::InvalidPlatformFileForTransit()) { |
132 DLOG(ERROR) << "Got invalid platformfilefortransit"; | 151 DLOG(ERROR) << "Got invalid platformfilefortransit"; |
133 } else if (status != PP_OK) { | 152 } else if (status != PP_OK) { |
134 base::ClosePlatformFile(IPC::PlatformFileForTransitToPlatformFile(file)); | 153 base::ClosePlatformFile(IPC::PlatformFileForTransitToPlatformFile(file)); |
135 } | 154 } |
136 } | 155 } |
137 | 156 |
138 void PnaclTranslationResourceHost::CleanupCacheRequests() { | 157 void PnaclTranslationResourceHost::CleanupCacheRequests() { |
| 158 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
139 for (CacheRequestInfoMap::iterator it = pending_cache_requests_.begin(); | 159 for (CacheRequestInfoMap::iterator it = pending_cache_requests_.begin(); |
140 it != pending_cache_requests_.end(); | 160 it != pending_cache_requests_.end(); |
141 ++it) { | 161 ++it) { |
142 it->second.callback->PostAbort(); | 162 it->second.callback->PostAbort(); |
143 } | 163 } |
144 pending_cache_requests_.clear(); | 164 pending_cache_requests_.clear(); |
145 } | 165 } |
146 | 166 |
| 167 void PnaclTranslationResourceHost::EnsurePnaclInstalled( |
| 168 PP_Instance instance, |
| 169 scoped_refptr<TrackedCallback> callback) { |
| 170 DCHECK(PpapiGlobals::Get()-> |
| 171 GetMainThreadMessageLoop()->BelongsToCurrentThread()); |
| 172 io_message_loop_->PostTask( |
| 173 FROM_HERE, |
| 174 base::Bind(&PnaclTranslationResourceHost::SendEnsurePnaclInstalled, |
| 175 this, instance, callback)); |
| 176 return; |
| 177 } |
| 178 |
| 179 void PnaclTranslationResourceHost::SendEnsurePnaclInstalled( |
| 180 PP_Instance instance, |
| 181 scoped_refptr<TrackedCallback> callback) { |
| 182 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
| 183 // If a request is already in, just queue this one and wait for notification. |
| 184 // Hope that the request is not canceled. |
| 185 if (pending_ensure_pnacl_requests_.size() > 0) { |
| 186 pending_ensure_pnacl_requests_.push_back(callback); |
| 187 return; |
| 188 } |
| 189 // Otherwise, try to send the request, then queue. |
| 190 if (!channel_ || !channel_->Send(new NaClHostMsg_EnsurePnaclInstalled( |
| 191 instance))) { |
| 192 PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
| 193 FROM_HERE, |
| 194 base::Bind(&TrackedCallback::Run, |
| 195 callback, |
| 196 static_cast<int32_t>(PP_ERROR_FAILED))); |
| 197 return; |
| 198 } |
| 199 pending_ensure_pnacl_requests_.push_back(callback); |
| 200 } |
| 201 |
| 202 void PnaclTranslationResourceHost::OnEnsurePnaclInstalledReply( |
| 203 PP_Instance instance, |
| 204 bool success) { |
| 205 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
| 206 // Broadcast to all listeners. |
| 207 for (EnsurePnaclInstalledList::iterator |
| 208 i = pending_ensure_pnacl_requests_.begin(), |
| 209 e = pending_ensure_pnacl_requests_.end(); |
| 210 i != e; ++i) { |
| 211 if (TrackedCallback::IsPending(*i)) { |
| 212 PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( |
| 213 FROM_HERE, |
| 214 base::Bind(&TrackedCallback::Run, |
| 215 *i, |
| 216 static_cast<int32_t>(success ? PP_OK : PP_ERROR_FAILED))); |
| 217 } |
| 218 } |
| 219 pending_ensure_pnacl_requests_.clear(); |
| 220 } |
| 221 |
| 222 void PnaclTranslationResourceHost::CleanupEnsurePnaclRequests() { |
| 223 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
| 224 for (EnsurePnaclInstalledList::iterator |
| 225 i = pending_ensure_pnacl_requests_.begin(), |
| 226 e = pending_ensure_pnacl_requests_.end(); |
| 227 i != e; ++i) { |
| 228 (*i)->PostAbort(); |
| 229 } |
| 230 pending_ensure_pnacl_requests_.clear(); |
| 231 } |
| 232 |
147 #endif // DISABLE_NACL | 233 #endif // DISABLE_NACL |
OLD | NEW |