public inbox for cygwin-cvs@sourceware.org
help / color / mirror / Atom feed
From: Corinna Vinschen <corinna@sourceware.org>
To: cygwin-cvs@sourceware.org
Subject: [newlib-cygwin/main] Cygwin: redefine how to recognize forkee state
Date: Mon, 29 Jan 2024 12:44:05 +0000 (GMT)	[thread overview]
Message-ID: <20240129124405.ED2DA3858407@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=1f68e88f0dfdac54d71ed0fd2c3f9a9f65636e06

commit 1f68e88f0dfdac54d71ed0fd2c3f9a9f65636e06
Author:     Corinna Vinschen <corinna@vinschen.de>
AuthorDate: Mon Jan 29 13:33:05 2024 +0100
Commit:     Corinna Vinschen <corinna@vinschen.de>
CommitDate: Mon Jan 29 13:33:05 2024 +0100

    Cygwin: redefine how to recognize forkee state
    
    So far the global variable in_forkee only indicated if the
    process is the child process during fork(2) itself.
    
    However, we need an indicator accessible from plain C code
    in newlib, allowing to check for a process being a forked
    process all the time, after fork(2) succeeded.
    
    Redefine bool in_forkee to int __in_forkee to allow exposing
    it to newlib.  Redefine how it indicates fork state (not
    forked, forking, forked).
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/dcrt0.cc    | 18 ++++++++++--------
 winsup/cygwin/dll_init.cc |  8 ++++----
 winsup/cygwin/fork.cc     |  2 +-
 winsup/cygwin/globals.cc  | 13 +++++++++++--
 winsup/cygwin/mm/heap.cc  |  2 +-
 5 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 17c9be731a54..fc1eec76a4a5 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -64,7 +64,7 @@ do_global_dtors ()
 static void
 do_global_ctors (void (**in_pfunc)(), int force)
 {
-  if (!force && in_forkee)
+  if (!force && __in_forkee == FORKING)
     return;		// inherit constructed stuff from parent pid
 
   /* Run ctors backwards, so skip the first entry and find how many
@@ -532,7 +532,7 @@ get_cygwin_startup_info ()
       switch (res->type)
 	{
 	  case _CH_FORK:
-	    in_forkee = true;
+	    __in_forkee = FORKING;
 	    should_be_cb = sizeof (child_info_fork);
 	    fallthrough;
 	  case _CH_SPAWN:
@@ -803,7 +803,7 @@ dll_crt0_1 (void *)
 
   _my_tls.incyg++;
   /* Inherit "parent" exec'ed process sigmask */
-  if (spawn_info && !in_forkee)
+  if (spawn_info && __in_forkee != FORKING)
     _my_tls.sigmask = spawn_info->sigmask;
 
   if (dynamically_loaded)
@@ -840,7 +840,7 @@ dll_crt0_1 (void *)
 
   /* Initialize pthread mainthread when not forked and it is safe to call new,
      otherwise it is reinitalized in fixup_after_fork */
-  if (!in_forkee)
+  if (__in_forkee != FORKING)
     {
       pthread::init_mainthread ();
       _pei386_runtime_relocator (user_data);
@@ -851,7 +851,7 @@ dll_crt0_1 (void *)
 #endif
 
   cygbench ("pre-forkee");
-  if (in_forkee)
+  if (__in_forkee == FORKING)
     {
       /* Make sure to restore the TEB's stack info.  If guardsize is -1 the
 	 stack has been provided by the application and must not be deallocated
@@ -1018,7 +1018,7 @@ _dll_crt0 ()
      under our own control and avoids collision with the OS. */
   if (!dynamically_loaded)
     {
-      if (!in_forkee)
+      if (__in_forkee != FORKING)
 	{
 	  /* Must be static since it's referenced after the stack and frame
 	     pointer registers have been changed. */
@@ -1056,7 +1056,7 @@ void
 dll_crt0 (per_process *uptr)
 {
   /* Set the local copy of the pointer into the user space. */
-  if (!in_forkee && uptr && uptr != user_data)
+  if (__in_forkee != FORKING && uptr && uptr != user_data)
     {
       memcpy (user_data, uptr, per_process_overwrite);
       *(user_data->impure_ptr_ptr) = _GLOBAL_REENT;
@@ -1246,7 +1246,9 @@ extern "C" void
 vapi_fatal (const char *fmt, va_list ap)
 {
   char buf[4096];
-  int n = __small_sprintf (buf, "%P: *** fatal error %s- ", in_forkee ? "in forked process " : "");
+  int n = __small_sprintf (buf, "%P: *** fatal error %s- ",
+				(__in_forkee == FORKING)
+				? "in forked process " : "");
   __small_vsprintf (buf + n, fmt, ap);
   va_end (ap);
   strace.prntf (_STRACE_SYSTEM, NULL, "%s", buf);
diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc
index b486eaa1f8f5..1a047511f8cc 100644
--- a/winsup/cygwin/dll_init.cc
+++ b/winsup/cygwin/dll_init.cc
@@ -39,7 +39,7 @@ static bool dll_global_dtors_recorded;
 
 /* We need the in_load_after_fork flag so dll_dllcrt0_1 can decide at fork
    time if this is a linked DLL or a dynamically loaded DLL.  In either case,
-   both, cygwin_finished_initializing and in_forkee are true, so they are not
+   both, cygwin_finished_initializing and __in_forkee are true, so they are not
    sufficient to discern the situation. */
 static bool NO_COPY in_load_after_fork;
 
@@ -161,7 +161,7 @@ dll_global_dtors ()
   /* Don't attempt to call destructors if we're still in fork processing
      since that likely means fork is failing and everything will not have been
      set up.  */
-  if (in_forkee)
+  if (__in_forkee == FORKING)
     return;
   int recorded = dll_global_dtors_recorded;
   dll_global_dtors_recorded = false;
@@ -205,7 +205,7 @@ dll::init ()
   int ret = 1;
 
   /* Don't run constructors or the "main" if we've forked. */
-  if (!in_forkee)
+  if (__in_forkee != FORKING)
     {
       /* global contructors */
       p.run_ctors ();
@@ -564,7 +564,7 @@ dll_list::detach (void *retaddr)
   /* Don't attempt to call destructors if we're still in fork processing
      since that likely means fork is failing and everything will not have been
      set up.  */
-  if (!myself || in_forkee)
+  if (!myself || __in_forkee == FORKING)
     return;
   guard (true);
   if ((d = find (retaddr)))
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index e553c015a364..0742ab36331c 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -639,7 +639,7 @@ dofork (void **proc, bool *with_forkables)
     else
       {
 	res = grouped.child (stackp);
-	in_forkee = false;
+	__in_forkee = FORKED;
 	ischild = true;	/* might have been reset by fork mem copy */
       }
   }
diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc
index c259ce18fc5d..a94aa5694e2d 100644
--- a/winsup/cygwin/globals.cc
+++ b/winsup/cygwin/globals.cc
@@ -73,8 +73,6 @@ bool wincmdln;
 winsym_t allow_winsymlinks = WSYM_default;
 bool disable_pcon;
 
-bool NO_COPY in_forkee;
-
 /* Taken from BSD libc:
    This variable is zero until a process has created a pthread.  It is used
    to avoid calling locking functions in libc when they are not required.
@@ -183,6 +181,17 @@ extern "C" {
    /* impure_ptr */ _GLOBAL_REENT,
   };
   int _check_for_executable = true;
+
+  /* This was a bool initially, just indicating if we're in the forked
+     child during fork(2).  However, we need an indicator accessible from
+     plain C we can ask if we're in a forked child even after fork(2)
+     finished.  Therefore redefined how we use this variable. */
+  enum {
+    NOT_FORKED	= 0,
+    FORKING	= 1,
+    FORKED	= 2
+  };
+  int NO_COPY __in_forkee;
 };
 
 int NO_COPY __api_fatal_exit_val = 1;
diff --git a/winsup/cygwin/mm/heap.cc b/winsup/cygwin/mm/heap.cc
index 72ea486f38f1..267f4ffa7da1 100644
--- a/winsup/cygwin/mm/heap.cc
+++ b/winsup/cygwin/mm/heap.cc
@@ -154,7 +154,7 @@ user_heap_info::init ()
 	  if ((reserve_size -= page_const) < allocsize)
 	    break;
 	}
-      if (!p && in_forkee && !fork_info->abort (NULL))
+      if (!p && __in_forkee == FORKING && !fork_info->abort (NULL))
 	api_fatal ("couldn't allocate heap, %E, base %p, top %p, "
 		   "reserve_size %ld, allocsize %ld, page_const %d",
 		   base, top,

                 reply	other threads:[~2024-01-29 12:44 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20240129124405.ED2DA3858407@sourceware.org \
    --to=corinna@sourceware.org \
    --cc=cygwin-cvs@sourceware.org \
    /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).