title: How to use `boost::thread_specific_ptr` with `for_each`
body: <p>In the code below, <code>Bar</code> is supposed to model a thread-unsafe object that is moderately expensive to create. <code>Foo</code> contains a <code>Bar</code> and is multi-threaded, so it uses a <code>thread_specific_ptr&lt;Bar&gt;</code> to make a per-thread <code>Bar</code> that can be re-used across multiple calls to <code>loop</code> for the same <code>Foo</code> (therefore amortizing the cost of creating a <code>Bar</code> for each thread). <code>Foo</code> always creates a <code>Bar</code> with the same <code>num</code>, so the sanity check is <em>supposed</em> to always pass, yet it fails.</p>
  <p>The reason for this is (I think) explained in the <a href="https://www.boost.org/doc/libs/1_76_0/doc/html/thread/thread_local_storage.html#thread.thread_local_storage.thread_specific_ptr.destructor" rel="nofollow noreferrer">requirement for the <code>thread_specific_ptr</code> destructor</a>:</p>
  <blockquote>
  <p>All the thread specific instances associated to this thread_specific_ptr (except maybe the one associated to this thread) must be null.</p>
  </blockquote>
  <p>So the problem is caused by a combination of three things:</p>
  <ol>
  <li><code>Bar</code> objects created in worker threads are not cleaned up when <code>Foo</code>s <code>thread_specific_ptr</code> is cleaned up, and are therefore persisted across iterations of the loop in <code>main</code> (essentially, a memory leak)</li>
  <li>The C++ runtime is re-using threads in <code>for_each</code> between iterations of the loop in <code>main</code></li>
  <li>The C++ runtime is re-allocating each <code>Foo</code> in the <code>main</code> loop to the same memory address</li>
  </ol>
  <p>The way that <code>thread_specific_ptr</code>s are indexed (by the <code>thread_specific_ptr</code>'s memory address and the thread ID) results in old <code>Bar</code>s being accidentally reused. I understand the problem; what I don't understand is what to do about it. Note the remark from the docs:</p>
  <blockquote>
  <p>The requirement is due to the fact that in order to delete all these instances, the implementation should be forced to maintain a list of all the threads having an associated specific ptr, which is against the goal of thread specific data.</p>
  </blockquote>
  <p>I'd like to avoid this complexity as well.</p>
  <p>How can I use <code>for_each</code> for simple thread management, but also avoid the memory leak? Solution requirements:</p>
  <ul>
  <li>It should only create one <code>Bar</code> per thread per <code>Foo</code> (i.e., don't create a new Bar inside the <code>for_each</code>)</li>
  <li>Assume <code>Bar</code> is not thread-safe.</li>
  <li>If possible, use <code>for_each</code> to make the parallel loop as simple as possible</li>
  <li>The loop should actually run in parallel (i.e., no mutex around a single <code>Bar</code>)</li>
  <li><code>Bar</code> objects created by <code>loop</code> should be available for use until the <code>Foo</code> object that created them is destructed, at which point all <code>Bar</code> objects should also be destructed.</li>
  </ul>
  <p>The following code compiles and should exit with return code 1 with high probability on a machine with sufficient cores.</p>
  <pre><code>#include &lt;boost/thread/tss.hpp&gt;
  #include &lt;execution&gt;
  #include &lt;iostream&gt;
  #include &lt;vector&gt;
  
  using namespace std;
  
  class Bar {
      public:
      // models a thread-unsafe object
      explicit Bar(int i) : num(i) { }
      int num;
  };
  
  class Foo {
      public:
      explicit Foo(int i) : num(i) { }
  
      void loop() {
          vector&lt;int&gt; idxs(32);
          iota(begin(idxs), end(idxs), 0);
          for_each(__pstl::execution::par, begin(idxs), end(idxs), [&amp;](int) {
              if (ptr.get() == nullptr) {
                  // no `Bar` exists for this thread yet, so create one
                  Bar *tmp = new Bar(num);
                  ptr.reset(tmp);
              }
              // Get the thread-local Bar
              Bar &amp;b = *ptr;
  
              // Sanity check: we ALWAYS create a `Bar` with the same num as `Foo`;
              // see the `if` block above.
              // Therefore, this condition shouldn't ever be true (but it is!)
              if (b.num != num) {
                 cout &lt;&lt; &quot;NOT THREAD SAFE: Foo index is &quot; &lt;&lt; num &lt;&lt; &quot;, but Bar index is &quot; &lt;&lt; b.num &lt;&lt; endl;
                 exit(1);
              }
          });
      }
      boost::thread_specific_ptr&lt;Bar&gt; ptr;
      int num;
  };
  
  int main() {
      for(int i = 0; i &lt; 100; i++) {
          Foo f(i);
          f.loop();
      }
      return 0;
  }
  </code></pre>