LCOV - code coverage report
Current view: top level - src/libplatform - delayed-task-queue.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 36 37 97.3 %
Date: 2019-03-21 Functions: 7 8 87.5 %

          Line data    Source code
       1             : // Copyright 2019 the V8 project 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 "src/libplatform/delayed-task-queue.h"
       6             : 
       7             : #include "include/v8-platform.h"
       8             : #include "src/base/logging.h"
       9             : #include "src/base/platform/time.h"
      10             : 
      11             : namespace v8 {
      12             : namespace platform {
      13             : 
      14       60135 : DelayedTaskQueue::DelayedTaskQueue(TimeFunction time_function)
      15      180405 :     : time_function_(time_function) {}
      16             : 
      17      114112 : DelayedTaskQueue::~DelayedTaskQueue() {
      18       57056 :   base::MutexGuard guard(&lock_);
      19             :   DCHECK(terminated_);
      20             :   DCHECK(task_queue_.empty());
      21       57056 : }
      22             : 
      23           0 : double DelayedTaskQueue::MonotonicallyIncreasingTime() {
      24          86 :   return time_function_();
      25             : }
      26             : 
      27     1357441 : void DelayedTaskQueue::Append(std::unique_ptr<Task> task) {
      28     1357441 :   base::MutexGuard guard(&lock_);
      29             :   DCHECK(!terminated_);
      30             :   task_queue_.push(std::move(task));
      31     1357441 :   queues_condition_var_.NotifyOne();
      32     1357441 : }
      33             : 
      34          35 : void DelayedTaskQueue::AppendDelayed(std::unique_ptr<Task> task,
      35             :                                      double delay_in_seconds) {
      36             :   DCHECK_GE(delay_in_seconds, 0.0);
      37          35 :   double deadline = MonotonicallyIncreasingTime() + delay_in_seconds;
      38             :   {
      39          35 :     base::MutexGuard guard(&lock_);
      40             :     DCHECK(!terminated_);
      41             :     delayed_task_queue_.emplace(deadline, std::move(task));
      42          35 :     queues_condition_var_.NotifyOne();
      43             :   }
      44          35 : }
      45             : 
      46     1775651 : std::unique_ptr<Task> DelayedTaskQueue::GetNext() {
      47     1775651 :   base::MutexGuard guard(&lock_);
      48             :   for (;;) {
      49             :     // Move delayed tasks that have hit their deadline to the main queue.
      50     3305140 :     std::unique_ptr<Task> task = PopTaskFromDelayedQueue();
      51     3305208 :     while (task) {
      52             :       task_queue_.push(std::move(task));
      53          68 :       task = PopTaskFromDelayedQueue();
      54             :     }
      55     3305140 :     if (!task_queue_.empty()) {
      56             :       std::unique_ptr<Task> result = std::move(task_queue_.front());
      57             :       task_queue_.pop();
      58             :       return result;
      59             :     }
      60             : 
      61     1947665 :     if (terminated_) {
      62      399353 :       queues_condition_var_.NotifyAll();
      63             :       return nullptr;
      64             :     }
      65             : 
      66     1548312 :     if (task_queue_.empty() && !delayed_task_queue_.empty()) {
      67             :       // Wait for the next delayed task or a newly posted task.
      68             :       double now = MonotonicallyIncreasingTime();
      69           4 :       double wait_in_seconds = delayed_task_queue_.begin()->first - now;
      70             :       base::TimeDelta wait_delta = base::TimeDelta::FromMicroseconds(
      71           4 :           base::TimeConstants::kMicrosecondsPerSecond * wait_in_seconds);
      72             : 
      73             :       // WaitFor unfortunately doesn't care about our fake time and will wait
      74             :       // the 'real' amount of time, based on whatever clock the system call
      75             :       // uses.
      76           4 :       bool notified = queues_condition_var_.WaitFor(&lock_, wait_delta);
      77             :       USE(notified);
      78             :     } else {
      79     1548308 :       queues_condition_var_.Wait(&lock_);
      80             :     }
      81             :   }
      82             : }
      83             : 
      84             : // Gets the next task from the delayed queue for which the deadline has passed
      85             : // according to |time_function_|. Returns nullptr if no such task exists.
      86     3305174 : std::unique_ptr<Task> DelayedTaskQueue::PopTaskFromDelayedQueue() {
      87     3305174 :   if (delayed_task_queue_.empty()) return nullptr;
      88             : 
      89             :   double now = MonotonicallyIncreasingTime();
      90             : 
      91             :   auto it = delayed_task_queue_.begin();
      92          47 :   if (it->first > now) return nullptr;
      93             : 
      94             :   std::unique_ptr<Task> result = std::move(it->second);
      95             :   delayed_task_queue_.erase(it);
      96             :   return result;
      97             : }
      98             : 
      99       57056 : void DelayedTaskQueue::Terminate() {
     100       57056 :   base::MutexGuard guard(&lock_);
     101             :   DCHECK(!terminated_);
     102       57056 :   terminated_ = true;
     103       57056 :   queues_condition_var_.NotifyAll();
     104       57056 : }
     105             : 
     106             : }  // namespace platform
     107             : }  // namespace v8

Generated by: LCOV version 1.10