Skip to content

Commit

Permalink
imagelist: Use thread-safe queue for thumbnail queue
Browse files Browse the repository at this point in the history
Moved thread-safe queue into it's own header so it can be used in both
the imagelist and imagefetcher.
  • Loading branch information
ahodesuka committed Dec 5, 2017
1 parent 3198c85 commit f34b4d5
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 55 deletions.
40 changes: 4 additions & 36 deletions src/booru/imagefetcher.h
Original file line number Diff line number Diff line change
@@ -1,49 +1,17 @@
#ifndef _IMAGEFETCHER_H_
#define _IMAGEFETCHER_H_

#include "curler.h"

#include <mutex>
#include <queue>
#include <thread>

#include "curler.h"
#include "tsqueue.h"

namespace AhoViewer
{
namespace Booru
{
class ImageFetcher : public sigc::trackable
{
// Thread-safe queue {{{
template <typename T>
class Queue
{
public:
bool push(T value)
{
std::unique_lock<std::mutex> lock(m_Mutex);
m_Queue.push(value);
return true;
}
bool pop(T & v)
{
std::unique_lock<std::mutex> lock(m_Mutex);
if (m_Queue.empty())
return false;
v = m_Queue.front();
m_Queue.pop();
return true;
}
void clear()
{
std::unique_lock<std::mutex> lock(m_Mutex);
while (!m_Queue.empty()) m_Queue.pop();
}

private:
std::queue<T> m_Queue;
std::mutex m_Mutex;
};
// }}}
public:
ImageFetcher();
virtual ~ImageFetcher();
Expand Down Expand Up @@ -79,7 +47,7 @@ namespace AhoViewer

CURLM *m_MultiHandle;
int m_RunningHandles;
Queue<Curler*> m_CurlerQueue;
TSQueue<Curler*> m_CurlerQueue;
std::vector<Curler*> m_Curlers;

std::weak_ptr<Glib::Dispatcher> m_SignalHandleAdded;
Expand Down
20 changes: 4 additions & 16 deletions src/imagelist.cc
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,7 @@ void ImageList::load_thumbnails()
return;

const Glib::RefPtr<Gdk::Pixbuf> thumb = m_Images[i]->get_thumbnail();
{
std::lock_guard<std::mutex> lock(m_ThumbnailMutex);
m_ThumbnailQueue.push(PixbufPair(i, std::move(thumb)));
}
m_ThumbnailQueue.push(PixbufPair(i, std::move(thumb)));

if (!m_ThumbnailCancel->is_cancelled())
m_SignalThumbnailLoaded();
Expand Down Expand Up @@ -256,8 +253,7 @@ void ImageList::cancel_thumbnail_thread()
if (m_ThumbnailThread.joinable())
m_ThumbnailThread.join();

std::lock_guard<std::mutex> lock(m_ThumbnailMutex);
m_ThumbnailQueue = std::queue<PixbufPair>();
m_ThumbnailQueue.clear();
}

// Returns an unsorted vector of the paths to valid T's.
Expand Down Expand Up @@ -287,18 +283,10 @@ std::vector<std::string> ImageList::get_entries(const std::string &path)
void ImageList::on_thumbnail_loaded()
{
m_ThumbnailLoadedConn.block();
PixbufPair p;

while (!m_ThumbnailCancel->is_cancelled() && !m_ThumbnailQueue.empty())
{
std::unique_lock<std::mutex> lock(m_ThumbnailMutex);
PixbufPair p = m_ThumbnailQueue.front();
lock.unlock();
while (!m_ThumbnailCancel->is_cancelled() && m_ThumbnailQueue.pop(p))
m_Widget->set_pixbuf(p.first, p.second);
lock.lock();
// Queue may have been clared during set_pixbuf
if (!m_ThumbnailQueue.empty())
m_ThumbnailQueue.pop();
}

m_ThumbnailLoadedConn.unblock();
}
Expand Down
6 changes: 3 additions & 3 deletions src/imagelist.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

#include <gtkmm.h>
#include <memory>
#include <queue>
#include <string>
#include <vector>

#include "archive/archive.h"
#include "booru/xml.h"
#include "image.h"
#include "threadpool.h"
#include "tsqueue.h"

namespace AhoViewer
{
Expand All @@ -27,7 +27,7 @@ namespace AhoViewer
using SignalArchiveErrorType = sigc::signal<void, const std::string>;

// Used for async thumbnail pixbuf loading
using PixbufPair = std::pair<size_t, const Glib::RefPtr<Gdk::Pixbuf>>;
using PixbufPair = std::pair<size_t, Glib::RefPtr<Gdk::Pixbuf>>;
public:
// ImageList::Widget {{{
// This is used by ThumbnailBar and Booru::Page.
Expand Down Expand Up @@ -154,7 +154,7 @@ namespace AhoViewer
std::vector<size_t> m_Cache;
std::unique_ptr<Archive> m_Archive;
std::vector<std::string> m_ArchiveEntries;
std::queue<PixbufPair> m_ThumbnailQueue;
TSQueue<PixbufPair> m_ThumbnailQueue;
std::function<int(size_t, size_t)> m_IndexSort;

Glib::RefPtr<Gio::Cancellable> m_CacheCancel;
Expand Down
40 changes: 40 additions & 0 deletions src/tsqueue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef _TSQUEUE_H_
#define _TSQUEUE_H_

#include <mutex>
#include <queue>

namespace AhoViewer
{
template <typename T>
class TSQueue
{
public:
bool push(T v)
{
std::unique_lock<std::mutex> lock(m_Mutex);
m_Queue.push(v);
return true;
}
bool pop(T &v)
{
std::unique_lock<std::mutex> lock(m_Mutex);
if (m_Queue.empty())
return false;
v = m_Queue.front();
m_Queue.pop();
return true;
}
void clear()
{
std::unique_lock<std::mutex> lock(m_Mutex);
while (!m_Queue.empty()) m_Queue.pop();
}

private:
std::queue<T> m_Queue;
std::mutex m_Mutex;
};
}

#endif /* _TSQUEUE_H_ */

0 comments on commit f34b4d5

Please sign in to comment.