#include "cache.h"
#include "config.h"
#include "fsmonitor.h"
#include "fsm-listen.h"
#include "fsmonitor--daemon.h"
#include "gettext.h"
#include "trace2.h"

/*
 * The documentation of ReadDirectoryChangesW() states that the maximum
 * buffer size is 64K when the monitored directory is remote.
 *
 * Larger buffers may be used when the monitored directory is local and
 * will help us receive events faster from the kernel and avoid dropped
 * events.
 *
 * So we try to use a very large buffer and silently fallback to 64K if
 * we get an error.
 */
#define MAX_RDCW_BUF_FALLBACK (65536)
#define MAX_RDCW_BUF          (65536 * 8)

struct one_watch
{
	char buffer[MAX_RDCW_BUF];
	DWORD buf_len;
	DWORD count;

	struct strbuf path;
	wchar_t wpath_longname[MAX_PATH + 1];
	DWORD wpath_longname_len;

	HANDLE hDir;
	HANDLE hEvent;
	OVERLAPPED overlapped;

	/*
	 * Is there an active ReadDirectoryChangesW() call pending.  If so, we
	 * need to later call GetOverlappedResult() and possibly CancelIoEx().
	 */
	BOOL is_active;

	/*
	 * Are shortnames enabled on the containing drive?  This is
	 * always true for "C:/" drives and usually never true for
	 * other drives.
	 *
	 * We only set this for the worktree because we only need to
	 * convert shortname paths to longname paths for items we send
	 * to clients.  (We don't care about shortname expansion for
	 * paths inside a GITDIR because we never send them to
	 * clients.)
	 */
	BOOL has_shortnames;
	BOOL has_tilde;
	wchar_t dotgit_shortname[16]; /* for 8.3 name */
};

struct fsm_listen_data
{
	struct one_watch *watch_worktree;
	struct one_watch *watch_gitdir;

	HANDLE hEventShutdown;

	HANDLE hListener[3]; /* we don't own these handles */
#define LISTENER_SHUTDOWN 0
#define LISTENER_HAVE_DATA_WORKTREE 1
#define LISTENER_HAVE_DATA_GITDIR 2
	int nr_listener_handles;
};

/*
 * Convert the WCHAR path from the event into UTF8 and normalize it.
 *
 * `wpath_len` is in WCHARS not bytes.
 */
static int normalize_path_in_utf8(wchar_t *wpath, DWORD wpath_len,
				  struct strbuf *normalized_path)
{
	int reserve;
	int len = 0;

	strbuf_reset(normalized_path);
	if (!wpath_len)
		goto normalize;

	/*
	 * Pre-reserve enough space in the UTF8 buffer for
	 * each Unicode WCHAR character to be mapped into a
	 * sequence of 2 UTF8 characters.  That should let us
	 * avoid ERROR_INSUFFICIENT_BUFFER 99.9+% of the time.
	 */
	reserve = 2 * wpath_len + 1;
	strbuf_grow(normalized_path, reserve);

	for (;;) {
		len = WideCharToMultiByte(CP_UTF8, 0,
					  wpath, wpath_len,
					  normalized_path->buf,
					  strbuf_avail(normalized_path) - 1,
					  NULL, NULL);
		if (len > 0)
			goto normalize;
		if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
			error(_("[GLE %ld] could not convert path to UTF-8: '%.*ls'"),
			      GetLastError(), (int)wpath_len, wpath);
			return -1;
		}

		strbuf_grow(normalized_path,
			    strbuf_avail(normalized_path) + reserve);
	}

normalize:
	strbuf_setlen(normalized_path, len);
	return strbuf_normalize_path(normalized_path);
}

/*
 * See if the worktree root directory has shortnames enabled.
 * This will help us decide if we need to do an expensive shortname
 * to longname conversion on every notification event.
 *
 * We do not want to create a file to test this, so we assume that the
 * root directory contains a ".git" file or directory.  (Our caller
 * only calls us for the worktree root, so this should be fine.)
 *
 * Remember the spelling of the shortname for ".git" if it exists.
 */
static void check_for_shortnames(struct one_watch *watch)
{
	wchar_t buf_in[MAX_PATH + 1];
	wchar_t buf_out[MAX_PATH + 1];
	wchar_t *last;
	wchar_t *p;

	/* build L"<wt-root-path>/.git" */
	swprintf(buf_in, ARRAY_SIZE(buf_in) - 1, L"%ls.git",
		 watch->wpath_longname);

	if (!GetShortPathNameW(buf_in, buf_out, ARRAY_SIZE(buf_out)))
		return;

	/*
	 * Get the final filename component of the shortpath.
	 * We know that the path does not have a final slash.
	 */
	for (last = p = buf_out; *p; p++)
		if (*p == L'/' || *p == '\\')
			last = p + 1;

	if (!wcscmp(last, L".git"))
		return;

	watch->has_shortnames = 1;
	wcsncpy(watch->dotgit_shortname, last,
		ARRAY_SIZE(watch->dotgit_shortname));

	/*
	 * The shortname for ".git" is usually of the form "GIT~1", so
	 * we should be able to avoid shortname to longname mapping on
	 * every notification event if the source string does not
	 * contain a "~".
	 *
	 * However, the documentation for GetLongPathNameW() says
	 * that there are filesystems that don't follow that pattern
	 * and warns against this optimization.
	 *
	 * Lets test this.
	 */
	if (wcschr(watch->dotgit_shortname, L'~'))
		watch->has_tilde = 1;
}

enum get_relative_result {
	GRR_NO_CONVERSION_NEEDED,
	GRR_HAVE_CONVERSION,
	GRR_SHUTDOWN,
};

/*
 * Info notification paths are relative to the root of the watch.
 * If our CWD is still at the root, then we can use relative paths
 * to convert from shortnames to longnames.  If our process has a
 * different CWD, then we need to construct an absolute path, do
 * the conversion, and then return the root-relative portion.
 *
 * We use the longname form of the root as our basis and assume that
 * it already has a trailing slash.
 *
 * `wpath_len` is in WCHARS not bytes.
 */
static enum get_relative_result get_relative_longname(
	struct one_watch *watch,
	const wchar_t *wpath, DWORD wpath_len,
	wchar_t *wpath_longname, size_t bufsize_wpath_longname)
{
	wchar_t buf_in[2 * MAX_PATH + 1];
	wchar_t buf_out[MAX_PATH + 1];
	DWORD root_len;
	DWORD out_len;

	/*
	 * Build L"<wt-root-path>/<event-rel-path>"
	 * Note that the <event-rel-path> might not be null terminated
	 * so we avoid swprintf() constructions.
	 */
	root_len = watch->wpath_longname_len;
	if (root_len + wpath_len >= ARRAY_SIZE(buf_in)) {
		/*
		 * This should not happen.  We cannot append the observed
		 * relative path onto the end of the worktree root path
		 * without overflowing the buffer.  Just give up.
		 */
		return GRR_SHUTDOWN;
	}
	wcsncpy(buf_in, watch->wpath_longname, root_len);
	wcsncpy(buf_in + root_len, wpath, wpath_len);
	buf_in[root_len + wpath_len] = 0;

	/*
	 * We don't actually know if the source pathname is a
	 * shortname or a longname.  This Windows routine allows
	 * either to be given as input.
	 */
	out_len = GetLongPathNameW(buf_in, buf_out, ARRAY_SIZE(buf_out));
	if (!out_len) {
		/*
		 * The shortname to longname conversion can fail for
		 * various reasons, for example if the file has been
		 * deleted.  (That is, if we just received a
		 * delete-file notification event and the file is
		 * already gone, we can't ask the file system to
		 * lookup the longname for it.  Likewise, for moves
		 * and renames where we are given the old name.)
		 *
		 * Since deleting or moving a file or directory by its
		 * shortname is rather obscure, I'm going ignore the
		 * failure and ask the caller to report the original
		 * relative path.  This seems kinder than failing here
		 * and forcing a resync.  Besides, forcing a resync on
		 * every file/directory delete would effectively
		 * cripple monitoring.
		 *
		 * We might revisit this in the future.
		 */
		return GRR_NO_CONVERSION_NEEDED;
	}

	if (!wcscmp(buf_in, buf_out)) {
		/*
		 * The path does not have a shortname alias.
		 */
		return GRR_NO_CONVERSION_NEEDED;
	}

	if (wcsncmp(buf_in, buf_out, root_len)) {
		/*
		 * The spelling of the root directory portion of the computed
		 * longname has changed.  This should not happen.  Basically,
		 * it means that we don't know where (without recomputing the
		 * longname of just the root directory) to split out the
		 * relative path.  Since this should not happen, I'm just
		 * going to let this fail and force a shutdown (because all
		 * subsequent events are probably going to see the same
		 * mismatch).
		 */
		return GRR_SHUTDOWN;
	}

	if (out_len - root_len >= bufsize_wpath_longname) {
		/*
		 * This should not happen.  We cannot copy the root-relative
		 * portion of the path into the provided buffer without an
		 * overrun.  Just give up.
		 */
		return GRR_SHUTDOWN;
	}

	/* Return the worktree root-relative portion of the longname. */

	wcscpy(wpath_longname, buf_out + root_len);
	return GRR_HAVE_CONVERSION;
}

void fsm_listen__stop_async(struct fsmonitor_daemon_state *state)
{
	SetEvent(state->listen_data->hListener[LISTENER_SHUTDOWN]);
}

static struct one_watch *create_watch(struct fsmonitor_daemon_state *state,
				      const char *path)
{
	struct one_watch *watch = NULL;
	DWORD desired_access = FILE_LIST_DIRECTORY;
	DWORD share_mode =
		FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE;
	HANDLE hDir;
	DWORD len_longname;
	wchar_t wpath[MAX_PATH + 1];
	wchar_t wpath_longname[MAX_PATH + 1];

	if (xutftowcs_path(wpath, path) < 0) {
		error(_("could not convert to wide characters: '%s'"), path);
		return NULL;
	}

	hDir = CreateFileW(wpath,
			   desired_access, share_mode, NULL, OPEN_EXISTING,
			   FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
			   NULL);
	if (hDir == INVALID_HANDLE_VALUE) {
		error(_("[GLE %ld] could not watch '%s'"),
		      GetLastError(), path);
		return NULL;
	}

	len_longname = GetLongPathNameW(wpath, wpath_longname,
					ARRAY_SIZE(wpath_longname));
	if (!len_longname) {
		error(_("[GLE %ld] could not get longname of '%s'"),
		      GetLastError(), path);
		CloseHandle(hDir);
		return NULL;
	}

	if (wpath_longname[len_longname - 1] != L'/' &&
	    wpath_longname[len_longname - 1] != L'\\') {
		wpath_longname[len_longname++] = L'/';
		wpath_longname[len_longname] = 0;
	}

	CALLOC_ARRAY(watch, 1);

	watch->buf_len = sizeof(watch->buffer); /* assume full MAX_RDCW_BUF */

	strbuf_init(&watch->path, 0);
	strbuf_addstr(&watch->path, path);

	wcscpy(watch->wpath_longname, wpath_longname);
	watch->wpath_longname_len = len_longname;

	watch->hDir = hDir;
	watch->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	return watch;
}

static void destroy_watch(struct one_watch *watch)
{
	if (!watch)
		return;

	strbuf_release(&watch->path);
	if (watch->hDir != INVALID_HANDLE_VALUE)
		CloseHandle(watch->hDir);
	if (watch->hEvent != INVALID_HANDLE_VALUE)
		CloseHandle(watch->hEvent);

	free(watch);
}

static int start_rdcw_watch(struct fsm_listen_data *data,
			    struct one_watch *watch)
{
	DWORD dwNotifyFilter =
		FILE_NOTIFY_CHANGE_FILE_NAME |
		FILE_NOTIFY_CHANGE_DIR_NAME |
		FILE_NOTIFY_CHANGE_ATTRIBUTES |
		FILE_NOTIFY_CHANGE_SIZE |
		FILE_NOTIFY_CHANGE_LAST_WRITE |
		FILE_NOTIFY_CHANGE_CREATION;

	ResetEvent(watch->hEvent);

	memset(&watch->overlapped, 0, sizeof(watch->overlapped));
	watch->overlapped.hEvent = watch->hEvent;

	/*
	 * Queue an async call using Overlapped IO.  This returns immediately.
	 * Our event handle will be signalled when the real result is available.
	 *
	 * The return value here just means that we successfully queued it.
	 * We won't know if the Read...() actually produces data until later.
	 */
	watch->is_active = ReadDirectoryChangesW(
		watch->hDir, watch->buffer, watch->buf_len, TRUE,
		dwNotifyFilter, &watch->count, &watch->overlapped, NULL);

	if (watch->is_active)
		return 0;

	error(_("ReadDirectoryChangedW failed on '%s' [GLE %ld]"),
	      watch->path.buf, GetLastError());
	return -1;
}

static int recv_rdcw_watch(struct one_watch *watch)
{
	DWORD gle;

	watch->is_active = FALSE;

	/*
	 * The overlapped result is ready.  If the Read...() was successful
	 * we finally receive the actual result into our buffer.
	 */
	if (GetOverlappedResult(watch->hDir, &watch->overlapped, &watch->count,
				TRUE))
		return 0;

	gle = GetLastError();
	if (gle == ERROR_INVALID_PARAMETER &&
	    /*
	     * The kernel throws an invalid parameter error when our
	     * buffer is too big and we are pointed at a remote
	     * directory (and possibly for other reasons).  Quietly
	     * set it down and try again.
	     *
	     * See note about MAX_RDCW_BUF at the top.
	     */
	    watch->buf_len > MAX_RDCW_BUF_FALLBACK) {
		watch->buf_len = MAX_RDCW_BUF_FALLBACK;
		return -2;
	}

	/*
	 * GetOverlappedResult() fails if the watched directory is
	 * deleted while we were waiting for an overlapped IO to
	 * complete.  The documentation did not list specific errors,
	 * but I observed ERROR_ACCESS_DENIED (0x05) errors during
	 * testing.
	 *
	 * Note that we only get notificaiton events for events
	 * *within* the directory, not *on* the directory itself.
	 * (These might be properies of the parent directory, for
	 * example).
	 *
	 * NEEDSWORK: We might try to check for the deleted directory
	 * case and return a better error message, but I'm not sure it
	 * is worth it.
	 *
	 * Shutdown if we get any error.
	 */

	error(_("GetOverlappedResult failed on '%s' [GLE %ld]"),
	      watch->path.buf, gle);
	return -1;
}

static void cancel_rdcw_watch(struct one_watch *watch)
{
	DWORD count;

	if (!watch || !watch->is_active)
		return;

	/*
	 * The calls to ReadDirectoryChangesW() and GetOverlappedResult()
	 * form a "pair" (my term) where we queue an IO and promise to
	 * hang around and wait for the kernel to give us the result.
	 *
	 * If for some reason after we queue the IO, we have to quit
	 * or otherwise not stick around for the second half, we must
	 * tell the kernel to abort the IO.  This prevents the kernel
	 * from writing to our buffer and/or signalling our event
	 * after we free them.
	 *
	 * (Ask me how much fun it was to track that one down).
	 */
	CancelIoEx(watch->hDir, &watch->overlapped);
	GetOverlappedResult(watch->hDir, &watch->overlapped, &count, TRUE);
	watch->is_active = FALSE;
}

/*
 * Process a single relative pathname event.
 * Return 1 if we should shutdown.
 */
static int process_1_worktree_event(
	struct string_list *cookie_list,
	struct fsmonitor_batch **batch,
	const struct strbuf *path,
	enum fsmonitor_path_type t,
	DWORD info_action)
{
	const char *slash;

	switch (t) {
	case IS_INSIDE_DOT_GIT_WITH_COOKIE_PREFIX:
		/* special case cookie files within .git */

		/* Use just the filename of the cookie file. */
		slash = find_last_dir_sep(path->buf);
		string_list_append(cookie_list,
				   slash ? slash + 1 : path->buf);
		break;

	case IS_INSIDE_DOT_GIT:
		/* ignore everything inside of "<worktree>/.git/" */
		break;

	case IS_DOT_GIT:
		/* "<worktree>/.git" was deleted (or renamed away) */
		if ((info_action == FILE_ACTION_REMOVED) ||
		    (info_action == FILE_ACTION_RENAMED_OLD_NAME)) {
			trace2_data_string("fsmonitor", NULL,
					   "fsm-listen/dotgit",
					   "removed");
			return 1;
		}
		break;

	case IS_WORKDIR_PATH:
		/* queue normal pathname */
		if (!*batch)
			*batch = fsmonitor_batch__new();
		fsmonitor_batch__add_path(*batch, path->buf);
		break;

	case IS_GITDIR:
	case IS_INSIDE_GITDIR:
	case IS_INSIDE_GITDIR_WITH_COOKIE_PREFIX:
	default:
		BUG("unexpected path classification '%d' for '%s'",
		    t, path->buf);
	}

	return 0;
}

/*
 * Process filesystem events that happen anywhere (recursively) under the
 * <worktree> root directory.  For a normal working directory, this includes
 * both version controlled files and the contents of the .git/ directory.
 *
 * If <worktree>/.git is a file, then we only see events for the file
 * itself.
 */
static int process_worktree_events(struct fsmonitor_daemon_state *state)
{
	struct fsm_listen_data *data = state->listen_data;
	struct one_watch *watch = data->watch_worktree;
	struct strbuf path = STRBUF_INIT;
	struct string_list cookie_list = STRING_LIST_INIT_DUP;
	struct fsmonitor_batch *batch = NULL;
	const char *p = watch->buffer;
	wchar_t wpath_longname[MAX_PATH + 1];

	/*
	 * If the kernel gets more events than will fit in the kernel
	 * buffer associated with our RDCW handle, it drops them and
	 * returns a count of zero.
	 *
	 * Yes, the call returns WITHOUT error and with length zero.
	 * This is the documented behavior.  (My testing has confirmed
	 * that it also sets the last error to ERROR_NOTIFY_ENUM_DIR,
	 * but we do not rely on that since the function did not
	 * return an error and it is not documented.)
	 *
	 * (The "overflow" case is not ambiguous with the "no data" case
	 * because we did an INFINITE wait.)
	 *
	 * This means we have a gap in coverage.  Tell the daemon layer
	 * to resync.
	 */
	if (!watch->count) {
		trace2_data_string("fsmonitor", NULL, "fsm-listen/kernel",
				   "overflow");
		fsmonitor_force_resync(state);
		return LISTENER_HAVE_DATA_WORKTREE;
	}

	/*
	 * On Windows, `info` contains an "array" of paths that are
	 * relative to the root of whichever directory handle received
	 * the event.
	 */
	for (;;) {
		FILE_NOTIFY_INFORMATION *info = (void *)p;
		wchar_t *wpath = info->FileName;
		DWORD wpath_len = info->FileNameLength / sizeof(WCHAR);
		enum fsmonitor_path_type t;
		enum get_relative_result grr;

		if (watch->has_shortnames) {
			if (!wcscmp(wpath, watch->dotgit_shortname)) {
				/*
				 * This event exactly matches the
				 * spelling of the shortname of
				 * ".git", so we can skip some steps.
				 *
				 * (This case is odd because the user
				 * can "rm -rf GIT~1" and we cannot
				 * use the filesystem to map it back
				 * to ".git".)
				 */
				strbuf_reset(&path);
				strbuf_addstr(&path, ".git");
				t = IS_DOT_GIT;
				goto process_it;
			}

			if (watch->has_tilde && !wcschr(wpath, L'~')) {
				/*
				 * Shortnames on this filesystem have tildes
				 * and the notification path does not have
				 * one, so we assume that it is a longname.
				 */
				goto normalize_it;
			}

			grr = get_relative_longname(watch, wpath, wpath_len,
						    wpath_longname,
						    ARRAY_SIZE(wpath_longname));
			switch (grr) {
			case GRR_NO_CONVERSION_NEEDED: /* use info buffer as is */
				break;
			case GRR_HAVE_CONVERSION:
				wpath = wpath_longname;
				wpath_len = wcslen(wpath);
				break;
			default:
			case GRR_SHUTDOWN:
				goto force_shutdown;
			}
		}

normalize_it:
		if (normalize_path_in_utf8(wpath, wpath_len, &path) == -1)
			goto skip_this_path;

		t = fsmonitor_classify_path_workdir_relative(path.buf);

process_it:
		if (process_1_worktree_event(&cookie_list, &batch, &path, t,
					     info->Action))
			goto force_shutdown;

skip_this_path:
		if (!info->NextEntryOffset)
			break;
		p += info->NextEntryOffset;
	}

	fsmonitor_publish(state, batch, &cookie_list);
	batch = NULL;
	string_list_clear(&cookie_list, 0);
	strbuf_release(&path);
	return LISTENER_HAVE_DATA_WORKTREE;

force_shutdown:
	fsmonitor_batch__free_list(batch);
	string_list_clear(&cookie_list, 0);
	strbuf_release(&path);
	return LISTENER_SHUTDOWN;
}

/*
 * Process filesystem events that happened anywhere (recursively) under the
 * external <gitdir> (such as non-primary worktrees or submodules).
 * We only care about cookie files that our client threads created here.
 *
 * Note that we DO NOT get filesystem events on the external <gitdir>
 * itself (it is not inside something that we are watching).  In particular,
 * we do not get an event if the external <gitdir> is deleted.
 *
 * Also, we do not care about shortnames within the external <gitdir>, since
 * we never send these paths to clients.
 */
static int process_gitdir_events(struct fsmonitor_daemon_state *state)
{
	struct fsm_listen_data *data = state->listen_data;
	struct one_watch *watch = data->watch_gitdir;
	struct strbuf path = STRBUF_INIT;
	struct string_list cookie_list = STRING_LIST_INIT_DUP;
	const char *p = watch->buffer;

	if (!watch->count) {
		trace2_data_string("fsmonitor", NULL, "fsm-listen/kernel",
				   "overflow");
		fsmonitor_force_resync(state);
		return LISTENER_HAVE_DATA_GITDIR;
	}

	for (;;) {
		FILE_NOTIFY_INFORMATION *info = (void *)p;
		const char *slash;
		enum fsmonitor_path_type t;

		if (normalize_path_in_utf8(
			    info->FileName,
			    info->FileNameLength / sizeof(WCHAR),
			    &path) == -1)
			goto skip_this_path;

		t = fsmonitor_classify_path_gitdir_relative(path.buf);

		switch (t) {
		case IS_INSIDE_GITDIR_WITH_COOKIE_PREFIX:
			/* special case cookie files within gitdir */

			/* Use just the filename of the cookie file. */
			slash = find_last_dir_sep(path.buf);
			string_list_append(&cookie_list,
					   slash ? slash + 1 : path.buf);
			break;

		case IS_INSIDE_GITDIR:
			goto skip_this_path;

		default:
			BUG("unexpected path classification '%d' for '%s'",
			    t, path.buf);
		}

skip_this_path:
		if (!info->NextEntryOffset)
			break;
		p += info->NextEntryOffset;
	}

	fsmonitor_publish(state, NULL, &cookie_list);
	string_list_clear(&cookie_list, 0);
	strbuf_release(&path);
	return LISTENER_HAVE_DATA_GITDIR;
}

void fsm_listen__loop(struct fsmonitor_daemon_state *state)
{
	struct fsm_listen_data *data = state->listen_data;
	DWORD dwWait;
	int result;

	state->listen_error_code = 0;

	if (start_rdcw_watch(data, data->watch_worktree) == -1)
		goto force_error_stop;

	if (data->watch_gitdir &&
	    start_rdcw_watch(data, data->watch_gitdir) == -1)
		goto force_error_stop;

	for (;;) {
		dwWait = WaitForMultipleObjects(data->nr_listener_handles,
						data->hListener,
						FALSE, INFINITE);

		if (dwWait == WAIT_OBJECT_0 + LISTENER_HAVE_DATA_WORKTREE) {
			result = recv_rdcw_watch(data->watch_worktree);
			if (result == -1) {
				/* hard error */
				goto force_error_stop;
			}
			if (result == -2) {
				/* retryable error */
				if (start_rdcw_watch(data, data->watch_worktree) == -1)
					goto force_error_stop;
				continue;
			}

			/* have data */
			if (process_worktree_events(state) == LISTENER_SHUTDOWN)
				goto force_shutdown;
			if (start_rdcw_watch(data, data->watch_worktree) == -1)
				goto force_error_stop;
			continue;
		}

		if (dwWait == WAIT_OBJECT_0 + LISTENER_HAVE_DATA_GITDIR) {
			result = recv_rdcw_watch(data->watch_gitdir);
			if (result == -1) {
				/* hard error */
				goto force_error_stop;
			}
			if (result == -2) {
				/* retryable error */
				if (start_rdcw_watch(data, data->watch_gitdir) == -1)
					goto force_error_stop;
				continue;
			}

			/* have data */
			if (process_gitdir_events(state) == LISTENER_SHUTDOWN)
				goto force_shutdown;
			if (start_rdcw_watch(data, data->watch_gitdir) == -1)
				goto force_error_stop;
			continue;
		}

		if (dwWait == WAIT_OBJECT_0 + LISTENER_SHUTDOWN)
			goto clean_shutdown;

		error(_("could not read directory changes [GLE %ld]"),
		      GetLastError());
		goto force_error_stop;
	}

force_error_stop:
	state->listen_error_code = -1;

force_shutdown:
	/*
	 * Tell the IPC thead pool to stop (which completes the await
	 * in the main thread (which will also signal this thread (if
	 * we are still alive))).
	 */
	ipc_server_stop_async(state->ipc_server_data);

clean_shutdown:
	cancel_rdcw_watch(data->watch_worktree);
	cancel_rdcw_watch(data->watch_gitdir);
}

int fsm_listen__ctor(struct fsmonitor_daemon_state *state)
{
	struct fsm_listen_data *data;

	CALLOC_ARRAY(data, 1);

	data->hEventShutdown = CreateEvent(NULL, TRUE, FALSE, NULL);

	data->watch_worktree = create_watch(state,
					    state->path_worktree_watch.buf);
	if (!data->watch_worktree)
		goto failed;

	check_for_shortnames(data->watch_worktree);

	if (state->nr_paths_watching > 1) {
		data->watch_gitdir = create_watch(state,
						  state->path_gitdir_watch.buf);
		if (!data->watch_gitdir)
			goto failed;
	}

	data->hListener[LISTENER_SHUTDOWN] = data->hEventShutdown;
	data->nr_listener_handles++;

	data->hListener[LISTENER_HAVE_DATA_WORKTREE] =
		data->watch_worktree->hEvent;
	data->nr_listener_handles++;

	if (data->watch_gitdir) {
		data->hListener[LISTENER_HAVE_DATA_GITDIR] =
			data->watch_gitdir->hEvent;
		data->nr_listener_handles++;
	}

	state->listen_data = data;
	return 0;

failed:
	CloseHandle(data->hEventShutdown);
	destroy_watch(data->watch_worktree);
	destroy_watch(data->watch_gitdir);

	return -1;
}

void fsm_listen__dtor(struct fsmonitor_daemon_state *state)
{
	struct fsm_listen_data *data;

	if (!state || !state->listen_data)
		return;

	data = state->listen_data;

	CloseHandle(data->hEventShutdown);
	destroy_watch(data->watch_worktree);
	destroy_watch(data->watch_gitdir);

	FREE_AND_NULL(state->listen_data);
}
