db/update: cancel the update on shutdown
This commit is contained in:
parent
3be36643a1
commit
681e012fb5
1
NEWS
1
NEWS
|
@ -9,6 +9,7 @@ ver 0.19 (not yet released)
|
||||||
- proxy: forward "idle" events
|
- proxy: forward "idle" events
|
||||||
- proxy: copy "Last-Modified" from remote directories
|
- proxy: copy "Last-Modified" from remote directories
|
||||||
- upnp: new plugin
|
- upnp: new plugin
|
||||||
|
- cancel the update on shutdown
|
||||||
* storage
|
* storage
|
||||||
- music_directory can point to a remote file server
|
- music_directory can point to a remote file server
|
||||||
- nfs: new plugin
|
- nfs: new plugin
|
||||||
|
|
|
@ -596,6 +596,9 @@ int mpd_main(int argc, char *argv[])
|
||||||
|
|
||||||
#if defined(ENABLE_DATABASE) && defined(ENABLE_INOTIFY)
|
#if defined(ENABLE_DATABASE) && defined(ENABLE_INOTIFY)
|
||||||
mpd_inotify_finish();
|
mpd_inotify_finish();
|
||||||
|
|
||||||
|
if (instance->update != nullptr)
|
||||||
|
instance->update->CancelAllAsync();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (state_file != nullptr) {
|
if (state_file != nullptr) {
|
||||||
|
|
|
@ -50,6 +50,10 @@ public:
|
||||||
bool Push(const char *path, bool discard, unsigned id);
|
bool Push(const char *path, bool discard, unsigned id);
|
||||||
|
|
||||||
UpdateQueueItem Pop();
|
UpdateQueueItem Pop();
|
||||||
|
|
||||||
|
void Clear() {
|
||||||
|
update_queue = decltype(update_queue)();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#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
|
inline void
|
||||||
UpdateService::Task()
|
UpdateService::Task()
|
||||||
{
|
{
|
||||||
|
@ -94,6 +111,8 @@ UpdateService::StartThread(UpdateQueueItem &&i)
|
||||||
|
|
||||||
next = std::move(i);
|
next = std::move(i);
|
||||||
|
|
||||||
|
walk.Prepare();
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
if (!update_thread.Start(Task, this, error))
|
if (!update_thread.Start(Task, this, error))
|
||||||
FatalError(error);
|
FatalError(error);
|
||||||
|
|
|
@ -64,6 +64,8 @@ public:
|
||||||
Storage &_storage,
|
Storage &_storage,
|
||||||
DatabaseListener &_listener);
|
DatabaseListener &_listener);
|
||||||
|
|
||||||
|
~UpdateService();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a non-zero job id when we are currently updating
|
* Returns a non-zero job id when we are currently updating
|
||||||
* the database.
|
* the database.
|
||||||
|
@ -82,6 +84,12 @@ public:
|
||||||
gcc_nonnull_all
|
gcc_nonnull_all
|
||||||
unsigned Enqueue(const char *path, bool discard);
|
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:
|
private:
|
||||||
/* virtual methods from class DeferredMonitor */
|
/* virtual methods from class DeferredMonitor */
|
||||||
virtual void RunDeferred() override;
|
virtual void RunDeferred() override;
|
||||||
|
|
|
@ -358,7 +358,7 @@ UpdateWalk::UpdateDirectory(Directory &directory, const FileInfo &info)
|
||||||
PurgeDeletedFromDirectory(directory);
|
PurgeDeletedFromDirectory(directory);
|
||||||
|
|
||||||
const char *name_utf8;
|
const char *name_utf8;
|
||||||
while ((name_utf8 = reader->Read()) != nullptr) {
|
while (!cancel && (name_utf8 = reader->Read()) != nullptr) {
|
||||||
if (skip_path(name_utf8))
|
if (skip_path(name_utf8))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,13 @@ class UpdateWalk final {
|
||||||
bool walk_discard;
|
bool walk_discard;
|
||||||
bool modified;
|
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;
|
Storage &storage;
|
||||||
|
|
||||||
DatabaseEditor editor;
|
DatabaseEditor editor;
|
||||||
|
@ -56,6 +63,22 @@ public:
|
||||||
UpdateWalk(EventLoop &_loop, DatabaseListener &_listener,
|
UpdateWalk(EventLoop &_loop, DatabaseListener &_listener,
|
||||||
Storage &_storage);
|
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.
|
* Returns true if the database was modified.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue