Subject: Re: bug#19688: [patch] add support for emacs daemon on Windows

From: Eli Zaretskii <[email-masked]>
Date: Sun, 25 Jan 2015 22:34:10 +0200

> Date: Mon, 26 Jan 2015 04:18:34 +0900
> From: Mark Laws <[email-masked]>
> 
> Attached is a patch which should apply cleanly on top of master
> (a3689d3c661fe36df971c875760f8d500b5ae994 as of this email). It allows
> Emacs to run as a daemon on Windows. Without daemon mode, emacsclient
> -a "" does not work, which makes it impossible to pass elisp to Emacs
> via emacsclient unless Emacs is already running. In other words, this
> will now work correctly:
> 
> emacsclient -a "" -e "(ediff-merge-files-with-ancestor ...)"

Thanks.

Did you get your paperwork with the FSF clerk done?  I don't see your
assignment on file yet.

> +#define W32_EMACS_SERVER_GUID "{0B8E5DCB-D7CF-4423-A9F1-2F6927F0D318}"

Where did this GUID come from?

In any case, instead of adding a one-line header file, it is better to
put this on nt/inc/ms-w32.h, which is included by both emacsclient.c
and all src/*.c files via src/config.h.

> +#ifndef WINDOWSNT
>  /* Pipe used to send exit notification to the daemon parent at
>     startup.  */
>  int daemon_pipe[2];
> +#else
> +bool w32_is_daemon;
> +bool w32_daemon_is_initialized;
> +static HANDLE w32_daemon_event;
> +#endif

Why do we need anything beyond the event handle?  Can't it serve
double duty as a flag as well?  We could use INVALID_HANDLE_VALUE
and/or NULL as distinct values with specific meanings.

> +#ifndef WINDOWSNT
>    /* Make sure IS_DAEMON starts up as false.  */
>    daemon_pipe[1] = 0;
> +#endif

You should do a similar initialization on WINDOWSNT, to avoid using
the value that was initialized when Emacs was dumped.

> +#ifdef WINDOWSNT
> +  daemon_check_preconditions ();
> +
> +  w32_daemon_event = CreateEvent (NULL, TRUE, FALSE, W32_EMACS_SERVER_GUID);
> +  if (w32_daemon_event == NULL)
> +    error ("Couldn't create event for Windows daemon");
> +  if (GetLastError () == ERROR_ALREADY_EXISTS)
> +    /* Signal the waiting emacsclient process.  */
> +    SetEvent (w32_daemon_event);
> +  CloseHandle (w32_daemon_event);
> +  w32_daemon_is_initialized = true;
> +#else

Please move this code to a function in w32.c, and here just call that
function.

Also, the call to daemon_check_preconditions should be outside of the
#ifdef, as it is used on all platforms.