I think it's safe to drop this patch now. It's mostly to prove that it
could work on Windows. But I don't think it's tested a lot (even I
only occasionally test it under wine).
On Thu, Mar 10, 2016 at 1:36 AM, David Turner wrote:
> From: Nguyễn Thái Ngọc Duy
>
> Windows supports shared memory, but the semantics is a bit different
> than POSIX shm. The most noticeable thing is there's no way to get the
> shared memory's size by the reader, and wrapping fstat to do that
> would be hell. So the shm size is added near the end, hidden away from
> shm users (storing it in headers would cause more problems with munmap,
> storing it as a separate shm is even worse).
>
> PostMessage is used instead of UNIX signals for
> notification. Lightweight (at least code-wise) on the client side.
>
> Signed-off-by: Nguyễn Thái Ngọc Duy
> ---
> config.mak.uname | 2 ++
> index-helper.c | 48
> read-cache.c | 13
> shm.c| 96
>
> 4 files changed, 159 insertions(+)
>
> diff --git a/config.mak.uname b/config.mak.uname
> index b5108e1..49320c7 100644
> --- a/config.mak.uname
> +++ b/config.mak.uname
> @@ -394,6 +394,7 @@ ifndef DEBUG
> else
> BASIC_CFLAGS += -Zi -MDd
> endif
> + PROGRAM_OBJS += index-helper.o
> X = .exe
> endif
> ifeq ($(uname_S),Interix)
> @@ -574,6 +575,7 @@ else
> NO_CURL = YesPlease
> endif
> endif
> + PROGRAM_OBJS += index-helper.o
> endif
> ifeq ($(uname_S),QNX)
> COMPAT_CFLAGS += -DSA_RESTART=0
> diff --git a/index-helper.c b/index-helper.c
> index 4dd9656..cf26da7 100644
> --- a/index-helper.c
> +++ b/index-helper.c
> @@ -155,6 +155,51 @@ static void loop(const char *pid_file, int
> idle_in_seconds)
> ; /* do nothing, all is handled by signal handlers already */
> }
>
> +#elif defined(GIT_WINDOWS_NATIVE)
> +
> +static void loop(const char *pid_file, int idle_in_seconds)
> +{
> + HWND hwnd;
> + UINT_PTR timer = 0;
> + MSG msg;
> + HINSTANCE hinst = GetModuleHandle(NULL);
> + WNDCLASS wc;
> +
> + /*
> +* Emulate UNIX signals by sending WM_USER+x to a
> +* window. Register window class and create a new window to
> +* catch these messages.
> +*/
> + memset(, 0, sizeof(wc));
> + wc.lpfnWndProc = DefWindowProc;
> + wc.hInstance = hinst;
> + wc.lpszClassName = "git-index-helper";
> + if (!RegisterClass())
> + die_errno(_("could not register new window class"));
> +
> + hwnd = CreateWindow("git-index-helper", pid_file,
> + 0, 0, 0, 1, 1, NULL, NULL, hinst, NULL);
> + if (!hwnd)
> + die_errno(_("could not register new window"));
> +
> + refresh(0);
> + while (1) {
> + timer = SetTimer(hwnd, timer, idle_in_seconds * 1000, NULL);
> + if (!timer)
> + die(_("no timer!"));
> + if (!GetMessage(, hwnd, 0, 0) || msg.message == WM_TIMER)
> + break;
> + switch (msg.message) {
> + case WM_USER:
> + refresh(0);
> + break;
> + default:
> + /* just reset the timer */
> + break;
> + }
> + }
> +}
> +
> #else
>
> static void loop(const char *pid_file, int idle_in_seconds)
> @@ -198,6 +243,9 @@ int main(int argc, char **argv)
> fd = hold_lock_file_for_update(,
>git_path("index-helper.pid"),
>LOCK_DIE_ON_ERROR);
> +#ifdef GIT_WINDOWS_NATIVE
> + strbuf_addstr(, "HWND");
> +#endif
> strbuf_addf(, "%" PRIuMAX, (uintmax_t) getpid());
> write_in_full(fd, sb.buf, sb.len);
> commit_lock_file();
> diff --git a/read-cache.c b/read-cache.c
> index 1a0ab0c..16fbdf6 100644
> --- a/read-cache.c
> +++ b/read-cache.c
> @@ -1546,6 +1546,18 @@ static void post_read_index_from(struct index_state
> *istate)
> tweak_untracked_cache(istate);
> }
>
> +#if defined(GIT_WINDOWS_NATIVE)
> +static void do_poke(struct strbuf *sb, int refresh_cache)
> +{
> + HWND hwnd;
> + if (!starts_with(sb->buf, "HWND"))
> + return;
> + hwnd = FindWindow("git-index-helper", sb->buf);
> + if (!hwnd)
> + return;
> + PostMessage(hwnd, refresh_cache ? WM_USER : WM_USER + 1, 0, 0);
> +}
> +#else
> static void do_poke(struct strbuf *sb, int refresh_cache)
> {
> char*start = sb->buf;
> @@ -1555,6 +1567,7 @@ static void do_poke(struct strbuf *sb, int
> refresh_cache)
> return;
> kill(pid, refresh_cache ? SIGHUP : SIGUSR1);
> }
> +#endif
>
> static void poke_daemon(struct index_state