// atomically sets stack_ back and enqueues all elements to the cache
 bool fetch_new_data(pointer end_ptr) {
   CAF_ASSERT(end_ptr == nullptr || end_ptr == stack_empty_dummy());
   pointer e = stack_.load();
   // must not be called on a closed queue
   CAF_ASSERT(e != nullptr);
   // fetching data while blocked is an error
   CAF_ASSERT(e != reader_blocked_dummy());
   // it's enough to check this once, since only the owner is allowed
   // to close the queue and only the owner is allowed to call this
   // member function
   while (e != end_ptr) {
     if (stack_.compare_exchange_weak(e, end_ptr)) {
       // fetching data while blocked is an error
       CAF_ASSERT(e != reader_blocked_dummy());
       if (is_dummy(e)) {
         // only use-case for this is closing a queue
         CAF_ASSERT(end_ptr == nullptr);
         return false;
       }
       while (e) {
         CAF_ASSERT(! is_dummy(e));
         auto next = e->next;
         e->next = head_;
         head_ = e;
         e = next;
       }
       return true;
     }
     // next iteration
   }
   return false;
 }
Пример #2
0
 // atomically sets m_stack back and enqueues all elements to the cache
 bool fetch_new_data(pointer end_ptr) {
     CPPA_REQUIRE(m_head == nullptr);
     CPPA_REQUIRE(!end_ptr || end_ptr == stack_empty_dummy());
     pointer e = m_stack.load();
     // must not be called on a closed queue
     CPPA_REQUIRE(e != nullptr);
     // it's enough to check this once, since only the owner is allowed
     // to close the queue and only the owner is allowed to call this
     // member function
     while (e != end_ptr) {
         if (m_stack.compare_exchange_weak(e, end_ptr)) {
             if (is_dummy(e)) {
                 // only use-case for this is closing a queue
                 CPPA_REQUIRE(end_ptr == nullptr);
                 return false;
             }
             while (e) {
                 CPPA_REQUIRE(!is_dummy(e));
                 auto next = e->next;
                 e->next = m_head;
                 m_head = e;
                 e = next;
             }
             return true;
         }
         // next iteration
     }
     return false;
 }
 /// Tries to set this queue from state `empty` to state `blocked`.
 bool try_block() {
   auto e = stack_empty_dummy();
   bool res = stack_.compare_exchange_strong(e, reader_blocked_dummy());
   CAF_ASSERT(e != nullptr);
   // return true in case queue was already blocked
   return res || e == reader_blocked_dummy();
 }
Пример #4
0
 inline bool is_dummy(pointer ptr) {
     return ptr == stack_empty_dummy() || ptr == reader_blocked_dummy();
 }
Пример #5
0
 inline bool fetch_new_data() {
     return fetch_new_data(stack_empty_dummy());
 }
Пример #6
0
 inline single_reader_queue() : m_head(nullptr) {
     m_stack = stack_empty_dummy();
 }
Пример #7
0
 /**
  * @brief Tries to set this queue from state @p blocked to state @p empty.
  * @returns @p true if the state change was successful, otherwise @p false.
  * @note This function does never fail spuriously.
  */
 inline bool try_unblock() {
     auto e = reader_blocked_dummy();
     return m_stack.compare_exchange_strong(e, stack_empty_dummy());
 }
Пример #8
0
 /**
  * @brief Tries to set this queue from state @p empty to state @p blocked.
  * @returns @p true if the state change was successful or if the mailbox
  *          was already blocked, otherwise @p false.
  * @note This function does never fail spuriously.
  */
 inline bool try_block() {
     auto e = stack_empty_dummy();
     bool res = m_stack.compare_exchange_strong(e, reader_blocked_dummy());
     // return true in case queue was already blocked
     return res || e == reader_blocked_dummy();
 }
 single_reader_queue() : head_(nullptr) {
   stack_ = stack_empty_dummy();
 }