mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-18 16:21:07 +00:00
Fix an edge case where m_remainingItems has elements but we don't have more workers to consume it
This commit is contained in:
parent
dbae196f2d
commit
30798435d1
@ -203,6 +203,13 @@ ThumbnailGenerator* ThumbnailGenerator::instance()
|
||||
return singleton;
|
||||
}
|
||||
|
||||
ThumbnailGenerator::ThumbnailGenerator()
|
||||
{
|
||||
int n = std::thread::hardware_concurrency()-1;
|
||||
if (n < 1) n = 1;
|
||||
m_maxWorkers = n;
|
||||
}
|
||||
|
||||
bool ThumbnailGenerator::checkWorkers()
|
||||
{
|
||||
base::scoped_lock hold(m_workersAccess);
|
||||
@ -231,17 +238,31 @@ void ThumbnailGenerator::generateThumbnail(IFileItem* fileitem)
|
||||
return;
|
||||
|
||||
if (fileitem->getThumbnailProgress() > 0.0) {
|
||||
if (fileitem->getThumbnailProgress() < 0.0002) {
|
||||
if (fileitem->getThumbnailProgress() == 0.00001) {
|
||||
m_remainingItems.prioritize(
|
||||
[fileitem](const Item& item) {
|
||||
return (item.fileitem == fileitem);
|
||||
});
|
||||
|
||||
// If there is no more workers running, we have to start a new
|
||||
// one to process the m_remainingItems queue. How is it possible
|
||||
// that a IFileItem has a thumbnail progress == 0.00001 but
|
||||
// there is no workers? This is an edge case where:
|
||||
// 1. The Worker::loadBgThread() asks for the queue of remaining items
|
||||
// and it's empty, so the thread is going to be closed
|
||||
// 2. We've just created a FOP for this IFileItem and ask for
|
||||
// available workers and we've already launch the max quantity
|
||||
// of possible workers (m_maxWorkers)
|
||||
// 3. All worker threads are just closed so there is no more
|
||||
// worker for the remaining item in the queue.
|
||||
if (m_workers.empty())
|
||||
startWorker();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Set a starting progress so we don't enqueue the same item two times.
|
||||
fileitem->setThumbnailProgress(0.0001);
|
||||
fileitem->setThumbnailProgress(0.00001);
|
||||
|
||||
THUMB_TRACE("Queue FOP thumbnail for %s\n",
|
||||
fileitem->fileName().c_str());
|
||||
@ -261,19 +282,7 @@ void ThumbnailGenerator::generateThumbnail(IFileItem* fileitem)
|
||||
m_remainingItems.push(Item(fileitem, fop.get()));
|
||||
fop.release();
|
||||
|
||||
int n = std::thread::hardware_concurrency()-1;
|
||||
if (n < 1) n = 1;
|
||||
if (m_workers.size() < n) {
|
||||
Worker* worker = new Worker(m_remainingItems);
|
||||
try {
|
||||
base::scoped_lock hold(m_workersAccess);
|
||||
m_workers.push_back(worker);
|
||||
}
|
||||
catch (...) {
|
||||
delete worker;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
startWorker();
|
||||
}
|
||||
|
||||
void ThumbnailGenerator::stopAllWorkers()
|
||||
@ -296,4 +305,14 @@ void ThumbnailGenerator::stopAllWorkers()
|
||||
worker->stop();
|
||||
}
|
||||
|
||||
void ThumbnailGenerator::startWorker()
|
||||
{
|
||||
base::scoped_lock hold(m_workersAccess);
|
||||
if (m_workers.size() < m_maxWorkers) {
|
||||
std::unique_ptr<Worker> worker(new Worker(m_remainingItems));
|
||||
m_workers.push_back(worker.get());
|
||||
worker.release();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -24,6 +24,7 @@ namespace app {
|
||||
class IFileItem;
|
||||
|
||||
class ThumbnailGenerator {
|
||||
ThumbnailGenerator();
|
||||
public:
|
||||
static ThumbnailGenerator* instance();
|
||||
|
||||
@ -43,6 +44,8 @@ namespace app {
|
||||
void stopAllWorkers();
|
||||
|
||||
private:
|
||||
void startWorker();
|
||||
|
||||
class Worker;
|
||||
typedef std::vector<Worker*> WorkerList;
|
||||
|
||||
@ -56,6 +59,7 @@ namespace app {
|
||||
}
|
||||
};
|
||||
|
||||
int m_maxWorkers;
|
||||
WorkerList m_workers;
|
||||
base::mutex m_workersAccess;
|
||||
std::unique_ptr<base::thread> m_stopThread;
|
||||
|
Loading…
x
Reference in New Issue
Block a user