Home | History | Annotate | Download | only in src
      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_
      6 #define V8_LOCKED_QUEUE_INL_
      7 
      8 #include "src/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   AtomicValue<Node*> next;
     19 };
     20 
     21 
     22 template <typename Record>
     23 inline LockedQueue<Record>::LockedQueue() {
     24   head_ = new Node();
     25   CHECK(head_ != nullptr);
     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(n != nullptr);
     47   n->value = record;
     48   {
     49     base::LockGuard<base::Mutex> 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::LockGuard<base::Mutex> 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::LockGuard<base::Mutex> 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::LockGuard<base::Mutex> 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_
     92