std::pair<bool, T> try_pop_front() { retry: unique_lock l(head_->mutex_); node_ptr first = head_->next_; if (unlikely(!first)) return std::make_pair(false, T()); unique_lock l0(first->mutex_); T t = first->value_; bool is_tail = !first->next_; if (is_tail) { l0.unlock(); tail_ptr_mutex_.lock(); l0.lock(); assert(head_->next_ == first); if (first->next_) { // no longer tail, retry tail_ptr_mutex_.unlock(); goto retry; } assert(tail_ == first); } head_->next_ = first->next_; if (is_tail) { tail_ = head_; tail_ptr_mutex_.unlock(); } return std::make_pair(true, t); }
void pop_front() { retry: unique_lock l(head_->mutex_); node_ptr first = head_->next_; assert(first); unique_lock l0(first->mutex_); bool is_tail = !first->next_; if (is_tail) { l0.unlock(); tail_ptr_mutex_.lock(); l0.lock(); assert(head_->next_ == first); if (first->next_) { // no longer tail, retry tail_ptr_mutex_.unlock(); goto retry; } assert(tail_ == first); } head_->next_ = first->next_; if (is_tail) { tail_ = head_; tail_ptr_mutex_.unlock(); } }
inline void remove(const T &val) { node_ptr prev = head_; prev->mutex_.lock(); node_ptr cur = prev->next_; while (cur) { cur->mutex_.lock(); if (cur->value_ == val) { // unlink bool is_tail = !cur->next_; if (is_tail) { cur->mutex_.unlock(); tail_ptr_mutex_.lock(); cur->mutex_.lock(); assert(tail_ == cur); } prev->next_ = cur->next_; if (is_tail) { tail_ = prev; tail_ptr_mutex_.unlock(); } cur->mutex_.unlock(); cur = prev->next_; } else { prev->mutex_.unlock(); prev = cur; cur = cur->next_; } } prev->mutex_.unlock(); }
void wait(lock_type& m) { int res=0; { detail::interruption_checker check_for_interruption(&cond); { boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); m.unlock(); res=pthread_cond_wait(&cond,&internal_mutex); } m.lock(); } if(res) { boost::throw_exception(condition_error()); } }
bool timed_wait(lock_type& m,boost::system_time const& wait_until) { struct timespec const timeout=detail::get_timespec(wait_until); int res=0; { detail::interruption_checker check_for_interruption(&cond); { boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); m.unlock(); res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); } m.lock(); } if(res==ETIMEDOUT) { return false; } if(res) { boost::throw_exception(condition_error()); } return true; }
~thread_safe_agent_t() { lock_.unlock(); }