Commit 681e012f authored by Max Kellermann's avatar Max Kellermann

db/update: cancel the update on shutdown

parent 3be36643
......@@ -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
......
......@@ -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) {
......
......@@ -50,6 +50,10 @@ public:
bool Push(const char *path, bool discard, unsigned id);
UpdateQueueItem Pop();
void Clear() {
update_queue = decltype(update_queue)();
}
};
#endif
......@@ -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);
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......@@ -57,6 +64,22 @@ public:
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.
*/
bool Walk(Directory &root, const char *path, bool discard);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment