OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 // Special case context for holding two tasks, a |first_task| + the task | 62 // Special case context for holding two tasks, a |first_task| + the task |
63 // that's owned by the parent struct, TaskContext, that then becomes the | 63 // that's owned by the parent struct, TaskContext, that then becomes the |
64 // second (i.e. 'reply') task. | 64 // second (i.e. 'reply') task. |
65 struct TaskQueue::PostTaskAndReplyContext : public TaskQueue::TaskContext { | 65 struct TaskQueue::PostTaskAndReplyContext : public TaskQueue::TaskContext { |
66 explicit PostTaskAndReplyContext(QueueContext* first_queue_ctx, | 66 explicit PostTaskAndReplyContext(QueueContext* first_queue_ctx, |
67 std::unique_ptr<QueuedTask> first_task, | 67 std::unique_ptr<QueuedTask> first_task, |
68 QueueContext* second_queue_ctx, | 68 QueueContext* second_queue_ctx, |
69 std::unique_ptr<QueuedTask> second_task) | 69 std::unique_ptr<QueuedTask> second_task) |
70 : TaskContext(second_queue_ctx, std::move(second_task)), | 70 : TaskContext(second_queue_ctx, std::move(second_task)), |
71 first_queue_ctx(first_queue_ctx), | 71 first_queue_ctx(first_queue_ctx), |
72 first_task(std::move(first_task)) { | 72 first_task(std::move(first_task)), |
| 73 reply_queue_(second_queue_ctx->queue->queue_) { |
73 // Retain the reply queue for as long as this object lives. | 74 // Retain the reply queue for as long as this object lives. |
74 // If we don't, we may have memory leaks and/or failures. | 75 // If we don't, we may have memory leaks and/or failures. |
75 dispatch_retain(first_queue_ctx->queue->queue_); | 76 dispatch_retain(reply_queue_); |
76 } | 77 } |
77 ~PostTaskAndReplyContext() override { | 78 ~PostTaskAndReplyContext() override { dispatch_release(reply_queue_); } |
78 dispatch_release(first_queue_ctx->queue->queue_); | |
79 } | |
80 | 79 |
81 static void RunTask(void* context) { | 80 static void RunTask(void* context) { |
82 auto* rc = static_cast<PostTaskAndReplyContext*>(context); | 81 auto* rc = static_cast<PostTaskAndReplyContext*>(context); |
83 if (rc->first_queue_ctx->is_active) { | 82 if (rc->first_queue_ctx->is_active) { |
84 AutoSetCurrentQueuePtr set_current(rc->first_queue_ctx->queue); | 83 AutoSetCurrentQueuePtr set_current(rc->first_queue_ctx->queue); |
85 if (!rc->first_task->Run()) | 84 if (!rc->first_task->Run()) |
86 rc->first_task.release(); | 85 rc->first_task.release(); |
87 } | 86 } |
88 // Post the reply task. This hands the work over to the parent struct. | 87 // Post the reply task. This hands the work over to the parent struct. |
89 // This task will eventually delete |this|. | 88 // This task will eventually delete |this|. |
90 dispatch_async_f(rc->queue_ctx->queue->queue_, rc, &TaskContext::RunTask); | 89 dispatch_async_f(rc->reply_queue_, rc, &TaskContext::RunTask); |
91 } | 90 } |
92 | 91 |
93 QueueContext* const first_queue_ctx; | 92 QueueContext* const first_queue_ctx; |
94 std::unique_ptr<QueuedTask> first_task; | 93 std::unique_ptr<QueuedTask> first_task; |
| 94 dispatch_queue_t reply_queue_; |
95 }; | 95 }; |
96 | 96 |
97 TaskQueue::TaskQueue(const char* queue_name) | 97 TaskQueue::TaskQueue(const char* queue_name) |
98 : queue_(dispatch_queue_create(queue_name, DISPATCH_QUEUE_SERIAL)), | 98 : queue_(dispatch_queue_create(queue_name, DISPATCH_QUEUE_SERIAL)), |
99 context_(new QueueContext(this)) { | 99 context_(new QueueContext(this)) { |
100 RTC_DCHECK(queue_name); | 100 RTC_DCHECK(queue_name); |
101 RTC_CHECK(queue_); | 101 RTC_CHECK(queue_); |
102 dispatch_set_context(queue_, context_); | 102 dispatch_set_context(queue_, context_); |
103 // Assign a finalizer that will delete the context when the last reference | 103 // Assign a finalizer that will delete the context when the last reference |
104 // to the queue is released. This may run after the TaskQueue object has | 104 // to the queue is released. This may run after the TaskQueue object has |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 context_, std::move(task), reply_queue->context_, std::move(reply)); | 158 context_, std::move(task), reply_queue->context_, std::move(reply)); |
159 dispatch_async_f(queue_, context, &PostTaskAndReplyContext::RunTask); | 159 dispatch_async_f(queue_, context, &PostTaskAndReplyContext::RunTask); |
160 } | 160 } |
161 | 161 |
162 void TaskQueue::PostTaskAndReply(std::unique_ptr<QueuedTask> task, | 162 void TaskQueue::PostTaskAndReply(std::unique_ptr<QueuedTask> task, |
163 std::unique_ptr<QueuedTask> reply) { | 163 std::unique_ptr<QueuedTask> reply) { |
164 return PostTaskAndReply(std::move(task), std::move(reply), Current()); | 164 return PostTaskAndReply(std::move(task), std::move(reply), Current()); |
165 } | 165 } |
166 | 166 |
167 } // namespace rtc | 167 } // namespace rtc |
OLD | NEW |