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