db/update: cancel the update on shutdown

This commit is contained in:
Max Kellermann 2014-02-27 16:36:11 +01:00
parent 3be36643a1
commit 681e012fb5
7 changed files with 59 additions and 1 deletions

1
NEWS
View File

@ -9,6 +9,7 @@ ver 0.19 (not yet released)
- proxy: forward "idle" events
- proxy: copy "Last-Modified" from remote directories
- upnp: new plugin
- cancel the update on shutdown
* storage
- music_directory can point to a remote file server
- nfs: new plugin

View File

@ -596,6 +596,9 @@ int mpd_main(int argc, char *argv[])
#if defined(ENABLE_DATABASE) && defined(ENABLE_INOTIFY)
mpd_inotify_finish();
if (instance->update != nullptr)
instance->update->CancelAllAsync();
#endif
if (state_file != nullptr) {

View File

@ -50,6 +50,10 @@ public:
bool Push(const char *path, bool discard, unsigned id);
UpdateQueueItem Pop();
void Clear() {
update_queue = decltype(update_queue)();
}
};
#endif

View File

@ -47,6 +47,23 @@ UpdateService::UpdateService(EventLoop &_loop, SimpleDatabase &_db,
{
}
UpdateService::~UpdateService()
{
CancelAllAsync();
if (update_thread.IsDefined())
update_thread.Join();
}
void
UpdateService::CancelAllAsync()
{
assert(GetEventLoop().IsInsideOrNull());
queue.Clear();
walk.Cancel();
}
inline void
UpdateService::Task()
{
@ -94,6 +111,8 @@ UpdateService::StartThread(UpdateQueueItem &&i)
next = std::move(i);
walk.Prepare();
Error error;
if (!update_thread.Start(Task, this, error))
FatalError(error);

View File

@ -64,6 +64,8 @@ public:
Storage &_storage,
DatabaseListener &_listener);
~UpdateService();
/**
* Returns a non-zero job id when we are currently updating
* the database.
@ -82,6 +84,12 @@ public:
gcc_nonnull_all
unsigned Enqueue(const char *path, bool discard);
/**
* Clear the queue and cancel the current update. Does not
* wait for the thread to exit.
*/
void CancelAllAsync();
private:
/* virtual methods from class DeferredMonitor */
virtual void RunDeferred() override;

View File

@ -358,7 +358,7 @@ UpdateWalk::UpdateDirectory(Directory &directory, const FileInfo &info)
PurgeDeletedFromDirectory(directory);
const char *name_utf8;
while ((name_utf8 = reader->Read()) != nullptr) {
while (!cancel && (name_utf8 = reader->Read()) != nullptr) {
if (skip_path(name_utf8))
continue;

View File

@ -48,6 +48,13 @@ class UpdateWalk final {
bool walk_discard;
bool modified;
/**
* Set to true by the main thread when the update thread shall
* cancel as quickly as possible. Access to this flag is
* unprotected.
*/
volatile bool cancel;
Storage &storage;
DatabaseEditor editor;
@ -56,6 +63,22 @@ public:
UpdateWalk(EventLoop &_loop, DatabaseListener &_listener,
Storage &_storage);
/**
* Cancel the current update and quit the Walk() method as
* soon as possible.
*/
void Cancel() {
cancel = true;
}
/**
* Call from the main thread before starting the update
* thread.
*/
void Prepare() {
cancel = false;
}
/**
* Returns true if the database was modified.
*/