mirror of
https://github.com/clangen/musikcube.git
synced 2025-03-14 13:21:13 +00:00
* Fixed a bug where queries may be enqueued into the library during
shutdown, and run after calling components have been destroyed. * Fixed a bug in PlaybackService where the "ModeChanged" event wasn't getting called after shuffling, and sometimes not on the MessageQueue thread.
This commit is contained in:
parent
7721f7d412
commit
5b9338c61e
@ -206,7 +206,6 @@ void PlaybackService::PrepareNextTrack() {
|
||||
void PlaybackService::SetRepeatMode(RepeatMode mode) {
|
||||
if (this->repeatMode != mode) {
|
||||
this->repeatMode = mode;
|
||||
this->ModeChanged();
|
||||
POST(this, MESSAGE_PREPARE_NEXT_TRACK, NO_POSITION, 0);
|
||||
POST(this, MESSAGE_MODE_CHANGED, 0, 0);
|
||||
}
|
||||
@ -244,6 +243,8 @@ void PlaybackService::ToggleShuffle() {
|
||||
POST(this, MESSAGE_PREPARE_NEXT_TRACK, NO_POSITION, 0);
|
||||
}
|
||||
}
|
||||
|
||||
POST(this, MESSAGE_MODE_CHANGED, 0, 0);
|
||||
}
|
||||
|
||||
void PlaybackService::ProcessMessage(IMessage &message) {
|
||||
@ -323,6 +324,7 @@ void PlaybackService::ProcessMessage(IMessage &message) {
|
||||
for (auto it = remotes.begin(); it != remotes.end(); it++) {
|
||||
(*it)->OnModeChanged(repeatMode, shuffled);
|
||||
}
|
||||
this->ModeChanged();
|
||||
}
|
||||
else if (type == MESSAGE_TIME_CHANGED) {
|
||||
this->TimeChanged(transport.Position());
|
||||
|
@ -58,6 +58,7 @@ namespace musik { namespace core {
|
||||
virtual int Id() = 0;
|
||||
virtual const std::string& Name() = 0;
|
||||
virtual void SetMessageQueue(musik::core::runtime::IMessageQueue& queue) = 0;
|
||||
virtual void Close() = 0;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<ILibrary> ILibraryPtr;
|
||||
|
@ -81,6 +81,10 @@ ILibraryPtr LibraryFactory::AddLibrary(int id, int type, const std::string& name
|
||||
}
|
||||
|
||||
void LibraryFactory::Shutdown() {
|
||||
for (ILibraryPtr library : this->libraries) {
|
||||
library->Close();
|
||||
}
|
||||
|
||||
Instance().libraries.clear();
|
||||
}
|
||||
|
||||
|
@ -98,10 +98,7 @@ LocalLibrary::LocalLibrary(std::string name,int id)
|
||||
}
|
||||
|
||||
LocalLibrary::~LocalLibrary() {
|
||||
this->Exit();
|
||||
this->thread->join();
|
||||
delete this->thread;
|
||||
delete this->indexer;
|
||||
this->Close();
|
||||
}
|
||||
|
||||
int LocalLibrary::Id() {
|
||||
@ -112,6 +109,32 @@ const std::string& LocalLibrary::Name() {
|
||||
return this->name;
|
||||
}
|
||||
|
||||
void LocalLibrary::Close() {
|
||||
std::thread* thread = nullptr;
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
|
||||
if (this->indexer) {
|
||||
delete this->indexer;
|
||||
this->indexer = nullptr;
|
||||
}
|
||||
|
||||
if (this->thread) {
|
||||
thread = this->thread;
|
||||
this->thread = nullptr;
|
||||
this->exit = true;
|
||||
this->queryQueue.clear();
|
||||
this->Exit();
|
||||
}
|
||||
}
|
||||
|
||||
if (thread) {
|
||||
thread->join();
|
||||
delete thread;
|
||||
}
|
||||
}
|
||||
|
||||
std::string LocalLibrary::GetLibraryDirectory() {
|
||||
std::string directory(musik::core::GetDataDirectory());
|
||||
|
||||
@ -134,7 +157,11 @@ std::string LocalLibrary::GetDatabaseFilename() {
|
||||
}
|
||||
|
||||
int LocalLibrary::Enqueue(IQueryPtr query, unsigned int options) {
|
||||
std::unique_lock<std::recursive_mutex> lock(this->mutex);
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
|
||||
if (this->exit) { /* closed */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (options & ILibrary::QuerySynchronous) {
|
||||
this->RunQuery(query, false); /* false = do not notify via QueryCompleted */
|
||||
@ -152,20 +179,34 @@ int LocalLibrary::Enqueue(IQueryPtr query, unsigned int options) {
|
||||
}
|
||||
|
||||
bool LocalLibrary::Exited() {
|
||||
std::unique_lock<std::recursive_mutex> lock(this->mutex);
|
||||
return this->exit;
|
||||
}
|
||||
|
||||
void LocalLibrary::Exit() {
|
||||
{
|
||||
std::unique_lock<std::recursive_mutex> lock(this->mutex);
|
||||
this->exit = true;
|
||||
}
|
||||
|
||||
/* kick sleeping threads back to the top of the loop */
|
||||
this->exit = true;
|
||||
this->queueCondition.notify_all();
|
||||
}
|
||||
|
||||
void LocalLibrary::ThreadProc() {
|
||||
IQueryPtr query;
|
||||
|
||||
while (true) {
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
|
||||
if (query = GetNextQuery()) {
|
||||
this->RunQuery(query);
|
||||
}
|
||||
|
||||
if (!this->queryQueue.size() && !this->Exited()) {
|
||||
this->queueCondition.wait(lock);
|
||||
}
|
||||
|
||||
if (this->Exited()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IQueryPtr LocalLibrary::GetNextQuery() {
|
||||
if (queryQueue.size()) {
|
||||
IQueryPtr front = queryQueue.front();
|
||||
@ -206,24 +247,6 @@ void LocalLibrary::RunQuery(IQueryPtr query, bool notify) {
|
||||
}
|
||||
}
|
||||
|
||||
void LocalLibrary::ThreadProc() {
|
||||
while (!this->Exited()) {
|
||||
IQueryPtr query;
|
||||
|
||||
{
|
||||
std::unique_lock<std::recursive_mutex> lock(this->mutex);
|
||||
query = GetNextQuery();
|
||||
|
||||
while (!query && !this->Exited()) {
|
||||
this->queueCondition.wait(lock);
|
||||
query = GetNextQuery();
|
||||
}
|
||||
}
|
||||
|
||||
this->RunQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalLibrary::SetMessageQueue(musik::core::runtime::IMessageQueue& queue) {
|
||||
this->messageQueue = &queue;
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ namespace musik { namespace core { namespace library {
|
||||
virtual int Id();
|
||||
virtual const std::string& Name();
|
||||
virtual void SetMessageQueue(musik::core::runtime::IMessageQueue& queue);
|
||||
virtual void Close();
|
||||
|
||||
/* IMessageTarget */
|
||||
virtual void ProcessMessage(musik::core::runtime::IMessage &message);
|
||||
@ -107,8 +108,8 @@ namespace musik { namespace core { namespace library {
|
||||
bool exit;
|
||||
|
||||
std::thread* thread;
|
||||
std::condition_variable_any queueCondition;
|
||||
std::recursive_mutex mutex;
|
||||
std::condition_variable queueCondition;
|
||||
std::mutex mutex;
|
||||
|
||||
core::IIndexer *indexer;
|
||||
core::db::Connection db;
|
||||
|
Loading…
x
Reference in New Issue
Block a user