title: boost mutex throwing (odd?) exception
body: <p>I am using a blocking queue example I got from this website, thinking it was pretty nice.
  This blocking queue is using boost::mutex.
  It is sometime throwing an exception : </p>
  
  <pre><code>terminate called after throwing an instance of 'boost::exception_detail::clone_impl&lt;boost::exception_detail::error_info_injector&lt;boost::system::system_error&gt; &gt;'
  </code></pre>
  
  <p>what():  Bad file descriptor</p>
  
  <p>Here's the Blocking Queue code : </p>
  
  <pre><code>#include &lt;boost/thread/mutex.hpp&gt;
  #include &lt;boost/thread/thread.hpp&gt;
  #include &lt;boost/thread/condition_variable.hpp&gt;
  #include &lt;exception&gt;
  #include &lt;list&gt;
  #include &lt;stdio.h&gt;
  
  struct BlockingQueueTerminate
    : std::exception
  {};
  
  namespace tools {
    template&lt;class T&gt;
    class BlockingQueue
    {
    private:
      boost::mutex mtx_;
      boost::condition_variable cnd_;
      std::list&lt;T&gt; q_;
      unsigned blocked_;
      bool stop_;
  
    public:
      BlockingQueue()
        : blocked_()
        , stop_()
      {}
  
      ~BlockingQueue()
      {
        this-&gt;stop(true);
      }
  
      void stop(bool wait)
      {
        // tell threads blocked on BlockingQueue::pull() to leave
        boost::mutex::scoped_lock lock(mtx_);
        stop_ = true;
        cnd_.notify_all();
  
        if(wait) // wait till all threads blocked on the queue leave BlockingQueue::pull()
      while(blocked_)
        cnd_.wait(lock);
      }
  
      void put(T t)
      {
        boost::mutex::scoped_lock lock(mtx_);  // The exception is thrown here !
        q_.push_back(t);
        cnd_.notify_one();
      }
  
    T pull()
      {
        boost::mutex::scoped_lock lock(mtx_);
        ++blocked_;
        while(!stop_ &amp;&amp; q_.empty())
      cnd_.wait(lock);
        --blocked_;
  
        if(stop_) {
      cnd_.notify_all(); // tell stop() this thread has left
      throw BlockingQueueTerminate();
        }
  
        T front = q_.front();
        q_.pop_front();
        return front;
      }
    };
  }
  </code></pre>
  
  <p>Anyone can spot what's going wrong here ? because I have tried the all day figuring it out in vain. I guess I need a outside eye to see it.
  Look for the comment '//The exception is thrown here !' to see where exactly the problem occurs.</p>
  
  <p>EDIT 1 : </p>
  
  <p>The context : I'm using this blocking queue in order to create a MySQL async wrapper.</p>
  
  <p>Here's my MySQL.hh</p>
  
  <pre><code>#ifndef MYSQL_HH_
  # define MYSQL_HH_
  # include &lt;boost/asio.hpp&gt;
  # include &lt;boost/thread.hpp&gt;
  # include &lt;boost/function.hpp&gt;
  # include &lt;mysql++/mysql++.h&gt;
  # include &lt;queue&gt;
  # include "async_executor.hh"
  # include "BlockingQueue.hh"
  
  class t_mysql_event {
  public:
    t_mysql_event(std::string query, boost::function&lt;void(mysqlpp::StoreQueryResult)&gt; cb) :
      m_query(query), m_store_cb(cb), m_store_bool(true) {}
  
    t_mysql_event(std::string query, boost::function&lt;void()&gt; cb) :
      m_query(query), m_exec_cb(cb),  m_store_bool(false) {}
  
    bool is_store_query() {
      return m_store_bool;
    }
  
    std::string toString() {
      return m_query;
    }
  
    std::string                       m_query;
    boost::function&lt;void(mysqlpp::StoreQueryResult)&gt;  m_store_cb;
    boost::function&lt;void()&gt;               m_exec_cb;
  
  private:
    bool                          m_store_bool;
  };
  
  namespace pools {
    class MySQL {
    public:
      ~MySQL() {}
  
      static MySQL* create_instance(boost::asio::io_service&amp; io);
  
      static MySQL* get_instance();
  
      void exec(std::string query, boost::function&lt;void()&gt; cb);
      void store(std::string query, boost::function&lt;void(mysqlpp::StoreQueryResult)&gt; cb);
  
    private:
      MySQL(boost::asio::io_service&amp; io) : executor(io, 100), parent_io(io), m_strand(io)
      {
        for (int i=0; i &lt; 100; ++i) {
      boost::thread(boost::bind(&amp;MySQL::retreive, this));
        }
      }
  
      void async_exec(std::string query, boost::function&lt;void()&gt; cb, mysqlpp::Connection&amp; conn);
      void async_store(std::string query, boost::function&lt;void(mysqlpp::StoreQueryResult)&gt; cb, mysqlpp::Connection&amp; conn);
  
      void retreive();
  
    private:
      tools::async_executor           executor;
      boost::asio::io_service&amp;        parent_io;
      boost::asio::strand         m_strand;
      tools::BlockingQueue&lt;t_mysql_event*&gt;    m_events;
      std::queue&lt;mysqlpp::Connection*&gt;    m_stack;
    };
  }
  
  #endif //MYSQL_HH_
  </code></pre>
  
  <p>Here's the MySQL.cc : </p>
  
  <pre><code>#include "MySQL.hh"
  
  static pools::MySQL* _instance = 0;
  
  namespace pools {
  
  
    MySQL* MySQL::create_instance(boost::asio::io_service&amp; io) {
      if (!_instance)
        _instance = new MySQL(io);
      return _instance;
    }
  
    MySQL* MySQL::get_instance() {
      if (!_instance) {
        exit(1);
      }
      return _instance;
    }
  
    void MySQL::exec(std::string query, boost::function&lt;void()&gt; cb) {
      m_events.put(new t_mysql_event(query, cb));
    }
  
    void MySQL::store(std::string query, boost::function&lt;void(mysqlpp::StoreQueryResult)&gt; cb) {
      m_events.put(new t_mysql_event(query, cb));
    }
  
    void MySQL::retreive() {
      mysqlpp::Connection conn("***", "***", "***", "***");
      for(;;) {
        t_mysql_event *event = m_events.pull();
        if (event-&gt;is_store_query())
      async_store(event-&gt;m_query, event-&gt;m_store_cb, conn);
        else
      async_exec(event-&gt;m_query, event-&gt;m_exec_cb, conn);
        delete event;
      }
    }
  
    void MySQL::async_exec(std::string query, boost::function&lt;void()&gt; cb, mysqlpp::Connection&amp; conn) {
      mysqlpp::Query db_q = conn.query(query.c_str());
      db_q.exec();
      parent_io.post(cb);
    }
  
    void MySQL::async_store(std::string query, boost::function&lt;void(mysqlpp::StoreQueryResult)&gt; cb, mysqlpp::Connection&amp; conn) {
      mysqlpp::Query db_q = conn.query(query.c_str());
      mysqlpp::StoreQueryResult res = db_q.store();
      parent_io.post(boost::bind(cb, res));
     }
  }
  </code></pre>
  
  <p>Afterwards : </p>
  
  <pre><code>class MyClass {
  public:
     MyClass() : _mysql(pools::MySQL::get_instance()) {}
  
     startQueries();
  private:
     void Query1() {
        std::stringstream query("");
        query &lt;&lt; "INSERT INTO Table1 ***";
        _mysql-&gt;exec(query.str(),
                     boost::bind(&amp;MyClass::Query2, this, _1));
     }
     void Query2() {
        std::stringstream query("");
        query &lt;&lt; "INSERT INTO Table2 ***";
        _mysql-&gt;exec(query.str(),
                     boost::bind(&amp;MyClass::Query3, this, _1));
     }
     void Query3() {
        std::stringstream query("");
        query &lt;&lt; "INSERT INTO Table3 ***";
        _mysql-&gt;exec(query.str(),
                     boost::bind(&amp;MyClass::done, this, _1));
     }
     void done() {}
     pools::MySQL *_mysql;
  };
  </code></pre>
  
  <p>Hoping that will answer to some request for more informations...</p>
  
  <p>Funny thing : </p>
  
  <p><strong>If I replace every _mysql by pools::MySQL::get_instance() I does not seems to crash.
  But I suspect there is an error far more important below that...</strong></p>