title: C++ Blocking Queue Segfault w/ Boost
body: <p>I had a need for a Blocking Queue in C++ with timeout-capable <code>offer()</code>. The queue is intended for <strong>multiple producers, one consumer</strong>. Back when I was implementing, I didn't find any good existing queues that fit this need, so I coded it myself.</p>
  
  <p>I'm seeing segfaults come out of the <code>take()</code> method on the queue, but they are intermittent. I've been looking over the code for issues but I'm not seeing anything that looks problematic.</p>
  
  <p>I'm wondering if:</p>
  
  <ul>
  <li>There is an existing library that does this reliably that I should
  use (boost or header-only preferred). </li>
  <li>Anyone sees any obvious flaw in my code that I need to fix.</li>
  </ul>
  
  <p>Here is the header:</p>
  
  <pre><code>class BlockingQueue
  {
      public:
          BlockingQueue(unsigned int capacity) : capacity(capacity) { };
          bool offer(const MyType &amp; myType, unsigned int timeoutMillis);
          MyType take();
          void put(const MyType &amp; myType);
          unsigned int getCapacity();
          unsigned int getCount();
  
      private:
           std::deque&lt;MyType&gt; queue;
           unsigned int capacity;
  };
  </code></pre>
  
  <p>And the relevant implementations:</p>
  
  <pre><code>boost::condition_variable cond;
  boost::mutex mut;
  
  bool BlockingQueue::offer(const MyType &amp; myType, unsigned int timeoutMillis)
  {
      Timer timer;
  
      // boost::unique_lock is a scoped lock - its destructor will call unlock().
      // So no need for us to make that call here.
      boost::unique_lock&lt;boost::mutex&gt; lock(mut);
  
      // We use a while loop here because the monitor may have woken up because
      // another producer did a PulseAll. In that case, the queue may not have
      // room, so we need to re-check and re-wait if that is the case.
      // We use an external stopwatch to stop the madness if we have taken too long.
      while (queue.size() &gt;= this-&gt;capacity)
      {
          int monitorTimeout = timeoutMillis - ((unsigned int) timer.getElapsedMilliSeconds());
  
          if (monitorTimeout &lt;= 0)
          {
              return false;
          }
  
          if (!cond.timed_wait(lock, boost::posix_time::milliseconds(timeoutMillis)))
          {
              return false;
          }
      }
  
      cond.notify_all();
  
      queue.push_back(myType);
  
      return true;
  }
  
  void BlockingQueue::put(const MyType &amp; myType)
  {
      // boost::unique_lock is a scoped lock - its destructor will call unlock().
      // So no need for us to make that call here.
      boost::unique_lock&lt;boost::mutex&gt; lock(mut);
  
      // We use a while loop here because the monitor may have woken up because
      // another producer did a PulseAll. In that case, the queue may not have
      // room, so we need to re-check and re-wait if that is the case.
      // We use an external stopwatch to stop the madness if we have taken too long.
      while (queue.size() &gt;= this-&gt;capacity)
      {
          cond.wait(lock);
      }
  
      cond.notify_all();
  
      queue.push_back(myType);
  }
  
  MyType BlockingQueue::take()
  {
      // boost::unique_lock is a scoped lock - its destructor will call unlock().
      // So no need for us to make that call here.
      boost::unique_lock&lt;boost::mutex&gt; lock(mut);
  
      while (queue.size() == 0)
      {
          cond.wait(lock);
      }
  
      cond.notify_one();
  
      MyType myType = this-&gt;queue.front();
  
      this-&gt;queue.pop_front();
  
      return myType;
  }
  
  unsigned int BlockingQueue::getCapacity()
  {
      return this-&gt;capacity;
  }
  
  unsigned int BlockingQueue::getCount()
  {
      return this-&gt;queue.size();
  }
  </code></pre>
  
  <p>And yes, I didn't implement the class using templates - that is next on the list :)</p>
  
  <p>Any help is greatly appreciated. Threading issues can be really hard to pin down.</p>
  
  <p>-Ben</p>