diff options
Diffstat (limited to 'ppapi')
22 files changed, 111 insertions, 161 deletions
diff --git a/ppapi/proxy/file_chooser_resource.cc b/ppapi/proxy/file_chooser_resource.cc index 5c11012..6135aaa 100644 --- a/ppapi/proxy/file_chooser_resource.cc +++ b/ppapi/proxy/file_chooser_resource.cc @@ -118,7 +118,7 @@ void FileChooserResource::OnPluginMsgShowReply( } // Notify the plugin of the new data. - TrackedCallback::ClearAndRun(&callback_, params.result()); + callback_->Run(params.result()); // DANGER: May delete |this|! } diff --git a/ppapi/proxy/flash_device_id_resource.cc b/ppapi/proxy/flash_device_id_resource.cc index d7174bd..493ebda 100644 --- a/ppapi/proxy/flash_device_id_resource.cc +++ b/ppapi/proxy/flash_device_id_resource.cc @@ -54,7 +54,7 @@ void FlashDeviceIDResource::OnPluginMsgGetDeviceIDReply( else *dest_ = PP_MakeUndefined(); dest_ = NULL; - TrackedCallback::ClearAndRun(&callback_, params.result()); + callback_->Run(params.result()); } } // namespace proxy diff --git a/ppapi/proxy/ppb_broker_proxy.cc b/ppapi/proxy/ppb_broker_proxy.cc index 9800d32..f7818dc 100644 --- a/ppapi/proxy/ppb_broker_proxy.cc +++ b/ppapi/proxy/ppb_broker_proxy.cc @@ -108,7 +108,7 @@ void Broker::ConnectComplete(IPC::PlatformFileForTransit socket_handle, return; } - TrackedCallback::ClearAndRun(¤t_connect_callback_, result); + current_connect_callback_->Run(result); } PPB_Broker_Proxy::PPB_Broker_Proxy(Dispatcher* dispatcher) diff --git a/ppapi/proxy/ppb_file_system_proxy.cc b/ppapi/proxy/ppb_file_system_proxy.cc index 4619a1f..1d8747a 100644 --- a/ppapi/proxy/ppb_file_system_proxy.cc +++ b/ppapi/proxy/ppb_file_system_proxy.cc @@ -94,7 +94,7 @@ PP_FileSystemType FileSystem::GetType() { } void FileSystem::OpenComplete(int32_t result) { - TrackedCallback::ClearAndRun(¤t_open_callback_, result); + current_open_callback_->Run(result); } PPB_FileSystem_Proxy::PPB_FileSystem_Proxy(Dispatcher* dispatcher) diff --git a/ppapi/proxy/ppb_flash_menu_proxy.cc b/ppapi/proxy/ppb_flash_menu_proxy.cc index 9cc8d63..a499e51 100644 --- a/ppapi/proxy/ppb_flash_menu_proxy.cc +++ b/ppapi/proxy/ppb_flash_menu_proxy.cc @@ -70,7 +70,7 @@ int32_t FlashMenu::Show(const struct PP_Point* location, void FlashMenu::ShowACK(int32_t selected_id, int32_t result) { *selected_id_ptr_ = selected_id; - TrackedCallback::ClearAndRun(&callback_, result); + callback_->Run(result); } PPB_Flash_Menu_Proxy::PPB_Flash_Menu_Proxy(Dispatcher* dispatcher) diff --git a/ppapi/proxy/ppb_graphics_2d_proxy.cc b/ppapi/proxy/ppb_graphics_2d_proxy.cc index 47abef9..23c90fc 100644 --- a/ppapi/proxy/ppb_graphics_2d_proxy.cc +++ b/ppapi/proxy/ppb_graphics_2d_proxy.cc @@ -65,7 +65,7 @@ class Graphics2D : public Resource, public thunk::PPB_Graphics2D_API { float scale_; // In the plugin, this is the current callback set for Flushes. When the - // pointer is non-NULL, we're waiting for a flush ACK. + // callback is pending, we're waiting for a flush ACK. scoped_refptr<TrackedCallback> current_flush_callback_; DISALLOW_COPY_AND_ASSIGN(Graphics2D); @@ -167,7 +167,7 @@ int32_t Graphics2D::Flush(scoped_refptr<TrackedCallback> callback, } void Graphics2D::FlushACK(int32_t result_code) { - TrackedCallback::ClearAndRun(¤t_flush_callback_, result_code); + current_flush_callback_->Run(result_code); } PPB_Graphics2D_Proxy::PPB_Graphics2D_Proxy(Dispatcher* dispatcher) diff --git a/ppapi/proxy/ppb_instance_proxy.cc b/ppapi/proxy/ppb_instance_proxy.cc index 90a33f4..f8cd310 100644 --- a/ppapi/proxy/ppb_instance_proxy.cc +++ b/ppapi/proxy/ppb_instance_proxy.cc @@ -1171,7 +1171,7 @@ void PPB_Instance_Proxy::OnPluginMsgMouseLockComplete(PP_Instance instance, NOTREACHED(); return; } - TrackedCallback::ClearAndRun(&(data->mouse_lock_callback), result); + data->mouse_lock_callback->Run(result); } void PPB_Instance_Proxy::MouseLockCompleteInHost(int32_t result, diff --git a/ppapi/proxy/ppb_talk_private_proxy.cc b/ppapi/proxy/ppb_talk_private_proxy.cc index 6297fa3..7c34185c 100644 --- a/ppapi/proxy/ppb_talk_private_proxy.cc +++ b/ppapi/proxy/ppb_talk_private_proxy.cc @@ -49,7 +49,7 @@ class Talk : public Resource, public thunk::PPB_Talk_Private_API { } void GotCompletion(int32_t result) { - TrackedCallback::ClearAndRun(&callback_, result); + callback_->Run(result); } private: diff --git a/ppapi/proxy/ppb_tcp_server_socket_private_proxy.cc b/ppapi/proxy/ppb_tcp_server_socket_private_proxy.cc index 5e6557b..a98d4a7 100644 --- a/ppapi/proxy/ppb_tcp_server_socket_private_proxy.cc +++ b/ppapi/proxy/ppb_tcp_server_socket_private_proxy.cc @@ -78,8 +78,7 @@ void TCPServerSocket::OnAcceptCompleted( } tcp_socket_buffer_ = NULL; - TrackedCallback::ClearAndRun(&accept_callback_, - succeeded ? PP_OK : PP_ERROR_FAILED); + accept_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED); } void TCPServerSocket::SendListen(const PP_NetAddress_Private& addr, diff --git a/ppapi/proxy/ppb_url_loader_proxy.cc b/ppapi/proxy/ppb_url_loader_proxy.cc index 5c2439e..9398671 100644 --- a/ppapi/proxy/ppb_url_loader_proxy.cc +++ b/ppapi/proxy/ppb_url_loader_proxy.cc @@ -351,11 +351,11 @@ void URLLoader::ReadResponseBodyAck(int32 result, const char* data) { result = bytes_to_return; } - TrackedCallback::ClearAndRun(¤t_callback_, result); + current_callback_->Run(result); } void URLLoader::CallbackComplete(int32_t result) { - TrackedCallback::ClearAndRun(¤t_callback_, result); + current_callback_->Run(result); } void URLLoader::PopBuffer(void* output_buffer, int32_t output_size) { diff --git a/ppapi/proxy/printing_resource.cc b/ppapi/proxy/printing_resource.cc index 6c1ae17..d9be3b7 100644 --- a/ppapi/proxy/printing_resource.cc +++ b/ppapi/proxy/printing_resource.cc @@ -50,7 +50,7 @@ void PrintingResource::OnPluginMsgGetDefaultPrintSettingsReply( *settings_out = settings; // Notify the plugin of the new data. - TrackedCallback::ClearAndRun(&callback, params.result()); + callback->Run(params.result()); // DANGER: May delete |this|! } diff --git a/ppapi/proxy/websocket_resource.cc b/ppapi/proxy/websocket_resource.cc index eb4176f..c45de90 100644 --- a/ppapi/proxy/websocket_resource.cc +++ b/ppapi/proxy/websocket_resource.cc @@ -371,7 +371,7 @@ void WebSocketResource::OnPluginMsgConnectReply( protocol_ = new StringVar(protocol); url_ = new StringVar(url); } - TrackedCallback::ClearAndRun(&connect_callback_, params.result()); + connect_callback_->Run(params.result()); } void WebSocketResource::OnPluginMsgCloseReply( @@ -412,7 +412,7 @@ void WebSocketResource::OnPluginMsgReceiveTextReply( if (!TrackedCallback::IsPending(receive_callback_)) return; - TrackedCallback::ClearAndRun(&receive_callback_, DoReceive()); + receive_callback_->Run(DoReceive()); } void WebSocketResource::OnPluginMsgReceiveBinaryReply( @@ -432,7 +432,7 @@ void WebSocketResource::OnPluginMsgReceiveBinaryReply( if (!TrackedCallback::IsPending(receive_callback_)) return; - TrackedCallback::ClearAndRun(&receive_callback_, DoReceive()); + receive_callback_->Run(DoReceive()); } void WebSocketResource::OnPluginMsgErrorReply( @@ -445,7 +445,7 @@ void WebSocketResource::OnPluginMsgErrorReply( // No more text or binary messages will be received. If there is ongoing // ReceiveMessage(), we must invoke the callback with error code here. receive_callback_var_ = NULL; - TrackedCallback::ClearAndRun(&receive_callback_, PP_ERROR_FAILED); + receive_callback_->Run(PP_ERROR_FAILED); } void WebSocketResource::OnPluginMsgBufferedAmountReply( diff --git a/ppapi/shared_impl/ppb_audio_input_shared.cc b/ppapi/shared_impl/ppb_audio_input_shared.cc index 4ea3e71..0814883 100644 --- a/ppapi/shared_impl/ppb_audio_input_shared.cc +++ b/ppapi/shared_impl/ppb_audio_input_shared.cc @@ -140,7 +140,7 @@ void PPB_AudioInput_Shared::OnEnumerateDevicesComplete( } devices_ = NULL; - TrackedCallback::ClearAndRun(&enumerate_devices_callback_, result); + enumerate_devices_callback_->Run(result); } void PPB_AudioInput_Shared::OnOpenComplete( @@ -160,7 +160,7 @@ void PPB_AudioInput_Shared::OnOpenComplete( // The callback may have been aborted by Close(). if (TrackedCallback::IsPending(open_callback_)) - TrackedCallback::ClearAndRun(&open_callback_, result); + open_callback_->Run(result); } // static diff --git a/ppapi/shared_impl/ppb_graphics_3d_shared.cc b/ppapi/shared_impl/ppb_graphics_3d_shared.cc index eabc646..0278c42 100644 --- a/ppapi/shared_impl/ppb_graphics_3d_shared.cc +++ b/ppapi/shared_impl/ppb_graphics_3d_shared.cc @@ -89,7 +89,7 @@ void PPB_Graphics3D_Shared::UnmapTexSubImage2DCHROMIUM(const void* mem) { void PPB_Graphics3D_Shared::SwapBuffersACK(int32_t pp_error) { DCHECK(HasPendingSwap()); - TrackedCallback::ClearAndRun(&swap_callback_, pp_error); + swap_callback_->Run(pp_error); } bool PPB_Graphics3D_Shared::HasPendingSwap() const { diff --git a/ppapi/shared_impl/ppb_video_capture_shared.cc b/ppapi/shared_impl/ppb_video_capture_shared.cc index 962b060..2a51b95 100644 --- a/ppapi/shared_impl/ppb_video_capture_shared.cc +++ b/ppapi/shared_impl/ppb_video_capture_shared.cc @@ -124,7 +124,7 @@ void PPB_VideoCapture_Shared::OnEnumerateDevicesComplete( } devices_ = NULL; - TrackedCallback::ClearAndRun(&enumerate_devices_callback_, result); + enumerate_devices_callback_->Run(result); } void PPB_VideoCapture_Shared::OnOpenComplete(int32_t result) { @@ -134,7 +134,7 @@ void PPB_VideoCapture_Shared::OnOpenComplete(int32_t result) { // The callback may have been aborted by Close(), or the open operation is // completed synchronously. if (TrackedCallback::IsPending(open_callback_)) - TrackedCallback::ClearAndRun(&open_callback_, result); + open_callback_->Run(result); } bool PPB_VideoCapture_Shared::SetStatus(PP_VideoCaptureStatus_Dev status, diff --git a/ppapi/shared_impl/ppb_video_decoder_shared.cc b/ppapi/shared_impl/ppb_video_decoder_shared.cc index 441b0d2..e2547aa 100644 --- a/ppapi/shared_impl/ppb_video_decoder_shared.cc +++ b/ppapi/shared_impl/ppb_video_decoder_shared.cc @@ -50,7 +50,7 @@ void PPB_VideoDecoder_Shared::Destroy() { bool PPB_VideoDecoder_Shared::SetFlushCallback( scoped_refptr<TrackedCallback> callback) { - if (flush_callback_.get()) + if (TrackedCallback::IsPending(flush_callback_)) return false; flush_callback_ = callback; return true; @@ -72,11 +72,11 @@ bool PPB_VideoDecoder_Shared::SetBitstreamBufferCallback( } void PPB_VideoDecoder_Shared::RunFlushCallback(int32 result) { - TrackedCallback::ClearAndRun(&flush_callback_, result); + flush_callback_->Run(result); } void PPB_VideoDecoder_Shared::RunResetCallback(int32 result) { - TrackedCallback::ClearAndRun(&reset_callback_, result); + reset_callback_->Run(result); } void PPB_VideoDecoder_Shared::RunBitstreamBufferCallback( diff --git a/ppapi/shared_impl/private/ppb_host_resolver_shared.cc b/ppapi/shared_impl/private/ppb_host_resolver_shared.cc index 543b1c0..ba026dc 100644 --- a/ppapi/shared_impl/private/ppb_host_resolver_shared.cc +++ b/ppapi/shared_impl/private/ppb_host_resolver_shared.cc @@ -84,8 +84,7 @@ void PPB_HostResolver_Shared::OnResolveCompleted( net_address_list_.clear(); } - TrackedCallback::ClearAndRun(&resolve_callback_, - succeeded ? PP_OK : PP_ERROR_FAILED); + resolve_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED); } uint32 PPB_HostResolver_Shared::GenerateHostResolverID() { diff --git a/ppapi/shared_impl/private/ppb_tcp_server_socket_shared.cc b/ppapi/shared_impl/private/ppb_tcp_server_socket_shared.cc index f057da6..f816c62 100644 --- a/ppapi/shared_impl/private/ppb_tcp_server_socket_shared.cc +++ b/ppapi/shared_impl/private/ppb_tcp_server_socket_shared.cc @@ -78,9 +78,9 @@ void PPB_TCPServerSocket_Shared::StopListening() { SendStopListening(); socket_id_ = 0; - if (listen_callback_.get()) + if (TrackedCallback::IsPending(listen_callback_)) listen_callback_->PostAbort(); - if (accept_callback_.get()) + if (TrackedCallback::IsPending(accept_callback_)) accept_callback_->PostAbort(); tcp_socket_buffer_ = NULL; } @@ -98,7 +98,7 @@ void PPB_TCPServerSocket_Shared::OnListenCompleted(uint32 socket_id, state_ = LISTENING; } - TrackedCallback::ClearAndRun(&listen_callback_, status); + listen_callback_->Run(status); } } // namespace ppapi diff --git a/ppapi/shared_impl/private/tcp_socket_private_impl.cc b/ppapi/shared_impl/private/tcp_socket_private_impl.cc index c4a9a17..e2c645f0 100644 --- a/ppapi/shared_impl/private/tcp_socket_private_impl.cc +++ b/ppapi/shared_impl/private/tcp_socket_private_impl.cc @@ -232,8 +232,7 @@ void TCPSocketPrivateImpl::OnConnectCompleted( remote_addr_ = remote_addr; connection_state_ = CONNECTED; } - TrackedCallback::ClearAndRun(&connect_callback_, - succeeded ? PP_OK : PP_ERROR_FAILED); + connect_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED); } void TCPSocketPrivateImpl::OnSSLHandshakeCompleted( @@ -251,12 +250,12 @@ void TCPSocketPrivateImpl::OnSSLHandshakeCompleted( resource_type_, pp_instance(), certificate_fields); - TrackedCallback::ClearAndRun(&ssl_handshake_callback_, PP_OK); + ssl_handshake_callback_->Run(PP_OK); } else { // The resource might be released in the callback so we need to hold // a reference so we can Disconnect() first. AddRef(); - TrackedCallback::ClearAndRun(&ssl_handshake_callback_, PP_ERROR_FAILED); + ssl_handshake_callback_->Run(PP_ERROR_FAILED); Disconnect(); Release(); } @@ -277,8 +276,7 @@ void TCPSocketPrivateImpl::OnReadCompleted(bool succeeded, read_buffer_ = NULL; bytes_to_read_ = -1; - TrackedCallback::ClearAndRun( - &read_callback_, + read_callback_->Run( succeeded ? static_cast<int32_t>(data.size()) : static_cast<int32_t>(PP_ERROR_FAILED)); } @@ -291,8 +289,7 @@ void TCPSocketPrivateImpl::OnWriteCompleted(bool succeeded, return; } - TrackedCallback::ClearAndRun( - &write_callback_, + write_callback_->Run( succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED)); } @@ -317,7 +314,7 @@ bool TCPSocketPrivateImpl::IsConnected() const { void TCPSocketPrivateImpl::PostAbortIfNecessary( scoped_refptr<TrackedCallback>* callback) { - if (callback->get()) + if (TrackedCallback::IsPending(*callback)) (*callback)->PostAbort(); } diff --git a/ppapi/shared_impl/private/udp_socket_private_impl.cc b/ppapi/shared_impl/private/udp_socket_private_impl.cc index d3e94c1..288c38f 100644 --- a/ppapi/shared_impl/private/udp_socket_private_impl.cc +++ b/ppapi/shared_impl/private/udp_socket_private_impl.cc @@ -162,8 +162,7 @@ void UDPSocketPrivateImpl::OnBindCompleted( bound_addr_ = addr; - TrackedCallback::ClearAndRun(&bind_callback_, - succeeded ? PP_OK : PP_ERROR_FAILED); + bind_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED); } void UDPSocketPrivateImpl::OnRecvFromCompleted( @@ -184,8 +183,7 @@ void UDPSocketPrivateImpl::OnRecvFromCompleted( bytes_to_read_ = -1; recvfrom_addr_ = addr; - TrackedCallback::ClearAndRun(&recvfrom_callback_, - succeeded ? static_cast<int32_t>(data.size()) : + recvfrom_callback_->Run(succeeded ? static_cast<int32_t>(data.size()) : static_cast<int32_t>(PP_ERROR_FAILED)); } @@ -196,7 +194,7 @@ void UDPSocketPrivateImpl::OnSendToCompleted(bool succeeded, return; } - TrackedCallback::ClearAndRun(&sendto_callback_, + sendto_callback_->Run( succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED)); } @@ -218,7 +216,7 @@ void UDPSocketPrivateImpl::Init(uint32 socket_id) { void UDPSocketPrivateImpl::PostAbortIfNecessary( scoped_refptr<TrackedCallback>* callback) { - if (callback->get()) + if (TrackedCallback::IsPending(*callback)) (*callback)->PostAbort(); } diff --git a/ppapi/shared_impl/tracked_callback.cc b/ppapi/shared_impl/tracked_callback.cc index 3b9e25f..65d94be 100644 --- a/ppapi/shared_impl/tracked_callback.cc +++ b/ppapi/shared_impl/tracked_callback.cc @@ -25,15 +25,12 @@ namespace ppapi { TrackedCallback::TrackedCallback( Resource* resource, const PP_CompletionCallback& callback) - : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), + : is_scheduled_(false), resource_id_(resource ? resource->pp_resource() : 0), completed_(false), aborted_(false), callback_(callback), result_for_blocked_callback_(PP_OK) { - // We can only track this callback if the resource is valid. It can be NULL - // in error conditions in the Enter* classes and for callbacks associated with - // an instance. // TODO(dmichael): Add tracking at the instance level, for callbacks that only // have an instance (e.g. for MouseLock). if (resource) { @@ -53,97 +50,80 @@ TrackedCallback::~TrackedCallback() { } void TrackedCallback::Abort() { - if (!completed()) { - aborted_ = true; - Run(PP_ERROR_ABORTED); - } -} - -void TrackedCallback::PostAbort() { // It doesn't make sense to abort a callback that's not associated with a // resource. - // TODO(dmichael): If we allow associating with an instance instead, we must - // allow for aborts in the case of the instance being destroyed. DCHECK(resource_id_); + Run(PP_ERROR_ABORTED); +} - if (!completed() && !aborted_) { - aborted_ = true; - MessageLoop::current()->PostTask( - FROM_HERE, - RunWhileLocked(base::Bind(&TrackedCallback::Abort, - weak_ptr_factory_.GetWeakPtr()))); - } +void TrackedCallback::PostAbort() { + PostRun(PP_ERROR_ABORTED); } void TrackedCallback::Run(int32_t result) { - if (!completed()) { - // Cancel any pending calls. - weak_ptr_factory_.InvalidateWeakPtrs(); - - // Copy |callback_| and look at |aborted()| now, since |MarkAsCompleted()| - // may delete us. - PP_CompletionCallback callback = callback_; - if (aborted()) - result = PP_ERROR_ABORTED; - - if (is_blocking()) { - // If the condition variable is invalid, there are two possibilities. One, - // we're running in-process, in which case the call should have come in on - // the main thread and we should have returned PP_ERROR_BLOCKS_MAIN_THREAD - // well before this. Otherwise, this callback was not created as a - // blocking callback. Either way, there's some internal error. - if (!operation_completed_condvar_.get()) { - NOTREACHED(); - return; - } - result_for_blocked_callback_ = result; - // Retain ourselves, since MarkAsCompleted will remove us from the - // tracker. Then MarkAsCompleted before waking up the blocked thread, - // which could potentially re-enter. - scoped_refptr<TrackedCallback> thiz(this); - MarkAsCompleted(); - // Wake up the blocked thread. See BlockUntilComplete for where the thread - // Wait()s. - operation_completed_condvar_->Signal(); - } else { - // Do this before running the callback in case of reentrancy (which - // shouldn't happen, but avoid strange failures). - MarkAsCompleted(); - // TODO(dmichael): Associate a message loop with the callback; if it's not - // the same as the current thread's loop, then post it to the right loop. - CallWhileUnlocked(PP_RunCompletionCallback, &callback, result); + // Only allow the callback to be run once. Note that this also covers the case + // where the callback was previously Aborted because its associated Resource + // went away. The callback may live on for a while because of a reference from + // a Closure. But when the Closure runs, Run() quietly does nothing, and the + // callback will go away when all referring Closures go away. + if (completed()) + return; + if (result == PP_ERROR_ABORTED) + aborted_ = true; + + // Copy |callback_| and look at |aborted()| now, since |MarkAsCompleted()| + // may delete us. + PP_CompletionCallback callback = callback_; + // Note that this call of Run() may have been scheduled prior to Abort() or + // PostAbort() being called. If we have been told to Abort, that always + // trumps a result that was scheduled before. + if (aborted()) + result = PP_ERROR_ABORTED; + + if (is_blocking()) { + // If the condition variable is invalid, there are two possibilities. One, + // we're running in-process, in which case the call should have come in on + // the main thread and we should have returned PP_ERROR_BLOCKS_MAIN_THREAD + // well before this. Otherwise, this callback was not created as a + // blocking callback. Either way, there's some internal error. + if (!operation_completed_condvar_.get()) { + NOTREACHED(); + return; } + result_for_blocked_callback_ = result; + // Retain ourselves, since MarkAsCompleted will remove us from the + // tracker. Then MarkAsCompleted before waking up the blocked thread, + // which could potentially re-enter. + scoped_refptr<TrackedCallback> thiz(this); + MarkAsCompleted(); + // Wake up the blocked thread. See BlockUntilComplete for where the thread + // Wait()s. + operation_completed_condvar_->Signal(); + } else { + // Do this before running the callback in case of reentrancy (which + // shouldn't happen, but avoid strange failures). + MarkAsCompleted(); + // TODO(dmichael): Associate a message loop with the callback; if it's not + // the same as the current thread's loop, then post it to the right loop. + CallWhileUnlocked(PP_RunCompletionCallback, &callback, result); } } void TrackedCallback::PostRun(int32_t result) { - DCHECK(!completed()); - if (!completed()) { - // There should be no pending calls. - DCHECK(!weak_ptr_factory_.HasWeakPtrs()); - weak_ptr_factory_.InvalidateWeakPtrs(); - - if (resource_id_) { - // If it has a resource_id_, it's in the tracker, and may be aborted if - // the resource is destroyed. - MessageLoop::current()->PostTask( - FROM_HERE, - RunWhileLocked(base::Bind(&TrackedCallback::Run, - weak_ptr_factory_.GetWeakPtr(), - result))); - } else { - // There is no resource_id_ associated with this callback, so it can't be - // aborted. We have the message loop retain the callback to make sure it - // gets run. This can happen when EnterBase is given an invalid resource, - // and in that case no resource or instance will retain this - // TrackedCallback. - MessageLoop::current()->PostTask( - FROM_HERE, - RunWhileLocked(base::Bind(&TrackedCallback::Run, - this, - result))); - } + if (completed()) { + NOTREACHED(); + return; } + if (result == PP_ERROR_ABORTED) + aborted_ = true; + // We might abort when there's already a scheduled callback, but callers + // should never try to PostRun more than once otherwise. + DCHECK(result == PP_ERROR_ABORTED || !is_scheduled_); + + base::Closure callback_closure( + RunWhileLocked(base::Bind(&TrackedCallback::Run, this, result))); + MessageLoop::current()->PostTask(FROM_HERE, callback_closure); + is_scheduled_ = true; } // static @@ -154,21 +134,6 @@ bool TrackedCallback::IsPending( return !callback->completed(); } -// static -void TrackedCallback::ClearAndRun(scoped_refptr<TrackedCallback>* callback, - int32_t result) { - scoped_refptr<TrackedCallback> temp; - temp.swap(*callback); - temp->Run(result); -} - -// static -void TrackedCallback::ClearAndAbort(scoped_refptr<TrackedCallback>* callback) { - scoped_refptr<TrackedCallback> temp; - temp.swap(*callback); - temp->Abort(); -} - int32_t TrackedCallback::BlockUntilComplete() { // Note, we are already holding the proxy lock in all these methods, including // this one (see ppapi/thunk/enter.cc for where it gets acquired). diff --git a/ppapi/shared_impl/tracked_callback.h b/ppapi/shared_impl/tracked_callback.h index 5286b51..1fa7b1b 100644 --- a/ppapi/shared_impl/tracked_callback.h +++ b/ppapi/shared_impl/tracked_callback.h @@ -11,7 +11,6 @@ #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" #include "base/synchronization/condition_variable.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_instance.h" @@ -74,8 +73,14 @@ class PPAPI_SHARED_EXPORT TrackedCallback // marked as to be aborted (by |PostAbort()|), |result| will be ignored and // the callback will be run with result |PP_ERROR_ABORTED|. // - // See also ClearAndRun(). + // Run() will invoke the call immediately, if invoked from the target thread + // (as determined by target_loop_). If invoked on a different thread, the + // callback will be scheduled to run later on target_loop_. + // TODO(dmichael): Make the above part about different threads actually true. void Run(int32_t result); + // PostRun is like Run(), except it guarantees that the callback will be run + // later. In particular, if you invoke PostRun on the same thread on which the + // callback is targeted to run, it will *not* be run immediately. void PostRun(int32_t result); void BlockUntilRun(); @@ -99,17 +104,6 @@ class PPAPI_SHARED_EXPORT TrackedCallback // of the callback (which may still be out-standing via a PostAbort). static bool IsPending(const scoped_refptr<TrackedCallback>& callback); - // Runs the given callback, clearing the given scoped_refptr before execution. - // This is useful for cases where there can be only one pending callback, and - // the presence of the callback indicates one is pending. Such code would - // normally want to clear it before execution so the plugin can issue a new - // request. - static void ClearAndRun(scoped_refptr<TrackedCallback>* callback, - int32_t result); - - // Same as ClearAndRun except it calls Abort(). - static void ClearAndAbort(scoped_refptr<TrackedCallback>* callback); - protected: bool is_blocking() { return !callback_.func; @@ -142,11 +136,9 @@ class PPAPI_SHARED_EXPORT TrackedCallback friend class base::RefCountedThreadSafe<TrackedCallback>; virtual ~TrackedCallback(); - // Factory used by |PostAbort()| and |PostRun()|. Note that it's safe to - // cancel any pending posted tasks on destruction -- before it's destroyed, - // the "owning" |CallbackTracker| must have gone through and done - // (synchronous) |Abort()|s. - base::WeakPtrFactory<TrackedCallback> weak_ptr_factory_; + // Flag used by |PostAbort()| and |PostRun()| to check that we don't schedule + // the callback more than once. + bool is_scheduled_; scoped_refptr<CallbackTracker> tracker_; PP_Resource resource_id_; |