From d44880dfa99197a8c1f4b65416470e6ffbe534f6 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Thu, 17 Oct 2013 21:34:36 +0200
Subject: [PATCH] UpdateGlue: handle update id management

Add UpdateQueueItem::id to keep track of the id in every item.
Replaces thhe hack in update_queue_push().
---
 src/UpdateGlue.cxx  | 30 ++++++++++++++++++++----------
 src/UpdateQueue.cxx | 10 +++++-----
 src/UpdateQueue.hxx | 14 ++++++++------
 3 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/src/UpdateGlue.cxx b/src/UpdateGlue.cxx
index 5eebe4e77..12ea126a9 100644
--- a/src/UpdateGlue.cxx
+++ b/src/UpdateGlue.cxx
@@ -57,7 +57,7 @@ static UpdateQueueItem next;
 unsigned
 isUpdatingDB(void)
 {
-	return (progress != UPDATE_PROGRESS_IDLE) ? update_task_id : 0;
+	return next.id;
 }
 
 static void
@@ -101,10 +101,17 @@ spawn_update_task(UpdateQueueItem &&i)
 	if (!update_thread.Start(update_task, nullptr, error))
 		FatalError(error);
 
-	if (++update_task_id > update_task_id_max)
-		update_task_id = 1;
 	FormatDebug(update_domain,
-		    "spawned thread for update job id %i", update_task_id);
+		    "spawned thread for update job id %i", next.id);
+}
+
+static unsigned
+generate_update_id()
+{
+	unsigned id = update_task_id + 1;
+	if (id > update_task_id_max)
+		id = 1;
+	return id;
 }
 
 unsigned
@@ -116,19 +123,20 @@ update_enqueue(const char *path, bool discard)
 		return 0;
 
 	if (progress != UPDATE_PROGRESS_IDLE) {
-		unsigned next_task_id =
-			update_queue_push(path, discard, update_task_id);
-		if (next_task_id == 0)
+		const unsigned id = generate_update_id();
+		if (!update_queue_push(path, discard, id))
 			return 0;
 
-		return next_task_id > update_task_id_max ?  1 : next_task_id;
+		update_task_id = id;
+		return id;
 	}
 
-	spawn_update_task(UpdateQueueItem(path, discard));
+	const unsigned id = update_task_id = generate_update_id();
+	spawn_update_task(UpdateQueueItem(path, discard, id));
 
 	idle_add(IDLE_UPDATE);
 
-	return update_task_id;
+	return id;
 }
 
 /**
@@ -137,8 +145,10 @@ update_enqueue(const char *path, bool discard)
 static void update_finished_event(void)
 {
 	assert(progress == UPDATE_PROGRESS_DONE);
+	assert(next.IsDefined());
 
 	update_thread.Join();
+	next = UpdateQueueItem();
 
 	idle_add(IDLE_UPDATE);
 
diff --git a/src/UpdateQueue.cxx b/src/UpdateQueue.cxx
index aa6074c7f..2a30e5d5f 100644
--- a/src/UpdateQueue.cxx
+++ b/src/UpdateQueue.cxx
@@ -27,14 +27,14 @@ static constexpr unsigned MAX_UPDATE_QUEUE_SIZE = 32;
 
 static std::queue<UpdateQueueItem, std::list<UpdateQueueItem>> update_queue;
 
-unsigned
-update_queue_push(const char *path, bool discard, unsigned base)
+bool
+update_queue_push(const char *path, bool discard, unsigned id)
 {
 	if (update_queue.size() >= MAX_UPDATE_QUEUE_SIZE)
-		return 0;
+		return false;
 
-	update_queue.emplace(path, discard);
-	return base + update_queue.size();
+	update_queue.emplace(path, discard, id);
+	return true;
 }
 
 UpdateQueueItem
diff --git a/src/UpdateQueue.hxx b/src/UpdateQueue.hxx
index 80c15f600..2769cc589 100644
--- a/src/UpdateQueue.hxx
+++ b/src/UpdateQueue.hxx
@@ -26,19 +26,21 @@
 
 struct UpdateQueueItem {
 	std::string path_utf8;
+	unsigned id;
 	bool discard;
 
-	UpdateQueueItem() = default;
-	UpdateQueueItem(const char *_path, bool _discard)
-		:path_utf8(_path), discard(_discard) {}
+	UpdateQueueItem():id(0) {}
+	UpdateQueueItem(const char *_path, bool _discard,
+			unsigned _id)
+		:path_utf8(_path), id(_id), discard(_discard) {}
 
 	bool IsDefined() const {
-		return !path_utf8.empty();
+		return id != 0;
 	}
 };
 
-unsigned
-update_queue_push(const char *path, bool discard, unsigned base);
+bool
+update_queue_push(const char *path, bool discard, unsigned id);
 
 UpdateQueueItem
 update_queue_shift();