|
|
|
@ -71,7 +71,7 @@ class Queue {
|
|
|
|
|
arr_(nullptr),
|
|
|
|
|
head_(0),
|
|
|
|
|
tail_(0),
|
|
|
|
|
my_name_(std::move(Services::GetUniqueID())),
|
|
|
|
|
my_name_(Services::GetUniqueID()),
|
|
|
|
|
alloc_(Services::GetInstance().GetServiceMemPool()) {
|
|
|
|
|
Init();
|
|
|
|
|
MS_LOG(DEBUG) << "Create Q with uuid " << my_name_ << " of size " << sz_ << ".";
|
|
|
|
@ -154,7 +154,16 @@ class Queue {
|
|
|
|
|
uint32_t k = head_++ % sz_;
|
|
|
|
|
*p = std::move(arr_[k]);
|
|
|
|
|
if (std::is_destructible<T>::value) {
|
|
|
|
|
// std::move above only changes arr_[k] from rvalue to lvalue.
|
|
|
|
|
// The real implementation of move constructor depends on T.
|
|
|
|
|
// It may be compiler generated or user defined. But either case
|
|
|
|
|
// the result of arr_[k] is still a valid object of type T, and
|
|
|
|
|
// we will not keep any extra copy in the queue.
|
|
|
|
|
arr_[k].~T();
|
|
|
|
|
// For gcc 9, an extra fix is needed here to clear the memory content
|
|
|
|
|
// of arr_[k] because this slot can be reused by another Add which can
|
|
|
|
|
// do another std::move. We have seen SEGV here in this case.
|
|
|
|
|
std::allocator_traits<Allocator<T>>::construct(alloc_, &(arr_[k]));
|
|
|
|
|
}
|
|
|
|
|
full_cv_.NotifyAll();
|
|
|
|
|
_lock.unlock();
|
|
|
|
|