mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-27 20:58:47 +00:00
planner: don't pass reference to asynchronous lambda
A reference to a unique_ptr<> was captured by a lambda used to calculate variations in the background. This is of course disastrous, because if the caller runs first it will delete the object. It's a wonder that this didn't crash regularly!? The problem is that capturing unique_ptr<>s in lambdas works, but makes the lambda non-copyable. Sadly, the QtConcurrent::run() function wants to copy the lambda. For now, do this by a release/reaquire pair. This is not exception safe. However, sine Qt doesn't support exceptions, we can live with that. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
ee25e8a1db
commit
f585726283
1 changed files with 14 additions and 2 deletions
|
@ -1142,8 +1142,20 @@ void DivePlannerPointsModel::updateDiveProfile()
|
|||
// Since we're calling computeVariations asynchronously and plan_deco_state is allocated
|
||||
// on the stack, it must be copied and freed by the worker-thread.
|
||||
auto plan_deco_state_copy = std::make_unique<deco_state>(plan_deco_state);
|
||||
QtConcurrent::run([this, plan_copy, &plan_deco_state_copy] ()
|
||||
{ this->computeVariationsFreeDeco(plan_copy, std::move(plan_deco_state_copy)); });
|
||||
|
||||
// Ideally, we would pass the unique_ptr to the lambda for QtConcurrent::run().
|
||||
// This, in principle, can be done as such:
|
||||
// [ptr = std::move(ptr)] () mutable { f(std::move(ptr)) };
|
||||
// However, this make the lambda uncopyable and QtConcurrent::run() sadly
|
||||
// uses copy semantics.
|
||||
// So let's be pragmatic and do a release/reaquire pair.
|
||||
// Somewhat disappointing, but what do you want to do?
|
||||
// Note 1: this is now not exception safe, but Qt doesn't support
|
||||
// exceptions anyway.
|
||||
// Note 2: We also can't use the function / argument syntax of QtConcurrent::run(),
|
||||
// because it likewise uses copy-semantics. How annoying.
|
||||
QtConcurrent::run([this, plan_copy, deco = plan_deco_state_copy.release()] ()
|
||||
{ this->computeVariationsFreeDeco(plan_copy, std::unique_ptr<deco_state>(deco)); });
|
||||
#else
|
||||
computeVariations(plan_copy, &plan_deco_state);
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue