On Fri, 30 Mar 2018 21:34:02 -0400, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison <matt_harbi...@yahoo.com>
> # Date 1522210269 14400
> #      Wed Mar 28 00:11:09 2018 -0400
> # Node ID 74bbfa1b88c69471713bcaa0c8124df4ce93783c
> # Parent  b9dd8403d8ff4b36847ce405c0db127ca64491a1
> server: add an error feedback mechanism for when the daemon fails to launch

Queued, thanks.

> +    # When daemonized on Windows, redirect stdout/stderr to the lockfile 
> (which
> +    # gets cleaned up after the child is up and running), so that the parent 
> can
> +    # read and print the error if this child dies early.  See 594dd384803c.  
> On
> +    # other platforms, the child can write to the parent's stdio directly, 
> until
> +    # it is redirected prior to runfn().
> +    if pycompat.iswindows and opts['daemon_postexec']:
> +        for inst in opts['daemon_postexec']:
> +            if inst.startswith('unlink:'):
> +                lockpath = inst[7:]
> +                if os.path.exists(lockpath):
> +                    procutil.stdout.flush()
> +                    procutil.stderr.flush()
> +
> +                    fd = os.open(lockpath,
> +                                 os.O_WRONLY | os.O_APPEND | os.O_BINARY)
> +                    try:
> +                        os.dup2(fd, 1)
> +                        os.dup2(fd, 2)

Nit: procutil.stdout/stderr.fileno() will look slightly nicer.

>              if pid < 0:
> +                # If the daemonized process managed to write out an error 
> msg,
> +                # report it.
> +                if pycompat.iswindows and os.path.exists(lockpath):
> +                    with open(lockpath) as log:

Nit: 'rb'

> +
> +        lockpath = None
>          for inst in opts['daemon_postexec']:
>              if inst.startswith('unlink:'):
>                  lockpath = inst[7:]
> -                os.unlink(lockpath)
>              elif inst.startswith('chdir:'):
>                  os.chdir(inst[6:])
>              elif inst != 'none':
> @@ -107,6 +135,11 @@ def runservice(opts, parentfn=None, init
>          if logfile and logfilefd not in (0, 1, 2):
>              os.close(logfilefd)
>  
> +        # Only unlink after redirecting stdout/stderr, so Windows doesn't
> +        # complain about a sharing violation.
> +        if lockpath:
> +            os.unlink(lockpath)

Perhaps we should build a dict of 'daemon_postexec' instructions instead of
parsing them twice. This "lockpath" change makes them effectively unordered.
_______________________________________________
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Reply via email to