1// Copyright 2013 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/task-queue.h"
6
7#include "src/base/logging.h"
8#include "src/base/platform/platform.h"
9#include "src/base/platform/time.h"
10
11namespace v8 {
12namespace platform {
13
14TaskQueue::TaskQueue() : process_queue_semaphore_(0), terminated_(false) {}
15
16
17TaskQueue::~TaskQueue() {
18  base::LockGuard<base::Mutex> guard(&lock_);
19  DCHECK(terminated_);
20  DCHECK(task_queue_.empty());
21}
22
23
24void TaskQueue::Append(Task* task) {
25  base::LockGuard<base::Mutex> guard(&lock_);
26  DCHECK(!terminated_);
27  task_queue_.push(task);
28  process_queue_semaphore_.Signal();
29}
30
31
32Task* TaskQueue::GetNext() {
33  for (;;) {
34    {
35      base::LockGuard<base::Mutex> guard(&lock_);
36      if (!task_queue_.empty()) {
37        Task* result = task_queue_.front();
38        task_queue_.pop();
39        return result;
40      }
41      if (terminated_) {
42        process_queue_semaphore_.Signal();
43        return NULL;
44      }
45    }
46    process_queue_semaphore_.Wait();
47  }
48}
49
50
51void TaskQueue::Terminate() {
52  base::LockGuard<base::Mutex> guard(&lock_);
53  DCHECK(!terminated_);
54  terminated_ = true;
55  process_queue_semaphore_.Signal();
56}
57
58void TaskQueue::BlockUntilQueueEmptyForTesting() {
59  for (;;) {
60    {
61      base::LockGuard<base::Mutex> guard(&lock_);
62      if (task_queue_.empty()) return;
63    }
64    base::OS::Sleep(base::TimeDelta::FromMilliseconds(5));
65  }
66}
67
68}  // namespace platform
69}  // namespace v8
70