title: Proper usage of std::promise and std::future, segfaults
body: <p>I've been trying my luck on a small threadpool implementation.
  However, after conceptualizing and implementing i've hit a brick wall.
  I've confirmed that the worker threads ate starting up and sleeping correctly, also that they pick up and execute stored tasks correctly.
  However, my program segfaults - i'm pretty sure its at <code>promise.set_value</code>.</p>
  
  <p>Im not sure how i could provide a complete, verifiable example (given that i can hardly upload the whole code) but i'll include the segments
  i believe to be relevant to this problem.
  First off, workers are created like this:</p>
  
  <pre><code>worker = [this](){
      while(true)
      {
          std::unique_lock&lt;std::mutex&gt; lock(mStatusMutex); //CV for status updates
          mCV.wait(lock);
          if(mStatus != Running) //If threadpool status does not imply running
              break; //Break out of loop, ending thread in the process
          else //If threadpool is in running state
          {
              lock.unlock(); //Unlock state
              while(true) //Loop until no tasks are left
              {
                  mTasksMutex.lock(); //Lock task queue
                  if(mTasks.empty()) //IF no tasks left, break out of loop and return to waiting
                  {
                      mTasksMutex.unlock();
                      break;
                  }
                  else //Else, retrieve a task, unlock the task queue and execute the task
                  {
                      std::function&lt;void()&gt; task = mTasks.front();
                      mTasks.pop();
                      mTasksMutex.unlock();
                      task(); //Execute task
                  }
              }
          }
      }
  };
  </code></pre>
  
  <p>And then started and stored into a <code>std::vector&lt;std::thread&gt;</code> like this:</p>
  
  <pre><code>std::thread tWorker(worker);
  mWorkers.push_back(std::move(tWorker));
  </code></pre>
  
  <p>Now, the tricky part i believe to be the following is when adding/executing tasks to the task queue, which is a <code>std::queue&lt;std::function&lt;void()&gt;&gt;</code>.
  The following two functions are relevant here:</p>
  
  <pre><code>template&lt;typename RT&gt;
  inline std::future&lt;RT&gt; queueTask(std::function&lt;RT()&gt; _task, bool _execute = false)
  {
      std::promise&lt;RT&gt; promise;
      std::function&lt;void()&gt; func([&amp;_task, &amp;promise]() -&gt; RT {
          RT val = _task();
          promise.set_value(val);
      });
  
      mTasksMutex.lock();
      mTasks.emplace(func);
      mTasksMutex.unlock();
      if(_execute) flush();
      return promise.get_future();
  }
  inline void flush()
  {
      mCV.notify_all();
  }
  </code></pre>
  
  <p>Is there anything principally wrong with this approach? 
  For anyone who believes this to be a bad question, feel free to tell me how i can improve it.
  Full code is hosted on <a href="https://github.com/calcyss/cernel" rel="nofollow noreferrer" title="github">my github repo</a>.</p>