From be63ec85a81119bc21734d0c4dc7f2b150433ed3 Mon Sep 17 00:00:00 2001 From: Janus Date: Tue, 7 Apr 2015 16:12:20 +0000 Subject: [PATCH] Showimage: Wait for loader threads on exit. * Uses find_thread to wait for loader threads. (better solutions are welcome) * As suggested by Axel the cache isn't static anymore. * Fixes 8902. --- src/apps/showimage/ImageCache.cpp | 28 ++++++++++++++++++++++---- src/apps/showimage/ImageCache.h | 9 +++------ src/apps/showimage/ShowImageApp.cpp | 1 + src/apps/showimage/ShowImageApp.h | 3 +++ src/apps/showimage/ShowImageWindow.cpp | 4 ++-- 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/apps/showimage/ImageCache.cpp b/src/apps/showimage/ImageCache.cpp index 6f3e5ff298..43bb9bf755 100644 --- a/src/apps/showimage/ImageCache.cpp +++ b/src/apps/showimage/ImageCache.cpp @@ -38,9 +38,6 @@ struct QueueEntry { }; -/*static*/ ImageCache ImageCache::sCache; - - // #pragma mark - @@ -82,7 +79,7 @@ ImageCache::ImageCache() ImageCache::~ImageCache() { - // TODO: delete CacheEntries, and QueueEntries + Stop(); } @@ -160,6 +157,29 @@ ImageCache::RetrieveImage(const entry_ref& ref, int32 page, } +void +ImageCache::Stop() +{ + // empty the working queue + fLocker.Lock(); + while (!fQueue.empty()) { + QueueEntry* entry = *fQueue.begin(); + fQueue.pop_front(); + delete entry; + } + fLocker.Unlock(); + + // wait for running thread + thread_id thread; + while (true) { + thread = find_thread("image loader"); + if (thread == B_NAME_NOT_FOUND) + break; + wait_for_thread(thread, NULL); + } +} + + /*static*/ status_t ImageCache::_QueueWorkerThread(void* _self) { diff --git a/src/apps/showimage/ImageCache.h b/src/apps/showimage/ImageCache.h index ac572c02fa..000cb32e4e 100644 --- a/src/apps/showimage/ImageCache.h +++ b/src/apps/showimage/ImageCache.h @@ -53,15 +53,14 @@ struct CacheEntry : DoublyLinkedListLinkImpl { class ImageCache { public: - static ImageCache& Default() { return sCache; } - + ImageCache(); + virtual ~ImageCache(); status_t RetrieveImage(const entry_ref& ref, int32 page = 1, const BMessenger* target = NULL); + void Stop(); private: - ImageCache(); - virtual ~ImageCache(); static status_t _QueueWorkerThread(void* self); @@ -91,8 +90,6 @@ private: uint64 fBytes; uint64 fMaxBytes; size_t fMaxEntries; - - static ImageCache sCache; }; diff --git a/src/apps/showimage/ShowImageApp.cpp b/src/apps/showimage/ShowImageApp.cpp index c3147da98e..5e8feeb159 100644 --- a/src/apps/showimage/ShowImageApp.cpp +++ b/src/apps/showimage/ShowImageApp.cpp @@ -174,6 +174,7 @@ ShowImageApp::QuitRequested() be_clipboard->StopWatching(be_app_messenger); // tell clipboard we don't want anymore notification } + DefaultCache().Stop(); return result; } diff --git a/src/apps/showimage/ShowImageApp.h b/src/apps/showimage/ShowImageApp.h index 7fc690785a..b75a2f2a15 100644 --- a/src/apps/showimage/ShowImageApp.h +++ b/src/apps/showimage/ShowImageApp.h @@ -11,6 +11,7 @@ #define SHOW_IMAGE_APP_H +#include "ImageCache.h" #include "ShowImageSettings.h" #include @@ -35,6 +36,7 @@ public: virtual bool QuitRequested(); ShowImageSettings* Settings() { return &fSettings; } + ImageCache& DefaultCache() { return fImageCache; } private: void _StartPulse(); @@ -48,6 +50,7 @@ private: BFilePanel* fOpenPanel; bool fPulseStarted; ShowImageSettings fSettings; + ImageCache fImageCache; BRect fLastWindowFrame; }; diff --git a/src/apps/showimage/ShowImageWindow.cpp b/src/apps/showimage/ShowImageWindow.cpp index f8fd3d4757..90fce00342 100644 --- a/src/apps/showimage/ShowImageWindow.cpp +++ b/src/apps/showimage/ShowImageWindow.cpp @@ -1234,7 +1234,7 @@ status_t ShowImageWindow::_LoadImage(bool forward) { BMessenger us(this); - status_t status = ImageCache::Default().RetrieveImage( + status_t status = my_app->DefaultCache().RetrieveImage( fNavigator.CurrentRef(), fNavigator.CurrentPage(), &us); if (status != B_OK) return status; @@ -1263,7 +1263,7 @@ ShowImageWindow::_PreloadImage(bool forward, entry_ref& ref) || (!forward && !fNavigator.GetPreviousFile(currentRef, ref))) return false; - return ImageCache::Default().RetrieveImage(ref) == B_OK; + return my_app->DefaultCache().RetrieveImage(ref) == B_OK; }