| 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 |