1

I've tried to use boost::lockfree::spsc_queue. Occasinally found segfault, when used it with std::vector<uint16_t>. The whole type is:

spsc_queue<vector<uint16_t>, boost::lockfree::capacity<1000>> queue;

Debugging showed, that segfault happend on pop, which was organized this way:

vector<uint16_t> vec;
while(!done)
  while(quuee.pop(&vec)){ /* do staff */}

Documentation on spsc_queue says:

bool pop(T & ret);

Pops one object from ringbuffer.

But, when I use

vector<uint16_t> vec;
while(!done)
  while(quuee.pop(&vec,1)){
    /* do staff */
  }

Segfault magically disappears. This makes me thinking, that bool pop(T&) somehow tries to restore as many items as possible.

Am I correctly use this container? Is this issue should happen to vector-like containers only? Is that staff rarely used, so it is buggy? What caveats I could face when I'm using it with vectors?

Community
  • 1
  • 1
Vasiliy Stavenko
  • 1,174
  • 1
  • 12
  • 29

1 Answers1

1

Segfault magically disappears. This makes me thinking, that bool pop(T&) somehow tries to restore as many items as possible.

That's magical thinking. It's not true

Am I correctly use this container?

We can't tell because you don't show how you're using it. (Only a fragment)

Is this issue should happen to vector-like containers only? Is that staff rarely used, so it is buggy?

Magical thinking again

What caveats I could face when I'm using it with vectors?

The same as with other types: Did you violate the threading invariants? Do you read from 1 single thread, and write from 1 single other thread?

UPDATE

Thanks for adding a SSCCE.

It was indeed a subtle bug in usage (I missed it earlier). You're passing a pointer to value and the queue element type is not convertible to that.

That means that the single-value overload is not applicable.

The overload that is taken is the the single-argument overload taking an OutputIterator.

template<typename OutputIterator> 
  boost::disable_if< typename is_convertible< T, OutputIterator >::type, size_type >::type 
  pop(OutputIterator it);

Pops objects to the output iterator it

Note

  • Thread-safe and wait-free

Requires:

  • only one thread is allowed to pop data to the spsc_queue

Returns:

number of popped items

Oops. You're invoking UB there as it will assign to &value+1 etc. This was indeed causing std::vector::assign to cry loudly.

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Here' the failing source. As I said, when setting one element to read in `pop` - it workds perfectly. http://dpaste.com/21KVVMV – Vasiliy Stavenko Oct 14 '15 at 10:02
  • Welcome to [UB](https://en.wikipedia.org/wiki/Undefined_behavior). "It works perfectly" is a perfectly acceptible outcome of UB. It's just not dependable. I'll look at the code later. – sehe Oct 14 '15 at 12:53
  • It's not UB. It's predictable in terms of using some other container. And it's predictable in terms of documentation of SPSC queue. Because this queue's behavior is guarantied if our data structure is copyable and has default constructor. `std::vector` fits perfectly. – Vasiliy Stavenko Oct 14 '15 at 16:38
  • Huh. I'm happy to hear you have no problem. Why are you here? I know you don't seem to have wrong usage (you asked, remember). But clearly you have issues that shouldn't occur. UB is simply the most likely cause. I didn't say the UB is caused by the queue usage. Also, the fact that it's predictable does not make it not undefined. – sehe Oct 14 '15 at 17:07
  • Ok. Is it bug? Is it documentation problem? – Vasiliy Stavenko Oct 14 '15 at 17:13
  • I can repeat it but it won't help. Is there a SSCCE? Yes there's a bug _somewhere_ of course is highly unlikely to be in the library code. Most likely there is a source of UB elsewhere. – sehe Oct 14 '15 at 17:40
  • @VasiliyStavenko FOUND IT! You're passing a pointer where a reference is needed. Sadly, that means your pointer is treated [as an output iterator for the overload that indeed gets as many items as possible](http://www.boost.org/doc/libs/1_59_0/doc/html/boost/lockfree/spsc_queue.html#idp151605744-bb) – sehe Oct 14 '15 at 19:04
  • Here's the recorded livestream for reference https://www.livecoding.tv/video/finding-ub-in-spsc_queue-usage/ ([experiment](http://chat.stackoverflow.com/transcript/10?m=24182469#24182469)) – sehe Oct 14 '15 at 19:12
  • 1
    Wooohoo! Thank you very much! Nice catch! – Vasiliy Stavenko Oct 14 '15 at 20:14