// This file contains the implementation of TaskQueue for Mac and iOS. // The implementation uses Grand Central Dispatch queues (GCD) to // do the actual task queuing.
// TODO(crbug.com/470337728): make use of QoS instead of dispatch queue // priorities to enable greater fidelity mapping of AUDIO and VIDEO // priorities.
int TaskQueuePriorityToGCD(TaskQueueFactory::Priority priority) { switch (priority) { case TaskQueueFactory::Priority::kNormal: return DISPATCH_QUEUE_PRIORITY_DEFAULT; case TaskQueueFactory::Priority::kHigh: case TaskQueueFactory::Priority::kAudio: case TaskQueueFactory::Priority::kVideo: return DISPATCH_QUEUE_PRIORITY_HIGH; case TaskQueueFactory::Priority::kLow: return DISPATCH_QUEUE_PRIORITY_LOW;
}
}
class TaskQueueGcd final : public TaskQueueBase { public:
TaskQueueGcd(absl::string_view queue_name, int gcd_priority);
TaskQueueGcd::TaskQueueGcd(absl::string_view queue_name, int gcd_priority)
: name_(queue_name),
queue_(RTCDispatchQueueCreateWithTarget(
name_.c_str(),
DISPATCH_QUEUE_SERIAL,
dispatch_get_global_queue(gcd_priority, 0))),
is_active_(true) {
RTC_CHECK(queue_);
dispatch_set_context(queue_, this); // Assign a finalizer that will delete the queue when the last reference // is released. This may run after the TaskQueue::Delete.
dispatch_set_finalizer_f(queue_, &DeleteQueue);
}
TaskQueueGcd::~TaskQueueGcd() = default;
void TaskQueueGcd::Delete() { // Implementation/behavioral note: // Dispatch queues are reference counted via calls to dispatch_retain and // dispatch_release. Pending blocks submitted to a queue also hold a // reference to the queue until they have finished. Once all references to a // queue have been released, the queue will be deallocated by the system. We // check `is_active_` before running tasks to ensure they don't execute after // `Delete()` has been called.
if (IsCurrent()) {
SetNotActive(this);
} else { // Use dispatch_sync to set the is_active_ to guarantee that there's not a // race with checking it from a task.
dispatch_sync_f(queue_, this, &SetNotActive);
}
// static void TaskQueueGcd::RunTask(void* task_context) {
std::unique_ptr<TaskContext> tc(static_cast<TaskContext*>(task_context));
CurrentTaskQueueSetter set_current(tc->queue);
if (tc->queue->is_active_) {
std::move(tc->task)();
} // Delete the task before CurrentTaskQueueSetter clears state that this code // is running on the task queue.
tc = nullptr;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.