diff src/library/library.cc @ 409:8d06825d96d1

library: refresh in a separate thread this is fugly but it works
author Paper <paper@tflc.us>
date Thu, 02 Apr 2026 00:18:56 -0400
parents 650a9159a0e7
children eb554255ea5f
line wrap: on
line diff
--- a/src/library/library.cc	Wed Jan 21 11:35:32 2026 -0500
+++ b/src/library/library.cc	Thu Apr 02 00:18:56 2026 -0400
@@ -19,6 +19,9 @@
 	/* Nevermind, this causes an immediate segfault on Windows
 	UpdateWatchers();
 	*/
+	/* Also, this would be completely useless as the paths in
+	 * the config are not filled until after main() is
+	 * called. */
 }
 
 void Database::UpdateWatchers()
@@ -62,6 +65,9 @@
 	if (!GetPathAnimeAndEpisode(bname, &aid, &ep))
 		return;
 
+	/* Lock the items mutex */
+	const std::lock_guard<std::recursive_mutex> lock(items_mutex_);
+
 	switch (event) {
 	case Filesystem::IWatcher::Created:
 		items[aid][ep] = path;
@@ -91,6 +97,9 @@
 	// episodes are contained in them. whichever directory has more episodes
 	// wins, or the first found if there is an equal amount.
 
+	/* TODO use a shared lock instead */
+	const std::lock_guard<std::recursive_mutex> lock(items_mutex_);
+
 	for (const auto &[anime_id, episodes] : items) {
 		if (id != anime_id)
 			continue;
@@ -104,15 +113,25 @@
 	return std::nullopt;
 }
 
-/* TODO shove this into a separate thread; currently it blocks */
+void Database::RefreshThread()
+{
+	for (const auto &w : watchers_)
+		w.second->Process();
+}
+
+/* TODO the threading code for this could be better */
 void Database::Refresh(std::optional<int> find_id)
 {
+	/* Join the thread if it was already run */
+	if (refresh_thread_.joinable())
+		refresh_thread_.join();
+
+	/* This is terrible */
 	find_id_ = find_id;
 
 	UpdateWatchers();
 
-	for (const auto &w : watchers_)
-		w.second->Process();
+	refresh_thread_ = std::thread(&Database::RefreshThread, this);
 }
 
 void Database::Refresh()
@@ -125,6 +144,16 @@
 	Refresh(std::optional<int>(id));
 }
 
+std::optional<std::filesystem::path> Database::GetAnimeEpisodePath(int anime, int episode)
+{
+	const std::lock_guard<std::recursive_mutex> lock(items_mutex_);
+
+	if (items.find(anime) == items.end() || items[anime].find(episode) == items[anime].end())
+		return std::nullopt;
+
+	return items[anime][episode];
+}
+
 // TODO export to JSON on exit
 
 Database db;