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

Side by Side Diff: media/base/callback_util.cc

Issue 10753021: Move AudioRenderer out of Filter heirarchy. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src
Patch Set: thing Created 8 years, 5 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "media/base/callback_util.h"
6
7 #include "base/bind.h"
8 #include "base/synchronization/lock.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/message_loop.h"
11 #include "base/message_loop_proxy.h"
12
13 namespace media {
14
15 // Executes the given closure if and only if the closure returned by
scherkus (not reviewing) 2012/07/19 21:29:02 I tried the ref-counting approach for fun but some
16 // GetClosure() has been executed exactly |count| times.
17 //
18 // |done_cb| will be executed on the same thread that created the CountingCB.
19 class CountingCB : public base::RefCountedThreadSafe<CountingCB> {
20 public:
21 explicit CountingCB(int count, const base::Closure& done_cb)
acolwell GONE FROM CHROMIUM 2012/07/19 23:09:14 nit: remove explicit now.
scherkus (not reviewing) 2012/07/19 23:46:47 Done.
22 : message_loop_(base::MessageLoopProxy::current()),
23 count_(count),
24 completed_(0),
25 done_cb_(done_cb) {
26 }
27
28 // Returns a closure bound to this object.
29 base::Closure GetClosure() {
30 return base::Bind(&CountingCB::OnCallback, this);
31 }
32
33 protected:
34 friend class base::RefCountedThreadSafe<CountingCB>;
35 virtual ~CountingCB() {}
36
37 private:
38 void OnCallback() {
39 {
40 base::AutoLock l(lock_);
41 completed_++;
42 DCHECK_LE(completed_, count_) << "CountingCB executed too many times";
43 if (completed_ != count_)
44 return;
45 }
46
47 if (!message_loop_->BelongsToCurrentThread()) {
48 message_loop_->PostTask(FROM_HERE, done_cb_);
49 return;
50 }
51
52 done_cb_.Run();
53 }
54
55 scoped_refptr<base::MessageLoopProxy> message_loop_;
56 base::Lock lock_;
57 int count_;
58 int completed_;
acolwell GONE FROM CHROMIUM 2012/07/19 23:09:14 nit: Consider decrementing count_ so you don't nee
scherkus (not reviewing) 2012/07/19 23:46:47 Done.
59 base::Closure done_cb_;
60
61 DISALLOW_COPY_AND_ASSIGN(CountingCB);
62 };
63
64 static void OnSeriesCallback(
65 scoped_refptr<base::MessageLoopProxy> message_loop,
66 scoped_ptr<std::queue<ClosureFunc> > closures,
67 const base::Closure& done_cb) {
68 if (!message_loop->BelongsToCurrentThread()) {
69 message_loop->PostTask(FROM_HERE, base::Bind(
70 &OnSeriesCallback, message_loop, base::Passed(&closures), done_cb));
71 return;
72 }
73
74 if (closures->empty()) {
75 done_cb.Run();
76 return;
77 }
78
79 ClosureFunc cb = closures->front();
80 closures->pop();
81 cb.Run(base::Bind(
82 &OnSeriesCallback, message_loop, base::Passed(&closures), done_cb));
83 }
84
85 void RunInSeries(scoped_ptr<std::queue<ClosureFunc> > closures,
86 const base::Closure& done_cb) {
87 OnSeriesCallback(base::MessageLoopProxy::current(),
88 closures.Pass(), done_cb);
89 }
90
91 static void OnStatusCallback(
92 scoped_refptr<base::MessageLoopProxy> message_loop,
93 scoped_ptr<std::queue<PipelineStatusCBFunc> > status_cbs,
94 const PipelineStatusCB& done_cb,
95 PipelineStatus last_status) {
96 if (!message_loop->BelongsToCurrentThread()) {
97 message_loop->PostTask(FROM_HERE, base::Bind(
98 &OnStatusCallback, message_loop, base::Passed(&status_cbs), done_cb,
99 last_status));
100 return;
101 }
102
103 if (status_cbs->empty() || last_status != PIPELINE_OK) {
104 done_cb.Run(last_status);
105 return;
106 }
107
108 PipelineStatusCBFunc status_cb = status_cbs->front();
109 status_cbs->pop();
110 status_cb.Run(base::Bind(
111 &OnStatusCallback, message_loop, base::Passed(&status_cbs), done_cb));
112 }
113
114 void RunInSeriesWithStatus(
115 scoped_ptr<std::queue<PipelineStatusCBFunc> > status_cbs,
116 const PipelineStatusCB& done_cb) {
117 OnStatusCallback(base::MessageLoopProxy::current(),
118 status_cbs.Pass(), done_cb, PIPELINE_OK);
119 }
120
121 void RunInParallel(scoped_ptr<std::queue<ClosureFunc> > closures,
122 const base::Closure& done_cb) {
123 if (closures->empty()) {
124 done_cb.Run();
125 return;
126 }
127
128 scoped_refptr<CountingCB> counting_cb =
129 new CountingCB(closures->size(), done_cb);
130 while (!closures->empty()) {
131 closures->front().Run(counting_cb->GetClosure());
132 closures->pop();
133 }
134 }
135
136 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698