public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: Bruno Haible <bruno@clisp.org>
To: cygwin@cygwin.com
Cc: gs-cygwin.com@gluelogic.com
Subject: Re: posix_spawn facility
Date: Thu, 20 Apr 2023 12:18:59 +0200	[thread overview]
Message-ID: <1853259.CQOukoFCf9@nimes> (raw)
In-Reply-To: <ZED5SOzW5QAkfxje@calimero.vinschen.de>

Corinna Vinschen wrote:
> Unfortunately you can't expect any noticable difference on Cygwin by
> using posix_spawn.  While Cygwin has a spawn() family of functions, we
> don't (and can't... yet) use them.
> 
> The problem is that we don't have a safe way to perform the spawn
> attributes and file actions which are supposed to be performed between
> the fork() and the exec() step when using the spawn() functions.  This
> would have to be implemented first.

So, you are saying that on Cygwin, spawnvpe() and friends are fast,
because child_info_spawn::worker ends up calling CreateProcessW rather
immediately? But posix_spawn is slow, because it goes another path,
through fork()?

If that's the case, it might help to look at how I created Gnulib's
posix_spawn for native Windows:

  1) Extend the spawnvpe function to a spawnvpech function. It takes
     additional arguments
       - const char *currdir
       - int currdirfd
       - HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle
     (The latter is because the first 3 file descriptors are passed
     specially on Windows.)

  2) Refactor the guts of spawnvpech, moving as much as possible into
     helper functions. In my case, spawnvpech shrunk to only 150 lines
     of code.

     The helper functions, in the native Windows case, were:
       - prepare_spawn
       - compose_command
       - compose_envblock
       - init_inheritable_handles, compose_handles_block,
         free_inheritable_handles
       - convert_CreateProcess_error
     See https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/windows-spawn.h .

     I would expect that similar helper functions can be created in
     Cygwin.

     The "inheritable handles" is a data structure that allows for the
     arbitrary reshuffling of file descriptors required by posix_spawn
     (the addopen, adddup2, addclose actions), i.e. which does the book-
     keeping which HANDLE must in the end be open in the parent and which
     must in the end be open in the child, and at which position. While
     at the same time optimizing the number of DuplicateHandle calls.
     Without this optimization, the code is simpler, but there were many
     redundant DuplicateHandle calls.
     This data structure is essential for posix_spawn[p] to be multithread-
     safe. posix_spawn[p] must not modify the file descriptors of the
     parent; instead it has to create the planned file descriptors for the
     child in memory.

     During this refactoring, it is essential to have a good test suite.
     Because when you make a mistake and leave a fd / HANDLE accidentally
     open (in the parent or in the child), applications that invoke a pipe
     start to hang.

  3) With these helper functions, write a new core for posix_spawn[p].
     In my case, it was less than 250 lines of code, which is not
     straightforward, but also not really hard either.
     See https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/spawni.c
     lines 610..852.

     At this step, you can use Gnulib's test suite for verifying that the new
     code works properly.

Hope this helps.

Bruno




  reply	other threads:[~2023-04-20 10:19 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-16 11:46 Bruno Haible
2023-04-17  9:18 ` Corinna Vinschen
2023-04-17 18:44   ` Bruno Haible
2023-04-18  9:25     ` Corinna Vinschen
2023-04-18 20:49       ` Eric Blake
2023-04-18 21:00         ` Corinna Vinschen
2023-04-18 22:10         ` Bruno Haible
2023-04-19  2:39           ` Eric Blake
2023-04-19  8:19             ` Corinna Vinschen
2023-04-19 11:56             ` Bruno Haible
2023-04-20  6:52               ` Csaba Raduly
2023-07-31 18:58         ` Eric Blake
2023-07-31 19:12           ` Corinna Vinschen
2023-04-19  8:24     ` Corinna Vinschen
2023-04-19 11:24       ` posix_spawn_file_actions_add[f]chdir_np Bruno Haible
2023-04-19 15:05         ` posix_spawn_file_actions_add[f]chdir_np Corinna Vinschen
2023-04-19 19:13           ` posix_spawn_file_actions_add[f]chdir_np Corinna Vinschen
2023-04-19 21:33             ` posix_spawn_file_actions_add[f]chdir_np Eliot Moss
2023-04-20 10:27             ` posix_spawn_file_actions_add[f]chdir_np Bruno Haible
2023-04-19 10:48     ` posix_spawn facility Bruno Haible
2023-04-20  7:14     ` gs-cygwin.com
2023-04-20  8:35       ` Corinna Vinschen
2023-04-20 10:18         ` Bruno Haible [this message]
2023-04-20 14:21           ` Corinna Vinschen
2023-04-20 14:40             ` Corinna Vinschen
2023-04-20 14:58               ` Bruno Haible
2023-04-20 15:40                 ` Corinna Vinschen
2023-04-20 18:46                   ` gs-cygwin.com
2023-04-20 18:40                 ` gs-cygwin.com
2023-04-20 19:31                   ` Bruno Haible
2023-04-20 20:00                     ` gs-cygwin.com
2023-05-10  9:15                       ` gs-cygwin.com
2023-04-20 18:04               ` gs-cygwin.com
2023-05-10  8:59       ` gs-cygwin.com

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1853259.CQOukoFCf9@nimes \
    --to=bruno@clisp.org \
    --cc=cygwin@cygwin.com \
    --cc=gs-cygwin.com@gluelogic.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).