Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Side by Side Diff: ppapi/shared_impl/tracked_callback.h

Issue 10081020: PPAPI: Make blocking completion callbacks work. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: export AssertLockHeld Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/shared_impl/proxy_lock.cc ('k') | ppapi/shared_impl/tracked_callback.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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_
OLDNEW
« no previous file with comments | « ppapi/shared_impl/proxy_lock.cc ('k') | ppapi/shared_impl/tracked_callback.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698