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-04-17 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       61029 : DelayedTaskQueue::DelayedTaskQueue(TimeFunction time_function)
      15      183087 :     : time_function_(time_function) {}
      16             : 
      17      115872 : DelayedTaskQueue::~DelayedTaskQueue() {
      18       57936 :   base::MutexGuard guard(&lock_);
      19             :   DCHECK(terminated_);
      20             :   DCHECK(task_queue_.empty());
      21       57936 : }
      22             : 
      23           0 : double DelayedTaskQueue::MonotonicallyIncreasingTime() {
      24     4079761 :   return time_function_();
      25             : }
      26             : 
      27     1771292 : void DelayedTaskQueue::Append(std::unique_ptr<Task> task) {
      28     1771292 :   base::MutexGuard guard(&lock_);
      29             :   DCHECK(!terminated_);
      30             :   task_queue_.push(std::move(task));
      31     1771292 :   queues_condition_var_.NotifyOne();
      32     1771292 : }
      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     2196409 : std::unique_ptr<Task> DelayedTaskQueue::GetNext() {
      47     2196409 :   base::MutexGuard guard(&lock_);
      48             :   for (;;) {
      49             :     // Move delayed tasks that have hit their deadline to the main queue.
      50             :     double now = MonotonicallyIncreasingTime();
      51     4079726 :     std::unique_ptr<Task> task = PopTaskFromDelayedQueue(now);
      52     4079794 :     while (task) {
      53             :       task_queue_.push(std::move(task));
      54          68 :       task = PopTaskFromDelayedQueue(now);
      55             :     }
      56     4079726 :     if (!task_queue_.empty()) {
      57             :       std::unique_ptr<Task> result = std::move(task_queue_.front());
      58             :       task_queue_.pop();
      59             :       return result;
      60             :     }
      61             : 
      62     2308400 :     if (terminated_) {
      63      405513 :       queues_condition_var_.NotifyAll();
      64             :       return nullptr;
      65             :     }
      66             : 
      67     1902887 :     if (task_queue_.empty() && !delayed_task_queue_.empty()) {
      68             :       // Wait for the next delayed task or a newly posted task.
      69           1 :       double wait_in_seconds = delayed_task_queue_.begin()->first - now;
      70             :       base::TimeDelta wait_delta = base::TimeDelta::FromMicroseconds(
      71           1 :           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           1 :       bool notified = queues_condition_var_.WaitFor(&lock_, wait_delta);
      77             :       USE(notified);
      78             :     } else {
      79     1902886 :       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 |now|. Returns nullptr if no such task exists.
      86     4079760 : std::unique_ptr<Task> DelayedTaskQueue::PopTaskFromDelayedQueue(double now) {
      87     4079760 :   if (delayed_task_queue_.empty()) return nullptr;
      88             : 
      89             :   auto it = delayed_task_queue_.begin();
      90          44 :   if (it->first > now) return nullptr;
      91             : 
      92             :   std::unique_ptr<Task> result = std::move(it->second);
      93             :   delayed_task_queue_.erase(it);
      94             :   return result;
      95             : }
      96             : 
      97       57936 : void DelayedTaskQueue::Terminate() {
      98       57936 :   base::MutexGuard guard(&lock_);
      99             :   DCHECK(!terminated_);
     100       57936 :   terminated_ = true;
     101       57936 :   queues_condition_var_.NotifyAll();
     102       57936 : }
     103             : 
     104             : }  // namespace platform
     105             : }  // namespace v8

Generated by: LCOV version 1.10