Start a thread to read an overlap. When the data has been read, stick the tile on the queue and notify the main thread.
| 530 | // Start a thread to read an overlap. When the data has been read, |
| 531 | // stick the tile on the queue and notify the main thread. |
| 532 | void EptReader::load(const ept::Overlap& overlap) |
| 533 | { |
| 534 | using namespace std::chrono_literals; |
| 535 | |
| 536 | m_p->pool->add([this, overlap]() |
| 537 | { |
| 538 | // Read the tile. |
| 539 | ept::TileContents tile(overlap, *m_p->info, *m_p->connector, m_p->addons); |
| 540 | |
| 541 | tile.read(); |
| 542 | |
| 543 | if (tile.error().size()) |
| 544 | { |
| 545 | log()->get(LogLevel::Warning) << "Failed to read " << |
| 546 | tile.key().toString() << ": " << tile.error() << std::endl; |
| 547 | } |
| 548 | |
| 549 | if (tile.error().empty() || !m_args->m_ignoreUnreadable) |
| 550 | { |
| 551 | // Put the tile on the output queue. Note that if the tile has |
| 552 | // an error and ignoreUnreadable isn't set, this will be fatal |
| 553 | // but that will occur downstream outside of this pool thread. |
| 554 | |
| 555 | while (!m_p->done) |
| 556 | { |
| 557 | { |
| 558 | std::lock_guard<std::mutex> l(m_p->mutex); |
| 559 | if (m_p->contents.size() < m_p->pool->numThreads()) |
| 560 | { |
| 561 | m_p->contents.push(std::move(tile)); |
| 562 | break; |
| 563 | } |
| 564 | } |
| 565 | // No room on queue, sleep. Could do a condition variable but that's |
| 566 | // more complex and probably makes no difference in most cases where |
| 567 | // this would come up. |
| 568 | std::this_thread::sleep_for(50ms); |
| 569 | } |
| 570 | } |
| 571 | else |
| 572 | { |
| 573 | // If the tile has an error, and the ignoreUnreadable option is |
| 574 | // set, then we just skip this tile. |
| 575 | std::lock_guard<std::mutex> l(m_p->mutex); |
| 576 | --m_tileCount; |
| 577 | } |
| 578 | |
| 579 | m_p->contentsCv.notify_one(); |
| 580 | } |
| 581 | ); |
| 582 | } |
| 583 | |
| 584 | |
| 585 | void EptReader::ready(PointTableRef table) |