title: How to get boost::object_pool thread safe?
body: <p>After asking <a href="https://stackoverflow.com/questions/19333595/is-there-a-faster-c-heap-allocation-deallocation-mechanism-available-than-boos?noredirect=1#comment28645338_19333595">Is there a faster heap allocation/deallocation mechanism available than boost::object_pool?</a> I got feedback that this object pool is NOT thread safe.</p>
  
  <p>So I wrote an ObjectFactory wrapping boost::object_pool and adding mutex locks:</p>
  
  <pre><code>#include &lt;memory&gt;
  using std::shared_ptr;
  
  #include &lt;boost/pool/object_pool.hpp&gt;
  #include &lt;boost/thread/mutex.hpp&gt;
  
  template &lt;typename T&gt;
  class ObjectFactory 
  {
  private:
      struct SharedDeleter 
      {
          ObjectFactory&lt;T&gt;* m_pFact;
  
          SharedDeleter(ObjectFactory&lt;T&gt;* fact) : m_pFact(fact) {}
  
          inline void operator()(T* p) const 
          {      
            m_pFact-&gt;destroy(p);
          }
      };
  
  
      boost::object_pool&lt;T&gt;   m_Pool;
      boost::mutex            m_PoolMutex;
  
      SharedDeleter           m_Deleter;
  
  
  public:
      ObjectFactory() : m_Deleter(this)
      {
      }
  
      template&lt;typename TType = T, typename... TArgs&gt; 
      inline TType* create(TArgs&amp;&amp;... mArgs)
      {
          boost::unique_lock&lt;boost::mutex&gt; scoped_lock(m_PoolMutex);
          return m_Pool.construct(mArgs...);
      }
  
      inline void destroy(T* mObj) 
      { 
          boost::unique_lock&lt;boost::mutex&gt; scoped_lock(m_PoolMutex);
          m_Pool.destroy(mObj); 
      }
  
  
      template&lt;typename TType = T, typename... TArgs&gt; 
      inline std::shared_ptr&lt;TType&gt; make_shared(TArgs&amp;&amp;... mArgs)
      {
          return std::shared_ptr&lt;TType&gt;(this-&gt;create(mArgs...), m_Deleter);
      }
  
  };
  </code></pre>
  
  <p>Timing results without the mutex lock:</p>
  
  <pre><code> With WithObjectFactory!: 
  Start time: 1381682855810868000 nanoseconds since Jan 1, 1970
  End time: 1381682863375427000 nanoseconds since Jan 1, 1970
  Duration: 7.56456 seconds
  
   With WithObjectFactory and std::shared_ptr!: 
  Start time: 1381682863375476000 nanoseconds since Jan 1, 1970
  End time: 1381682879114065000 nanoseconds since Jan 1, 1970
  Duration: 15.7386 seconds
  </code></pre>
  
  <p>Timing results WITH the mutex locks:</p>
  
  <pre><code> With WithObjectFactory!: 
  Start time: 1381683562246086000 nanoseconds since Jan 1, 1970
  End time: 1381683574399319000 nanoseconds since Jan 1, 1970
  Duration: 12.1532 seconds
  
   With WithObjectFactory and std::shared_ptr!: 
  Start time: 1381683574399378000 nanoseconds since Jan 1, 1970
  End time: 1381683595103438000 nanoseconds since Jan 1, 1970
  Duration: 20.7041 seconds
  </code></pre>
  
  <p>What you see is that the mutex locking takes more than 20% of the time leaving, IMHO, boost::object_pool only usable for single thread applications.</p>
  
  <p>My questions: 
  Am I using the proper locking mechanism?
  Does the destroy also needs a mutex lock?
  Is there any bug I am not seeing in above code?</p>
  
  <p>Thanks</p>
  
  <p>EDIT:
  Tested with std::map but is to slow. Found boost::thread_specific_ptr and it seems to work:</p>
  
  <pre><code>#include &lt;memory&gt;
  using std::shared_ptr;
  
  #include &lt;boost/pool/object_pool.hpp&gt;
  #include &lt;boost/thread.hpp&gt;
  
  template &lt;typename T&gt;
  class ObjectFactory 
  {
  private:
      struct SharedDeleter 
      {
          ObjectFactory&lt;T&gt;* m_pFact;
  
          SharedDeleter(ObjectFactory&lt;T&gt;* fact) : m_pFact(fact) {}
  
          inline void operator()(T* p) const 
          {      
            m_pFact-&gt;destroy(p);
          }
      };
  
      boost::thread_specific_ptr&lt;boost::object_pool&lt;T&gt;&gt;   m_tpPool;   
      SharedDeleter           m_Deleter;
  
  public:
      ObjectFactory() : m_Deleter(this)
      {
          if ( !m_tpPool.get() )
              m_tpPool.reset(new boost::object_pool&lt;T&gt;());
      }
  
      template&lt;typename TType = T, typename... TArgs&gt; 
      inline TType* create(TArgs&amp;&amp;... mArgs)
      {
          return m_tpPool-&gt;construct(mArgs...);
      }
  
      inline void destroy(T* mObj) 
      { 
          m_tpPool-&gt;destroy(mObj);
      }
  
      template&lt;typename TType = T, typename... TArgs&gt; 
      inline std::shared_ptr&lt;TType&gt; make_shared(TArgs&amp;&amp;... mArgs)
      {
          return std::shared_ptr&lt;TType&gt;(this-&gt;create(mArgs...), m_Deleter);
      }
  };
  </code></pre>
  
  <p>Results with above code:</p>
  
  <pre><code> With WithObjectFactory!: 
  Start time: 1381714923605177000 nanoseconds since Jan 1, 1970
  End time: 1381714934202228000 nanoseconds since Jan 1, 1970
  Duration: 10.5971 seconds
  
   With WithObjectFactory and std::shared_ptr!: 
  Start time: 1381714934202285000 nanoseconds since Jan 1, 1970
  End time: 1381714950900537000 nanoseconds since Jan 1, 1970
  Duration: 16.6983 seconds
  </code></pre>