1 | // Copyright 2015 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 | #ifndef V8_LOCKED_QUEUE_INL_H_ |
6 | #define V8_LOCKED_QUEUE_INL_H_ |
7 | |
8 | #include "src/base/atomic-utils.h" |
9 | #include "src/locked-queue.h" |
10 | |
11 | namespace v8 { |
12 | namespace internal { |
13 | |
14 | template <typename Record> |
15 | struct LockedQueue<Record>::Node : Malloced { |
16 | Node() : next(nullptr) {} |
17 | Record value; |
18 | base::AtomicValue<Node*> next; |
19 | }; |
20 | |
21 | |
22 | template <typename Record> |
23 | inline LockedQueue<Record>::LockedQueue() { |
24 | head_ = new Node(); |
25 | CHECK_NOT_NULL(head_); |
26 | tail_ = head_; |
27 | } |
28 | |
29 | |
30 | template <typename Record> |
31 | inline LockedQueue<Record>::~LockedQueue() { |
32 | // Destroy all remaining nodes. Note that we do not destroy the actual values. |
33 | Node* old_node = nullptr; |
34 | Node* cur_node = head_; |
35 | while (cur_node != nullptr) { |
36 | old_node = cur_node; |
37 | cur_node = cur_node->next.Value(); |
38 | delete old_node; |
39 | } |
40 | } |
41 | |
42 | |
43 | template <typename Record> |
44 | inline void LockedQueue<Record>::Enqueue(const Record& record) { |
45 | Node* n = new Node(); |
46 | CHECK_NOT_NULL(n); |
47 | n->value = record; |
48 | { |
49 | base::MutexGuard guard(&tail_mutex_); |
50 | tail_->next.SetValue(n); |
51 | tail_ = n; |
52 | } |
53 | } |
54 | |
55 | |
56 | template <typename Record> |
57 | inline bool LockedQueue<Record>::Dequeue(Record* record) { |
58 | Node* old_head = nullptr; |
59 | { |
60 | base::MutexGuard guard(&head_mutex_); |
61 | old_head = head_; |
62 | Node* const next_node = head_->next.Value(); |
63 | if (next_node == nullptr) return false; |
64 | *record = next_node->value; |
65 | head_ = next_node; |
66 | } |
67 | delete old_head; |
68 | return true; |
69 | } |
70 | |
71 | |
72 | template <typename Record> |
73 | inline bool LockedQueue<Record>::IsEmpty() const { |
74 | base::MutexGuard guard(&head_mutex_); |
75 | return head_->next.Value() == nullptr; |
76 | } |
77 | |
78 | |
79 | template <typename Record> |
80 | inline bool LockedQueue<Record>::Peek(Record* record) const { |
81 | base::MutexGuard guard(&head_mutex_); |
82 | Node* const next_node = head_->next.Value(); |
83 | if (next_node == nullptr) return false; |
84 | *record = next_node->value; |
85 | return true; |
86 | } |
87 | |
88 | } // namespace internal |
89 | } // namespace v8 |
90 | |
91 | #endif // V8_LOCKED_QUEUE_INL_H_ |
92 |