lyrics fetcher: limit number of worker threads downloading lyrics in background
This commit is contained in:
@@ -39,7 +39,9 @@ using Global::myOldScreen;
|
|||||||
|
|
||||||
#ifdef HAVE_CURL_CURL_H
|
#ifdef HAVE_CURL_CURL_H
|
||||||
LyricsFetcher **Lyrics::itsFetcher = 0;
|
LyricsFetcher **Lyrics::itsFetcher = 0;
|
||||||
std::set<MPD::Song *> Lyrics::itsDownloaded;
|
std::queue<MPD::Song *> Lyrics::itsToDownload;
|
||||||
|
pthread_mutex_t Lyrics::itsDIBLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
size_t Lyrics::itsWorkersNumber = 0;
|
||||||
#endif // HAVE_CURL_CURL_H
|
#endif // HAVE_CURL_CURL_H
|
||||||
|
|
||||||
Lyrics *myLyrics = new Lyrics;
|
Lyrics *myLyrics = new Lyrics;
|
||||||
@@ -106,7 +108,7 @@ void Lyrics::SwitchTo()
|
|||||||
if (isReadyToTake)
|
if (isReadyToTake)
|
||||||
Take();
|
Take();
|
||||||
|
|
||||||
if (isDownloadInProgress || !itsDownloaded.empty())
|
if (isDownloadInProgress || itsWorkersNumber > 0)
|
||||||
{
|
{
|
||||||
ShowMessage("Lyrics are being downloaded...");
|
ShowMessage("Lyrics are being downloaded...");
|
||||||
return;
|
return;
|
||||||
@@ -170,20 +172,56 @@ void Lyrics::DownloadInBackground(const MPD::Song *s)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ShowMessage("Fetching lyrics for %s...", s->toString(Config.song_status_format_no_colors).c_str());
|
ShowMessage("Fetching lyrics for %s...", s->toString(Config.song_status_format_no_colors).c_str());
|
||||||
// we need to copy it and store separetely since this song may get deleted in the meantime.
|
|
||||||
MPD::Song *s_copy = new MPD::Song(*s);
|
MPD::Song *s_copy = new MPD::Song(*s);
|
||||||
itsDownloaded.insert(s_copy);
|
pthread_mutex_lock(&itsDIBLock);
|
||||||
pthread_t t;
|
if (itsWorkersNumber == itsMaxWorkersNumber)
|
||||||
pthread_attr_t attr;
|
itsToDownload.push(s_copy);
|
||||||
pthread_attr_init(&attr);
|
else
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
{
|
||||||
pthread_create(&t, &attr, DownloadInBackgroundImpl, s_copy);
|
++itsWorkersNumber;
|
||||||
|
pthread_t t;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
pthread_create(&t, &attr, DownloadInBackgroundImpl, s_copy);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&itsDIBLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *Lyrics::DownloadInBackgroundImpl(void *void_ptr)
|
void *Lyrics::DownloadInBackgroundImpl(void *void_ptr)
|
||||||
{
|
{
|
||||||
MPD::Song *s = static_cast<MPD::Song *>(void_ptr);
|
MPD::Song *s = static_cast<MPD::Song *>(void_ptr);
|
||||||
|
DownloadInBackgroundImplHelper(s);
|
||||||
|
delete s;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&itsDIBLock);
|
||||||
|
if (itsToDownload.empty())
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&itsDIBLock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s = itsToDownload.front();
|
||||||
|
itsToDownload.pop();
|
||||||
|
pthread_mutex_unlock(&itsDIBLock);
|
||||||
|
}
|
||||||
|
DownloadInBackgroundImplHelper(s);
|
||||||
|
delete s;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&itsDIBLock);
|
||||||
|
--itsWorkersNumber;
|
||||||
|
pthread_mutex_unlock(&itsDIBLock);
|
||||||
|
|
||||||
|
pthread_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lyrics::DownloadInBackgroundImplHelper(MPD::Song *s)
|
||||||
|
{
|
||||||
std::string artist = Curl::escape(locale_to_utf_cpy(s->GetArtist()));
|
std::string artist = Curl::escape(locale_to_utf_cpy(s->GetArtist()));
|
||||||
std::string title = Curl::escape(locale_to_utf_cpy(s->GetTitle()));
|
std::string title = Curl::escape(locale_to_utf_cpy(s->GetTitle()));
|
||||||
|
|
||||||
@@ -199,11 +237,6 @@ void *Lyrics::DownloadInBackgroundImpl(void *void_ptr)
|
|||||||
}
|
}
|
||||||
if (result.first == true)
|
if (result.first == true)
|
||||||
Save(GenerateFilename(*s), result.second);
|
Save(GenerateFilename(*s), result.second);
|
||||||
|
|
||||||
delete s;
|
|
||||||
itsDownloaded.erase(s);
|
|
||||||
|
|
||||||
pthread_exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *Lyrics::Download()
|
void *Lyrics::Download()
|
||||||
|
|||||||
13
src/lyrics.h
13
src/lyrics.h
@@ -22,6 +22,7 @@
|
|||||||
#define _LYRICS_H
|
#define _LYRICS_H
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
#include "ncmpcpp.h"
|
#include "ncmpcpp.h"
|
||||||
#include "mpdpp.h"
|
#include "mpdpp.h"
|
||||||
@@ -72,8 +73,16 @@ class Lyrics : public Screen<Scrollpad>
|
|||||||
|
|
||||||
# ifdef HAVE_CURL_CURL_H
|
# ifdef HAVE_CURL_CURL_H
|
||||||
static void *DownloadInBackgroundImpl(void *);
|
static void *DownloadInBackgroundImpl(void *);
|
||||||
// storage for songs for which lyrics are being downloaded at the moment
|
static void DownloadInBackgroundImplHelper(MPD::Song *);
|
||||||
static std::set<MPD::Song *> itsDownloaded;
|
// lock for allowing exclusive access to itsToDownload and itsWorkersNumber
|
||||||
|
static pthread_mutex_t itsDIBLock;
|
||||||
|
// storage for songs for which lyrics are scheduled to be downloaded
|
||||||
|
static std::queue<MPD::Song *> itsToDownload;
|
||||||
|
// current worker threads (ie. downloading lyrics)
|
||||||
|
static size_t itsWorkersNumber;
|
||||||
|
// maximum number of worker threads. if it's reached, next lyrics requests
|
||||||
|
// are put into itsToDownload queue.
|
||||||
|
static const size_t itsMaxWorkersNumber = 4;
|
||||||
|
|
||||||
void *Download();
|
void *Download();
|
||||||
static void *DownloadWrapper(void *);
|
static void *DownloadWrapper(void *);
|
||||||
|
|||||||
Reference in New Issue
Block a user