diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 7005341c2..037e9d5ac 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -23,7 +23,6 @@ set(CORE_SOURCES ./support/NonLibraryTrackHelper.cpp ./support/Preferences.cpp ./support/PreferenceKeys.cpp - ./support/ThreadHelper.cpp ./support/Version.cpp ../3rdparty/src/md5/md5.c ../3rdparty/src/sqlite/sqlite3.c diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj index c4e982a2b..664e94c70 100755 --- a/src/core/core.vcxproj +++ b/src/core/core.vcxproj @@ -111,7 +111,6 @@ - @@ -159,7 +158,6 @@ - diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters index acaf1cedd..50e9b613a 100755 --- a/src/core/core.vcxproj.filters +++ b/src/core/core.vcxproj.filters @@ -70,9 +70,6 @@ src\support - - src\support - src\support @@ -183,9 +180,6 @@ src\support - - src\support - src\library diff --git a/src/core/library/Indexer.cpp b/src/core/library/Indexer.cpp index d25ed1251..46c85fa7d 100644 --- a/src/core/library/Indexer.cpp +++ b/src/core/library/Indexer.cpp @@ -57,7 +57,7 @@ static const std::string TAG = "Indexer"; static const int MAX_THREADS = 10; -static const int NOTIFY_INTERVAL = 300; +static const size_t NOTIFY_INTERVAL = 300; using namespace musik::core; using namespace musik::core::metadata; @@ -82,9 +82,7 @@ static std::string normalizePath(const std::string& path) { Indexer::Indexer(const std::string& libraryPath, const std::string& dbFilename) : thread(nullptr) -, status(0) , restart(false) -, filesIndexed(0) , filesSaved(0) , prefs(Preferences::ForComponent(prefs::components::Settings)) , readSemaphore(prefs->GetInt(prefs::keys::MaxTagReadThreads, MAX_THREADS)) { @@ -95,7 +93,11 @@ Indexer::Indexer(const std::string& libraryPath, const std::string& dbFilename) Indexer::~Indexer() { if (this->thread) { - this->Exit(); + { + boost::mutex::scoped_lock lock(this->stateMutex); + this->exit = true; + } + this->thread->join(); delete this->thread; this->thread = nullptr; @@ -103,23 +105,18 @@ Indexer::~Indexer() { } void Indexer::Synchronize(bool restart) { - boost::mutex::scoped_lock lock(this->exitMutex); + boost::mutex::scoped_lock lock(this->stateMutex); this->restart = restart; this->Notify(); } -bool Indexer::Restarted() { - boost::mutex::scoped_lock lock(this->exitMutex); - return this->restart; -} - void Indexer::AddPath(const std::string& path) { Indexer::AddRemoveContext context; context.add = true; context.path = normalizeDir(path); { - boost::mutex::scoped_lock lock(this->exitMutex); + boost::mutex::scoped_lock lock(this->stateMutex); this->addRemoveQueue.push_back(context); } @@ -132,7 +129,7 @@ void Indexer::RemovePath(const std::string& path) { context.path = normalizeDir(path); { - boost::mutex::scoped_lock lock(this->exitMutex); + boost::mutex::scoped_lock lock(this->stateMutex); this->addRemoveQueue.push_back(context); } @@ -150,11 +147,6 @@ void Indexer::SynchronizeInternal(boost::asio::io_service* io) { this->audioDecoders = PluginFactory::Instance() .QueryInterface("GetDecoderFactory"); - { - boost::mutex::scoped_lock lock(this->progressMutex); - this->filesIndexed = 0; - } - this->ProcessAddRemoveQueue(); /* get sync paths and ids from the db */ @@ -182,12 +174,7 @@ void Indexer::SynchronizeInternal(boost::asio::io_service* io) { } /* add new files */ - - { - boost::mutex::scoped_lock lock(this->progressMutex); - this->status = 2; - this->filesSaved = 0; - } + this->filesSaved = 0; for(std::size_t i = 0; i < paths.size(); ++i) { this->trackTransaction.reset(new db::ScopedTransaction(this->dbConnection)); @@ -204,11 +191,6 @@ void Indexer::SynchronizeInternal(boost::asio::io_service* io) { musik::debug::info(TAG, "cleanup 1/2"); - { - boost::mutex::scoped_lock lock(this->progressMutex); - this->status = 3; - } - if (!this->Restarted() && !this->Exited()) { this->SyncDelete(); } @@ -217,12 +199,6 @@ void Indexer::SynchronizeInternal(boost::asio::io_service* io) { musik::debug::info(TAG, "cleanup 2/2"); - { - boost::mutex::scoped_lock lock(this->progressMutex); - this->status = 4; - } - - if (!this->Restarted() && !this->Exited()){ this->SyncCleanup(); } @@ -231,11 +207,6 @@ void Indexer::SynchronizeInternal(boost::asio::io_service* io) { musik::debug::info(TAG, "optimizing"); - { - boost::mutex::scoped_lock lock(this->progressMutex); - this->status = 5; - } - if (!this->Restarted() && !this->Exited()){ this->SyncOptimize(); } @@ -244,11 +215,6 @@ void Indexer::SynchronizeInternal(boost::asio::io_service* io) { this->metadataReaders.clear(); - { - boost::mutex::scoped_lock lock(this->progressMutex); - this->status = 0; - } - musik::debug::info(TAG, "done!"); } @@ -351,13 +317,13 @@ void Indexer::SyncDirectory( std::vector threads; for( ; file != end && !this->Exited() && !this->Restarted(); file++) { - if (this->filesSaved.load() > NOTIFY_INTERVAL) { + if (this->filesSaved > NOTIFY_INTERVAL) { if (this->trackTransaction) { this->trackTransaction->CommitAndRestart(); } this->TrackRefreshed(); - this->filesSaved.store(0); + this->filesSaved = 0; } if (is_directory(file->status())) { /* recursion here */ @@ -365,8 +331,6 @@ void Indexer::SyncDirectory( this->SyncDirectory(io, syncRoot, file->path().string(), pathId); } else { - ++this->filesIndexed; - if (io) { this->readSemaphore.wait(); @@ -400,7 +364,7 @@ void Indexer::ThreadLoop() { while (!this->Exited()) { this->restart = false; - if(!firstTime || (firstTime && prefs->GetBool(prefs::keys::SyncOnStartup, true))) { /* first time through the loop skips this */ + if(!firstTime || (firstTime && prefs->GetBool(prefs::keys::SyncOnStartup, false))) { /* first time through the loop skips this */ this->SynchronizeStart(); this->dbConnection.Open(this->dbFilename.c_str(), 0); /* ensure the db is open */ @@ -427,12 +391,6 @@ void Indexer::ThreadLoop() { #endif this->RunAnalyzers(); - - { - boost::mutex::scoped_lock lock(this->progressMutex); - this->status = 0; - } - this->dbConnection.Close(); /* TODO: raii */ this->SynchronizeEnd(); @@ -573,10 +531,6 @@ static int optimize( return count; } -////////////////////////////////////////// -///\brief -///Optimizes and fixing sorting and indexes -////////////////////////////////////////// void Indexer::SyncOptimize() { DBID count = 0, id = 0; @@ -602,7 +556,7 @@ void Indexer::SyncOptimize() { } void Indexer::ProcessAddRemoveQueue() { - boost::mutex::scoped_lock lock(this->exitMutex); + boost::mutex::scoped_lock lock(this->stateMutex); while (!this->addRemoveQueue.empty()) { AddRemoveContext context = this->addRemoveQueue.front(); @@ -644,13 +598,6 @@ void Indexer::RunAnalyzers() { return; } - /* initialize status */ - - { - boost::mutex::scoped_lock lock(this->progressMutex); - this->status = 6; - } - /* for each track... */ DBID trackId = 0; @@ -730,3 +677,32 @@ void Indexer::RunAnalyzers() { getNextTrack.BindInt(0, trackId); } } + + +bool Indexer::Restarted() { + boost::mutex::scoped_lock lock(this->stateMutex); + return this->restart; +} + +bool Indexer::Exited() { + boost::mutex::scoped_lock lock(this->stateMutex); + return this->exit; +} + +void Indexer::NotificationWait() { + boost::mutex::scoped_lock lock(this->stateMutex); + if (!this->exit) { + this->waitCondition.wait(lock); + } +} + +void Indexer::NotificationTimedWait(const boost::xtime &time) { + boost::mutex::scoped_lock lock(this->stateMutex); + if (!this->exit) { + this->waitCondition.timed_wait(lock, time); + } +} + +void Indexer::Notify() { + this->waitCondition.notify_all(); +} \ No newline at end of file diff --git a/src/core/library/Indexer.h b/src/core/library/Indexer.h index c9316d9d0..7e1b8caa8 100644 --- a/src/core/library/Indexer.h +++ b/src/core/library/Indexer.h @@ -34,7 +34,6 @@ #pragma once -#include #include #include #include @@ -44,6 +43,7 @@ #include #include +#include #include #include #include @@ -54,7 +54,7 @@ namespace musik { namespace core { - class Indexer : public IIndexer, public ThreadHelper, private boost::noncopyable { + class Indexer : public IIndexer, private boost::noncopyable { public: Indexer( const std::string& libraryPath, @@ -70,6 +70,11 @@ namespace musik { namespace core { private: void ThreadLoop(); + bool Exited(); + void NotificationWait(); + void NotificationTimedWait(const boost::xtime &oTime); + void Notify(); + bool Restarted(); void SyncDelete(); @@ -77,7 +82,6 @@ namespace musik { namespace core { void ProcessAddRemoveQueue(); void SyncOptimize(); void RunAnalyzers(); - void SynchronizeInternal(boost::asio::io_service* io); void SyncDirectory( @@ -95,13 +99,13 @@ namespace musik { namespace core { std::string libraryPath; std::string dbFilename; - int status; bool restart; + bool exit; + + boost::mutex stateMutex; + boost::condition waitCondition; boost::thread *thread; - boost::mutex progressMutex; - - size_t filesIndexed; std::atomic filesSaved; struct AddRemoveContext { diff --git a/src/core/support/ThreadHelper.cpp b/src/core/support/ThreadHelper.cpp deleted file mode 100644 index 528fb5bbd..000000000 --- a/src/core/support/ThreadHelper.cpp +++ /dev/null @@ -1,74 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// Copyright (c) 2007-2016 musikcube team -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the author nor the names of other contributors may -// be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -////////////////////////////////////////////////////////////////////////////// - -#include "pch.hpp" -#include - -using namespace musik::core; - -ThreadHelper::ThreadHelper() -: exit(false) { -} - -ThreadHelper::~ThreadHelper() { -} - -bool ThreadHelper::Exited() { - boost::mutex::scoped_lock lock(this->exitMutex); - return this->exit; -} - -void ThreadHelper::Exit() { - boost::mutex::scoped_lock lock(this->exitMutex); - this->exit = true; - this->notify.notify_all(); -} - -void ThreadHelper::NotificationWait(){ - boost::mutex::scoped_lock lock(this->exitMutex); - if (!this->exit) { - this->notify.wait(lock); - } -} - -void ThreadHelper::NotificationTimedWait(const boost::xtime &time) { - boost::mutex::scoped_lock lock(this->exitMutex); - if (!this->exit) { - this->notify.timed_wait(lock, time); - } -} - -void ThreadHelper::Notify(){ - this->notify.notify_all(); -} diff --git a/src/core/support/ThreadHelper.h b/src/core/support/ThreadHelper.h deleted file mode 100644 index 365480163..000000000 --- a/src/core/support/ThreadHelper.h +++ /dev/null @@ -1,64 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// Copyright (c) 2007-2016 musikcube team -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the author nor the names of other contributors may -// be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include - -#include -#include - - -namespace musik{ namespace core{ - class ThreadHelper{ - public: - ThreadHelper(void); - virtual ~ThreadHelper(void); - - virtual void Exit(); - boost::mutex exitMutex; - protected: - bool Exited(); - - void NotificationWait(); - void NotificationTimedWait(const boost::xtime &oTime); - void Notify(); - - bool exit; - boost::condition notify; - - }; -} } - -