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: 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;
|
||||
|
@ -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.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue