@@ -78,15 +78,16 @@ void DSCTriageView::loadImagesWithAddr(const std::vector<uint64_t>& addresses, b
7878 if (!controller)
7979 return ;
8080
81- std::map<uint64_t , CacheImage> images = {};
81+ typedef std::vector<CacheImage> ImageList;
82+ ImageList images = {};
8283 for (const uint64_t & addr : addresses)
8384 {
8485 auto image = controller->GetImageContaining (addr);
8586 if (image.has_value ())
8687 {
8788 // Only try to load if we have not already.
8889 if (!controller->IsImageLoaded (*image))
89- images.insert ({image-> headerAddress , *image} );
90+ images.emplace_back ( *image);
9091
9192 // TODO: We currently only add direct dependencies, may want to make the depth configurable?
9293 if (includeDependencies)
@@ -97,7 +98,7 @@ void DSCTriageView::loadImagesWithAddr(const std::vector<uint64_t>& addresses, b
9798 auto depImage = controller->GetImageWithName (depName);
9899 if (depImage.has_value () && !controller->IsImageLoaded (*depImage))
99100 {
100- images.insert ({depImage-> headerAddress , *depImage} );
101+ images.emplace_back ( *depImage);
101102 }
102103 }
103104 }
@@ -107,26 +108,46 @@ void DSCTriageView::loadImagesWithAddr(const std::vector<uint64_t>& addresses, b
107108 // Don't create a worker action if we don't have any images.
108109 if (images.empty ())
109110 return ;
111+ Ref<BackgroundTask> imageLoadTask = new BackgroundTask (" Loading images..." , true );
110112
111- WorkerPriorityEnqueue ([controller, this , images]() {
112- size_t loadedImages = 0 ;
113- const std::string initialLoad = fmt::format (" Loading images... (0/{})" , images.size ());
114- auto imageLoadTask = BackgroundTask (initialLoad, true );
113+ // Apply the images in a future than update the triage view and run analysis.
114+ QPointer<QFutureWatcher<ImageList>> watcher = new QFutureWatcher<ImageList>(this );
115+ connect (watcher, &QFutureWatcher<ImageList>::finished, this , [watcher, this ]() {
116+ if (watcher)
117+ {
118+ auto loadedImages = watcher->result ();
119+ if (loadedImages.empty ())
120+ return ;
121+
122+ // Update the triage to display the images as loaded.
123+ for (const auto & image : loadedImages)
124+ setImageLoaded (image.headerAddress );
115125
116- for (const auto & [addr, image] : images)
126+ // Run analysis.
127+ this ->m_data ->AddAnalysisOption (" linearsweep" );
128+ this ->m_data ->UpdateAnalysis ();
129+ }
130+ });
131+ QFuture<ImageList> future = QtConcurrent::run ([this , controller, images, imageLoadTask]() {
132+ ImageList loadedImages = {};
133+ for (const auto & image : images)
117134 {
118- if (imageLoadTask. IsCancelled ())
135+ if (imageLoadTask-> IsCancelled () || QThread::currentThread ()-> isInterruptionRequested ())
119136 break ;
120- std::string newLoad = fmt::format (" Loading images... ({}/{})" , loadedImages++ , images.size ());
121- imageLoadTask. SetProgressText (newLoad);
137+ std::string newLoad = fmt::format (" Loading images... ({}/{})" , loadedImages. size () , images.size ());
138+ imageLoadTask-> SetProgressText (newLoad);
122139 if (controller->ApplyImage (*this ->m_data , image))
123- setImageLoaded (image.headerAddress );
140+ loadedImages.emplace_back (image);
141+ }
142+ imageLoadTask->Finish ();
143+ return loadedImages;
144+ });
145+ watcher->setFuture (future);
146+ connect (this , &QObject::destroyed, this , [watcher, imageLoadTask]() {
147+ if (watcher && watcher->isRunning ()) {
148+ watcher->cancel ();
149+ imageLoadTask->Cancel ();
124150 }
125- imageLoadTask.Finish ();
126-
127- // We have loaded images, lets make sure to update analysis!
128- this ->m_data ->AddAnalysisOption (" linearsweep" );
129- this ->m_data ->UpdateAnalysis ();
130151 });
131152}
132153
0 commit comments