OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #ifndef PPAPI_SHARED_IMPL_TRACKED_CALLBACK_H_ | 5 #ifndef PPAPI_SHARED_IMPL_TRACKED_CALLBACK_H_ |
6 #define PPAPI_SHARED_IMPL_TRACKED_CALLBACK_H_ | 6 #define PPAPI_SHARED_IMPL_TRACKED_CALLBACK_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 #include <set> | 9 #include <set> |
10 | 10 |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
| 13 #include "base/memory/scoped_ptr.h" |
13 #include "base/memory/weak_ptr.h" | 14 #include "base/memory/weak_ptr.h" |
| 15 #include "base/synchronization/condition_variable.h" |
14 #include "ppapi/c/pp_completion_callback.h" | 16 #include "ppapi/c/pp_completion_callback.h" |
| 17 #include "ppapi/c/pp_instance.h" |
15 #include "ppapi/c/pp_resource.h" | 18 #include "ppapi/c/pp_resource.h" |
16 #include "ppapi/shared_impl/ppapi_shared_export.h" | 19 #include "ppapi/shared_impl/ppapi_shared_export.h" |
17 | 20 |
18 namespace ppapi { | 21 namespace ppapi { |
19 | 22 |
20 class CallbackTracker; | 23 class CallbackTracker; |
21 class Resource; | 24 class Resource; |
22 | 25 |
| 26 namespace thunk { |
| 27 namespace subtle { |
| 28 // For a friend declaration below. |
| 29 class EnterBase; |
| 30 } |
| 31 } |
| 32 |
23 // |TrackedCallback| represents a tracked Pepper callback (from the browser to | 33 // |TrackedCallback| represents a tracked Pepper callback (from the browser to |
24 // the plugin), typically still pending. Such callbacks have the standard Pepper | 34 // the plugin), typically still pending. Such callbacks have the standard Pepper |
25 // callback semantics. Execution (i.e., completion) of callbacks happens through | 35 // callback semantics. Execution (i.e., completion) of callbacks happens through |
26 // objects of subclasses of |TrackedCallback|. Two things are ensured: (1) that | 36 // objects of subclasses of |TrackedCallback|. Two things are ensured: (1) that |
27 // the callback is executed at most once, and (2) once a callback is marked to | 37 // the callback is executed at most once, and (2) once a callback is marked to |
28 // be aborted, any subsequent completion is abortive (even if a non-abortive | 38 // be aborted, any subsequent completion is abortive (even if a non-abortive |
29 // completion had previously been scheduled). | 39 // completion had previously been scheduled). |
30 // | 40 // |
31 // The details of non-abortive completion depend on the type of callback (e.g., | 41 // The details of non-abortive completion depend on the type of callback (e.g., |
32 // different parameters may be required), but basic abort functionality is core. | 42 // different parameters may be required), but basic abort functionality is core. |
(...skipping 11 matching lines...) Expand all Loading... |
44 // - They must ensure that the callback is executed at most once (by looking at | 54 // - They must ensure that the callback is executed at most once (by looking at |
45 // |completed()| before running the callback). | 55 // |completed()| before running the callback). |
46 // - They must ensure that the callback is run abortively if it is marked as to | 56 // - They must ensure that the callback is run abortively if it is marked as to |
47 // be aborted (by looking at |aborted()| before running the callback). | 57 // be aborted (by looking at |aborted()| before running the callback). |
48 // - They must call |MarkAsCompleted()| immediately before actually running the | 58 // - They must call |MarkAsCompleted()| immediately before actually running the |
49 // callback; see the comment for |MarkAsCompleted()| for a caveat. | 59 // callback; see the comment for |MarkAsCompleted()| for a caveat. |
50 class PPAPI_SHARED_EXPORT TrackedCallback | 60 class PPAPI_SHARED_EXPORT TrackedCallback |
51 : public base::RefCountedThreadSafe<TrackedCallback> { | 61 : public base::RefCountedThreadSafe<TrackedCallback> { |
52 public: | 62 public: |
53 // Create a tracked completion callback and register it with the tracker. The | 63 // Create a tracked completion callback and register it with the tracker. The |
54 // resource pointer is not stored. | 64 // resource pointer is not stored. If |resource| is NULL, this callback will |
55 TrackedCallback(Resource* resource, | 65 // not be added to the callback tracker. |
56 const PP_CompletionCallback& callback); | 66 TrackedCallback(Resource* resource, const PP_CompletionCallback& callback); |
57 | 67 |
58 // These run the callback in an abortive manner, or post a task to do so (but | 68 // These run the callback in an abortive manner, or post a task to do so (but |
59 // immediately marking the callback as to be aborted). | 69 // immediately marking the callback as to be aborted). |
60 void Abort(); | 70 void Abort(); |
61 void PostAbort(); | 71 void PostAbort(); |
62 | 72 |
63 // Run the callback with the given result. If the callback had previously been | 73 // Run the callback with the given result. If the callback had previously been |
64 // marked as to be aborted (by |PostAbort()|), |result| will be ignored and | 74 // marked as to be aborted (by |PostAbort()|), |result| will be ignored and |
65 // the callback will be run with result |PP_ERROR_ABORTED|. | 75 // the callback will be run with result |PP_ERROR_ABORTED|. |
66 // | 76 // |
67 // See also ClearAndRun(). | 77 // See also ClearAndRun(). |
68 void Run(int32_t result); | 78 void Run(int32_t result); |
| 79 void PostRun(int32_t result); |
| 80 |
| 81 void BlockUntilRun(); |
69 | 82 |
70 // Returns the ID of the resource which "owns" the callback, or 0 if the | 83 // Returns the ID of the resource which "owns" the callback, or 0 if the |
71 // callback is not associated with any resource. | 84 // callback is not associated with any resource. |
72 PP_Resource resource_id() const { return resource_id_; } | 85 PP_Resource resource_id() const { return resource_id_; } |
73 | 86 |
74 // Returns true if the callback was completed (possibly aborted). | 87 // Returns true if the callback was completed (possibly aborted). |
75 bool completed() const { return completed_; } | 88 bool completed() const { return completed_; } |
76 | 89 |
77 // Returns true if the callback was or should be aborted; this will be the | 90 // Returns true if the callback was or should be aborted; this will be the |
78 // case whenever |Abort()| or |PostAbort()| is called before a non-abortive | 91 // case whenever |Abort()| or |PostAbort()| is called before a non-abortive |
79 // completion. | 92 // completion. |
80 bool aborted() const { return aborted_; } | 93 bool aborted() const { return aborted_; } |
81 | 94 |
82 // Helper to determine if the given callback is set and not yet completed. | 95 // Helper to determine if the given callback is set and not yet completed. |
83 // The normal pattern is to use a scoped_refptr to hold a callback. This | 96 // The normal pattern is to use a scoped_refptr to hold a callback. This |
84 // function tells you if the operation is currently in progress by checking | 97 // function tells you if the operation is currently in progress by checking |
85 // both the null-ness of the scoped_refptr, as well as the completion state | 98 // both the null-ness of the scoped_refptr, as well as the completion state |
86 // of the callback (which may still be out-standing via a PostAbort). | 99 // of the callback (which may still be out-standing via a PostAbort). |
87 static bool IsPending(const scoped_refptr<TrackedCallback>& callback); | 100 static bool IsPending(const scoped_refptr<TrackedCallback>& callback); |
88 | 101 |
89 // Runs the given callback, clearing the given scoped_refptr before execution. | 102 // Runs the given callback, clearing the given scoped_refptr before execution. |
90 // This is useful for cases where there can be only one pending callback, and | 103 // This is useful for cases where there can be only one pending callback, and |
91 // the presence of the callback indicates is one is pending. Such code would | 104 // the presence of the callback indicates one is pending. Such code would |
92 // normally want to clear it before execution so the plugin can issue a new | 105 // normally want to clear it before execution so the plugin can issue a new |
93 // request. | 106 // request. |
94 static void ClearAndRun(scoped_refptr<TrackedCallback>* callback, | 107 static void ClearAndRun(scoped_refptr<TrackedCallback>* callback, |
95 int32_t result); | 108 int32_t result); |
96 | 109 |
97 // Same as ClearAndRun except it calls Abort(). | 110 // Same as ClearAndRun except it calls Abort(). |
98 static void ClearAndAbort(scoped_refptr<TrackedCallback>* callback); | 111 static void ClearAndAbort(scoped_refptr<TrackedCallback>* callback); |
99 | 112 |
| 113 protected: |
| 114 bool is_blocking() { |
| 115 return !callback_.func; |
| 116 } |
| 117 bool is_required() { |
| 118 return (callback_.func && |
| 119 !(callback_.flags & PP_COMPLETIONCALLBACK_FLAG_OPTIONAL)); |
| 120 } |
| 121 bool is_optional() { |
| 122 return (callback_.func && |
| 123 (callback_.flags & PP_COMPLETIONCALLBACK_FLAG_OPTIONAL)); |
| 124 } |
| 125 |
100 private: | 126 private: |
101 // This class is ref counted. | 127 // TrackedCallback and EnterBase manage dealing with how to invoke callbacks |
102 friend class base::RefCountedThreadSafe<TrackedCallback>; | 128 // appropriately. Pepper interface implementations and proxies should not have |
103 virtual ~TrackedCallback(); | 129 // to check the type of callback, block, or mark them complete explicitly. |
| 130 friend class ppapi::thunk::subtle::EnterBase; |
| 131 |
| 132 // Block until the associated operation has completed. Returns the result. |
| 133 // This must only be called on a non-main thread on a blocking callback. |
| 134 int32_t BlockUntilComplete(); |
104 | 135 |
105 // Mark this object as complete and remove it from the tracker. This must only | 136 // Mark this object as complete and remove it from the tracker. This must only |
106 // be called once. Note that running this may result in this object being | 137 // be called once. Note that running this may result in this object being |
107 // deleted (so keep a reference if it'll still be needed). | 138 // deleted (so keep a reference if it'll still be needed). |
108 void MarkAsCompleted(); | 139 void MarkAsCompleted(); |
109 | 140 |
110 // Factory used by |PostAbort()|. Note that it's safe to cancel any pending | 141 // This class is ref counted. |
111 // posted aborts on destruction -- before it's destroyed, the "owning" | 142 friend class base::RefCountedThreadSafe<TrackedCallback>; |
112 // |CallbackTracker| must have gone through and done (synchronous) |Abort()|s. | 143 virtual ~TrackedCallback(); |
113 base::WeakPtrFactory<TrackedCallback> abort_impl_factory_; | 144 |
| 145 // Factory used by |PostAbort()| and |PostRun()|. Note that it's safe to |
| 146 // cancel any pending posted tasks on destruction -- before it's destroyed, |
| 147 // the "owning" |CallbackTracker| must have gone through and done |
| 148 // (synchronous) |Abort()|s. |
| 149 base::WeakPtrFactory<TrackedCallback> weak_ptr_factory_; |
114 | 150 |
115 scoped_refptr<CallbackTracker> tracker_; | 151 scoped_refptr<CallbackTracker> tracker_; |
116 PP_Resource resource_id_; | 152 PP_Resource resource_id_; |
117 bool completed_; | 153 bool completed_; |
118 bool aborted_; | 154 bool aborted_; |
119 PP_CompletionCallback callback_; | 155 PP_CompletionCallback callback_; |
120 | 156 |
| 157 int32_t result_for_blocked_callback_; |
| 158 // Used for pausing/waking the blocked thread if this is a blocking completion |
| 159 // callback. Note that in-process, there is no lock, blocking callbacks are |
| 160 // not allowed, and therefore this pointer will be NULL. |
| 161 scoped_ptr<base::ConditionVariable> operation_completed_condvar_; |
| 162 |
121 DISALLOW_IMPLICIT_CONSTRUCTORS(TrackedCallback); | 163 DISALLOW_IMPLICIT_CONSTRUCTORS(TrackedCallback); |
122 }; | 164 }; |
123 | 165 |
124 } // namespace ppapi | 166 } // namespace ppapi |
125 | 167 |
126 #endif // PPAPI_SHARED_IMPL_TRACKED_CALLBACK_H_ | 168 #endif // PPAPI_SHARED_IMPL_TRACKED_CALLBACK_H_ |
OLD | NEW |