// Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef PPAPI_SHARED_IMPL_TRACKED_CALLBACK_H_ #define PPAPI_SHARED_IMPL_TRACKED_CALLBACK_H_ #include <stdint.h> #include <memory> #include "base/functional/callback.h" #include "base/memory/ref_counted.h" #include "base/synchronization/condition_variable.h" #include "base/synchronization/lock.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_resource.h" #include "ppapi/shared_impl/ppapi_shared_export.h" #include "ppapi/shared_impl/ppb_message_loop_shared.h" namespace ppapi { class CallbackTracker; class MessageLoopShared; class Resource; namespace thunk { namespace subtle { // For a friend declaration below. class EnterBase; } } // |TrackedCallback| represents a tracked Pepper callback (from the browser to // the plugin), typically still pending. Such callbacks have the standard Pepper // callback semantics. Execution (i.e., completion) of callbacks happens through // objects of subclasses of |TrackedCallback|. Two things are ensured: (1) that // the callback is executed at most once, and (2) once a callback is marked to // be aborted, any subsequent completion is abortive (even if a non-abortive // completion had previously been scheduled). // // The details of non-abortive completion depend on the type of callback (e.g., // different parameters may be required), but basic abort functionality is core. // The ability to post aborts is needed in many situations to ensure that the // plugin is not re-entered into. (Note that posting a task to just run // |Abort()| is different and not correct; calling |PostAbort()| additionally // guarantees that all subsequent completions will be abortive.) // // This class is reference counted so that different things can hang on to it, // and not worry too much about ensuring Pepper callback semantics. Note that // the "owning" |CallbackTracker| will keep a reference until the callback is // completed. // // A note on threading: // TrackedCallback is usable on any thread. It is *mostly* only used when // ppapi::ProxyLock is held. However, it's necessary that Run() can be called // without the ProxyLock. This is used to allow running the callback from // the IO thread. In particular, blocking callbacks may not have a message loop // to which we could post, so Run() must be able to signal the condition // variable to wake up the thread that's waiting on the blocking callback, and // Run() must be able to do this while not holding the ProxyLock. class PPAPI_SHARED_EXPORT TrackedCallback : public base::RefCountedThreadSafe<TrackedCallback> { … }; } // namespace ppapi #endif // PPAPI_SHARED_IMPL_TRACKED_CALLBACK_H_