| 28 | } |
| 29 | |
| 30 | bool TranslatorsPool::Finish() |
| 31 | { |
| 32 | m_threadPool.WaitingStop(); |
| 33 | using TranslatorPtr = std::shared_ptr<TranslatorInterface>; |
| 34 | threads::ThreadSafeQueue<std::future<TranslatorPtr>> queue; |
| 35 | while (!m_translators.Empty()) |
| 36 | { |
| 37 | std::promise<TranslatorPtr> p; |
| 38 | std::shared_ptr<TranslatorInterface> translator; |
| 39 | m_translators.TryPop(translator); |
| 40 | p.set_value(translator); |
| 41 | queue.Push(p.get_future()); |
| 42 | } |
| 43 | |
| 44 | base::ComputationalThreadPool pool(queue.Size() / 2 + 1); |
| 45 | CHECK_GREATER_OR_EQUAL(queue.Size(), 1, ()); |
| 46 | while (queue.Size() != 1) |
| 47 | { |
| 48 | std::future<TranslatorPtr> left; |
| 49 | std::future<TranslatorPtr> right; |
| 50 | queue.WaitAndPop(left); |
| 51 | queue.WaitAndPop(right); |
| 52 | |
| 53 | struct State |
| 54 | { |
| 55 | std::future<TranslatorPtr> left; |
| 56 | std::future<TranslatorPtr> right; |
| 57 | }; |
| 58 | |
| 59 | // Should be copyable to workaround MSVC bug (https://developercommunity.visualstudio.com/t/108672) |
| 60 | auto state = std::make_shared<State>(); |
| 61 | state->left = std::move(left); |
| 62 | state->right = std::move(right); |
| 63 | |
| 64 | queue.Push(pool.Submit([state = std::move(state)]() mutable |
| 65 | { |
| 66 | auto leftTranslator = state->left.get(); |
| 67 | auto rigthTranslator = state->right.get(); |
| 68 | rigthTranslator->Finish(); |
| 69 | leftTranslator->Finish(); |
| 70 | leftTranslator->Merge(*rigthTranslator); |
| 71 | return leftTranslator; |
| 72 | })); |
| 73 | } |
| 74 | |
| 75 | std::future<TranslatorPtr> translatorFuture; |
| 76 | queue.WaitAndPop(translatorFuture); |
| 77 | auto translator = translatorFuture.get(); |
| 78 | translator->Finish(); |
| 79 | return translator->Save(); |
| 80 | } |
| 81 | } // namespace generator |
nothing calls this directly
no test coverage detected