Index: base/mac/libdispatch_task_runner.cc |
diff --git a/base/mac/libdispatch_task_runner.cc b/base/mac/libdispatch_task_runner.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..0c1eebc5c5e7b606abaad876edf0e8ff3cb579b4 |
--- /dev/null |
+++ b/base/mac/libdispatch_task_runner.cc |
@@ -0,0 +1,83 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "base/mac/libdispatch_task_runner.h" |
+ |
+#include <stdint.h> |
+ |
+#include "base/callback.h" |
+ |
+namespace base { |
+namespace mac { |
+ |
+LibDispatchTaskRunner::LibDispatchTaskRunner(const char* name) |
+ : queue_(dispatch_queue_create(name, NULL)), |
+ queue_finalized_(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
+ base::WaitableEvent::InitialState::NOT_SIGNALED) { |
+ dispatch_set_context(queue_, this); |
+ dispatch_set_finalizer_f(queue_, &LibDispatchTaskRunner::Finalizer); |
+} |
+ |
+bool LibDispatchTaskRunner::PostDelayedTask( |
+ const tracked_objects::Location& from_here, |
+ OnceClosure task, |
+ base::TimeDelta delay) { |
+ if (!queue_) |
+ return false; |
+ |
+ // The block runtime would implicitly copy the reference, not the object |
+ // it's referencing. Copy the closure into block storage so it's available |
+ // to run. |
+ __block OnceClosure task_copy = std::move(task); |
+ void(^run_task)(void) = ^{ |
+ std::move(task_copy).Run(); |
+ }; |
+ |
+ int64_t delay_nano = |
+ delay.InMicroseconds() * base::Time::kNanosecondsPerMicrosecond; |
+ if (delay_nano > 0) { |
+ dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, delay_nano); |
+ dispatch_after(time, queue_, run_task); |
+ } else { |
+ dispatch_async(queue_, run_task); |
+ } |
+ return true; |
+} |
+ |
+bool LibDispatchTaskRunner::RunsTasksOnCurrentThread() const { |
+ return queue_ == dispatch_get_current_queue(); |
+} |
+ |
+bool LibDispatchTaskRunner::PostNonNestableDelayedTask( |
+ const tracked_objects::Location& from_here, |
+ OnceClosure task, |
+ base::TimeDelta delay) { |
+ return PostDelayedTask(from_here, std::move(task), delay); |
+} |
+ |
+void LibDispatchTaskRunner::Shutdown() { |
+ dispatch_release(queue_); |
+ queue_ = NULL; |
+ queue_finalized_.Wait(); |
+} |
+ |
+dispatch_queue_t LibDispatchTaskRunner::GetDispatchQueue() const { |
+ return queue_; |
+} |
+ |
+LibDispatchTaskRunner::~LibDispatchTaskRunner() { |
+ if (queue_) { |
+ dispatch_set_context(queue_, NULL); |
+ dispatch_set_finalizer_f(queue_, NULL); |
+ dispatch_release(queue_); |
+ } |
+} |
+ |
+void LibDispatchTaskRunner::Finalizer(void* context) { |
+ LibDispatchTaskRunner* self = static_cast<LibDispatchTaskRunner*>(context); |
+ self->queue_finalized_.Signal(); |
+} |
+ |
+} // namespace mac |
+} // namespace base |