Subject: [PATCH 8/8] read-cache: inform the daemon that the index has been updated

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Tue, 13 May 2014 18:15:37 +0700

The daemon would immediately load the new index in memory in
background. Next time Git needs to read the index again, everything is
ready.

Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
---
 cache.h      |  1 +
 read-cache.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/cache.h b/cache.h
index fb29c7e..3115b86 100644
--- a/cache.h
+++ b/cache.h
@@ -483,6 +483,7 @@ extern int is_index_unborn(struct index_state *);
 extern int read_index_unmerged(struct index_state *);
 #define COMMIT_LOCK		(1 << 0)
 #define CLOSE_LOCK		(1 << 1)
+#define REFRESH_DAEMON		(1 << 2)
 extern int write_locked_index(struct index_state *, struct lock_file *lock, unsigned flags);
 extern int discard_index(struct index_state *);
 extern int unmerged_index(const struct index_state *);
diff --git a/read-cache.c b/read-cache.c
index e98521f..d5c9247 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -16,6 +16,9 @@
 #include "varint.h"
 #include "split-index.h"
 #include "sigchain.h"
+#include "unix-socket.h"
+#include "pkt-line.h"
+#include "run-command.h"
 
 static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
 					       unsigned int options);
@@ -2030,6 +2033,32 @@ void set_alternate_index_output(const char *name)
 	alternate_index_output = name;
 }
 
+static void refresh_daemon(struct index_state *istate)
+{
+	int fd;
+	fd = unix_stream_connect(git_path("daemon/index"));
+	if (fd < 0) {
+		struct child_process cp;
+		const char *av[] = {"read-cache--daemon", "--detach", NULL };
+		memset(&cp, 0, sizeof(cp));
+		cp.argv = av;
+		cp.git_cmd = 1;
+		cp.no_stdin = 1;
+		if (run_command(&cp))
+			warning(_("failed to start read-cache--daemon: %s"),
+				strerror(errno));
+		return;
+	}
+	/*
+	 * packet_write() could die() but unless this is from
+	 * update_index_if_able(), we're about to exit anyway,
+	 * probably ok to die (for now). Blocking mode is another
+	 * problem to deal with later.
+	 */
+	packet_write(fd, "refresh");
+	close(fd);
+}
+
 static int commit_locked_index(struct lock_file *lk)
 {
 	if (alternate_index_output) {
@@ -2052,9 +2081,22 @@ static int do_write_locked_index(struct index_state *istate, struct lock_file *l
 		return ret;
 	assert((flags & (COMMIT_LOCK | CLOSE_LOCK)) !=
 	       (COMMIT_LOCK | CLOSE_LOCK));
-	if (flags & COMMIT_LOCK)
-		return commit_locked_index(lock);
-	else if (flags & CLOSE_LOCK)
+	if (flags & COMMIT_LOCK) {
+		int ret;
+		int len = strlen(lock->filename) - 5; /* .lock */
+		if (!use_read_cache_daemon || len < 6 ||
+		    /*
+		     * do not wake the daemon when we update a temporary
+		     * index. This is not a perfect test for this, but good
+		     * enough.
+		     */
+		    strncmp(lock->filename + len - 6, "/index", 6))
+			flags &= ~REFRESH_DAEMON;
+		ret = commit_locked_index(lock);
+		if (!ret && use_read_cache_daemon)
+			refresh_daemon(istate);
+		return ret;
+	} else if (flags & CLOSE_LOCK)
 		return close_lock_file(lock);
 	else
 		return ret;
@@ -2066,7 +2108,7 @@ static int write_split_index(struct index_state *istate,
 {
 	int ret;
 	prepare_to_write_split_index(istate);
-	ret = do_write_locked_index(istate, lock, flags);
+	ret = do_write_locked_index(istate, lock, flags | REFRESH_DAEMON);
 	finish_writing_split_index(istate);
 	return ret;
 }
@@ -2133,7 +2175,8 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
 	    (istate->cache_changed & ~EXTMASK)) {
 		if (si)
 			hashclr(si->base_sha1);
-		return do_write_locked_index(istate, lock, flags);
+		return do_write_locked_index(istate, lock,
+					     flags | REFRESH_DAEMON);
 	}
 
 	if (getenv("GIT_TEST_SPLIT_INDEX")) {
-- 
1.9.1.346.ga2b5940