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

Side by Side Diff: webrtc/base/task_queue_gcd.cc

Issue 1919733002: New task queueing primitive for async tasks: TaskQueue. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fix variable destruction order in PostALot Created 4 years, 7 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
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "webrtc/base/task_queue.h"
perkj_webrtc 2016/04/26 14:30:37 Can you add a note what this implement?- ie -what
tommi 2016/04/28 12:04:01 Done.
12
13 #include <string.h>
14
15 #include "webrtc/base/checks.h"
16 #include "webrtc/base/logging.h"
17 #include "webrtc/base/task_queue_posix.h"
18
19 namespace rtc {
20 using internal::GetQueuePtrTls;
21 using internal::AutoSetCurrentQueuePtr;
22
23 struct TaskQueue::QueueContext {
24 explicit QueueContext(TaskQueue* q) : queue(q), is_active(true) {}
25
26 static void DeleteContext(void* context) {
27 QueueContext* qc = reinterpret_cast<QueueContext*>(context);
28 delete qc;
29 }
30
31 TaskQueue* const queue;
32 bool is_active;
33 };
34
35 TaskQueue::TaskQueue(const char* queue_name)
36 : queue_(dispatch_queue_create(queue_name, DISPATCH_QUEUE_SERIAL)),
37 context_(new QueueContext(this)) {
38 RTC_DCHECK(queue_name);
39 queue_ = dispatch_queue_create(queue_name, DISPATCH_QUEUE_SERIAL);
perkj_webrtc 2016/04/26 14:30:38 already created at line 36.
tommi 2016/04/28 12:04:01 Doh! artefact of moving code around. Thanks for ca
40 RTC_CHECK(queue_);
41 dispatch_set_context(queue_, context_);
42 // Assign a finalizer that will delete the context when the last reference
43 // to the queue is released. This may run after the TaskQueue object has
44 // been deleted.
45 dispatch_set_finalizer_f(queue_, &QueueContext::DeleteContext);
46 }
47
48 TaskQueue::~TaskQueue() {
49 RTC_DCHECK(!IsCurrent());
50 // Implementation/behavioral note:
51 // Dispatch queues are reference counted via calls to dispatch_retain and
52 // dispatch_release. Pending blocks submitted to a queue also hold a
53 // reference to the queue until they have finished. Once all references to a
54 // queue have been released, the queue will be deallocated by the system.
55 // This is why we check the context before running tasks.
56
57 // Use dispatch_sync to set the context to null to guarantee that there's not
58 // a race between checking the context and using it from a task.
59 dispatch_sync(queue_, ^{
60 context_->is_active = false;
61 });
62 dispatch_release(queue_);
63 }
64
65 // static
66 TaskQueue* TaskQueue::Current() {
perkj_webrtc 2016/04/26 14:30:37 Can static TaskQueue::Current be made public?
tommi 2016/04/28 12:04:01 Done.
67 return static_cast<TaskQueue*>(pthread_getspecific(GetQueuePtrTls()));
68 }
69
70 // static
71 bool TaskQueue::IsCurrent(const char* queue_name) {
72 TaskQueue* current = Current();
73 return current &&
74 strcmp(queue_name, dispatch_queue_get_label(current->queue_)) == 0;
75 }
76
77 bool TaskQueue::IsCurrent() const {
78 RTC_DCHECK(queue_);
79 return this == Current();
80 }
81
82 void TaskQueue::PostTask(std::unique_ptr<QueuedTask> task) {
83 QueuedTask* task_ptr = task.release();
84 QueueContext* context = context_;
85 dispatch_async(queue_, ^{
perkj_webrtc 2016/04/26 14:30:37 I can read this but I have never seen ^{ before- y
tommi 2016/04/28 12:04:01 Good idea, however I don't think it's needed now a
86 QueuedTask* t = task_ptr; // since task_ptr is unassignable.
perkj_webrtc 2016/04/26 14:30:37 Are ^{ lambdas with similar rules? Is task_ptr an
tommi 2016/04/28 12:04:01 Yes, the rules are similar. However, now I've rem
87 if (context->is_active) {
perkj_webrtc 2016/04/26 14:30:37 Does context->is_active mean that it is safe to do
tommi 2016/04/28 12:04:01 I think we discussed this offline today but let me
88 AutoSetCurrentQueuePtr set_current(context->queue);
89 if (!t->Run())
90 t = nullptr;
91 }
92 if (t)
93 delete t;
94 });
95 }
96
97 void TaskQueue::PostDelayedTask(std::unique_ptr<QueuedTask> task,
98 uint32_t milliseconds) {
99 QueuedTask* task_ptr = task.release();
100 QueueContext* context = context_;
101 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, milliseconds * NSEC_PER_MSEC),
102 queue_, ^{
103 QueuedTask* t = task_ptr;
perkj_webrtc 2016/04/26 14:30:37 Humm- this is code duplication. Is there a way to
perkj_webrtc 2016/04/26 14:30:38 indentation looks weird.
tommi 2016/04/28 12:04:01 git cl format. However, I think that this won't b
104 if (context->is_active) {
105 AutoSetCurrentQueuePtr set_current(context->queue);
106 if (!t->Run())
107 t = nullptr;
108 }
109 if (t)
110 delete t;
111 });
112 }
113
114 void TaskQueue::PostTaskAndReply(std::unique_ptr<QueuedTask> task,
115 std::unique_ptr<QueuedTask> reply,
116 TaskQueue* reply_queue) {
117 QueuedTask* task_ptr = task.release();
118 QueuedTask* reply_task_ptr = reply.release();
119 dispatch_queue_t target_queue = reply_queue->queue_;
120 dispatch_retain(target_queue);
121 QueueContext* context = context_;
122 QueueContext* reply_context = reply_queue->context_;
123 dispatch_async(queue_, ^{
124 QueuedTask* t = task_ptr;
125 if (context->is_active) {
126 AutoSetCurrentQueuePtr set_current(context->queue);
127 if (!t->Run())
128 t = nullptr;
129 }
130 if (t)
131 delete t;
132 dispatch_async(target_queue, ^{
133 QueuedTask* r = reply_task_ptr;
134 if (reply_context->is_active) {
135 AutoSetCurrentQueuePtr set_current(reply_context->queue);
136 if (!r->Run())
137 r = nullptr;
138 }
139 if (r)
140 delete r;
141 });
142 dispatch_release(target_queue);
143 });
144 }
145
146 void TaskQueue::PostTaskAndReply(std::unique_ptr<QueuedTask> task,
147 std::unique_ptr<QueuedTask> reply) {
148 return PostTaskAndReply(std::move(task), std::move(reply), Current());
149 }
150
151 } // namespace rtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698