aboutsummaryrefslogtreecommitdiff
path: root/winsup/cygwin/fork.cc
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2004-02-12 03:01:58 +0000
committerChristopher Faylor <me@cgf.cx>2004-02-12 03:01:58 +0000
commite431827c7cab81292e8cd4ec9d3a4a60b35a42f2 (patch)
tree1b9056071ae2ab09f0d3474904a4c5f71599128d /winsup/cygwin/fork.cc
parent2bc01fb1f5d3166c4960c5f9a1ff617f0f46a60d (diff)
downloadnewlib-e431827c7cab81292e8cd4ec9d3a4a60b35a42f2.zip
newlib-e431827c7cab81292e8cd4ec9d3a4a60b35a42f2.tar.gz
newlib-e431827c7cab81292e8cd4ec9d3a4a60b35a42f2.tar.bz2
Rename _threadinfo to _cygtls, throughout.
* cygtls.h (_cygtls::call_signal_handler): Rename from call_signal_handler_now. (_cygtls::push): Make second argument mandatory. (_cygtls::fixup_after_fork): Declare new function. (_cygtls::lock): Ditto. * cygtls.cc (_cygtls::fixup_after_fork): Define new function. * dcrt0.cc (cygwin_finished_initializing): Define as bool. (alloc_stack): Use _tlstop rather than arbitrary variable in probably vain attempt to avoid strange fork problem on CTRL-C. (dll_crt0_0): Remove obsolete winpids::init call. * dll_init.cc (dll_dllcrt0): Detect forkee condition as equivalent to initializing. * winsup.h (cygwin_finished_initializing): Declare as bool. * exceptions.cc (handle_exceptions): Rely on cygwin_finished_initializing to determine how to handle exception during process startup. (_cygtls::call_signal_handler): Rename from call_signal_handler_now. (_cygtls::interrupt_now): Fill in second argument to push. (signal_fixup_after_fork): Eliminate. (setup_handler): Initialize locked to avoid potential inappropriate unlock. Resume thread if it has acquired the stack lock. (ctrl_c_handler): Just exit if ctrl-c is hit before cygiwn has finished initializing. * fork.cc (sync_with_child): Don't call abort since it can cause exit deadlocks. (sync_with_child): Change debugging output slightly. (fork_child): Set cygwin_finished_initializing here. Call _cygtls fork fixup and explicitly call sigproc_init. (fork_parent): Release malloc lock on fork failure. (vfork): Call signal handler via _my_tls. * sigproc.cc (sig_send): Ditto. * syscalls.cc (readv): Ditto. * termios.cc (tcsetattr): Ditto. * wait.cc (wait4): Ditto. * signal.cc (nanosleep): Ditto. (abort): Ditto. (kill_pgrp): Avoid killing self if exiting. * sync.cc (muto::acquire): Remove (temporarily?) ill-advised exiting_thread check. * gendef (_sigfe): Be more agressive in protecting stack pointer from other access by signal thread. (_cygtls::locked): Define new function. (_sigbe): Ditto. (_cygtls::pop): Protect edx. (_cygtls::lock): Use guaranteed method to set eax to 1. (longjmp): Aggressively protect signal stack. * miscfuncs.cc (low_priority_sleep): Reduce "sleep time" for secs == 0. * pinfo.cc (winpids::set): Counterintuitively use malloc's lock to protect simultaneous access to the pids list since there are pathological conditions which can cause malloc to call winpid. (winpids::init): Eliminate. * pinfo.h (winpids::cs): Eliminate declaration. * pinfo.h (winpids::init): Eliminate definition.
Diffstat (limited to 'winsup/cygwin/fork.cc')
-rw-r--r--winsup/cygwin/fork.cc50
1 files changed, 28 insertions, 22 deletions
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 8a5e5bf..01b9dbc 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -167,11 +167,11 @@ sync_with_child (PROCESS_INFORMATION &pi, HANDLE subproc_ready,
*/
if (errcode != STATUS_CONTROL_C_EXIT)
{
- system_printf ("child %u(%p) died before initialization with status code %p",
- cygwin_pid (pi.dwProcessId), pi.hProcess, errcode);
- system_printf ("*** child state %s", s);
+ system_printf ("child %u(%p) died before initialization with status code %p",
+ cygwin_pid (pi.dwProcessId), pi.hProcess, errcode);
+ system_printf ("*** child state %s", s);
#ifdef DEBUGGING
- abort ();
+ try_to_debug ();
#endif
}
set_errno (EAGAIN);
@@ -212,13 +212,13 @@ sync_with_parent (const char *s, bool hang_self)
switch (psync_rc)
{
case WAIT_TIMEOUT:
- api_fatal ("WFSO timed out for %s", s);
+ api_fatal ("WFSO timed out %s", s);
break;
case WAIT_FAILED:
if (GetLastError () == ERROR_INVALID_HANDLE &&
WaitForSingleObject (fork_info->forker_finished, 1) != WAIT_FAILED)
break;
- api_fatal ("WFSO failed for %s, fork_finished %p, %E", s,
+ api_fatal ("WFSO failed %s, fork_finished %p, %E", s,
fork_info->forker_finished);
break;
default:
@@ -243,6 +243,17 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
sigproc_printf ("hParent %p, child 1 first_dll %p, load_dlls %d", hParent,
first_dll, load_dlls);
+ /* If we've played with the stack, stacksize != 0. That means that
+ fork() was invoked from other than the main thread. Make sure that
+ the threadinfo information is properly set up. */
+ if (!fork_info->stacksize)
+ {
+ _main_tls = &_my_tls;
+ _main_tls->init_thread (NULL, NULL);
+ _main_tls->local_clib = *_impure_ptr;
+ _impure_ptr = &_main_tls->local_clib;
+ }
+
#ifdef DEBUGGING
char c;
if (GetEnvironmentVariable ("FORKDEBUG", &c, 1))
@@ -257,18 +268,6 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
}
#endif
- /* If we've played with the stack, stacksize != 0. That means that
- fork() was invoked from other than the main thread. Make sure that
- when the "main" thread exits it calls do_exit, like a normal process.
- Exit with a status code of 0. */
- if (fork_info->stacksize)
- {
- _main_tls = &_my_tls;
- _main_tls->init_thread (NULL, NULL);
- _main_tls->local_clib = *_impure_ptr;
- _impure_ptr = &_main_tls->local_clib;
- }
-
set_file_api_mode (current_codepage);
MALLOC_CHECK;
@@ -307,7 +306,8 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
#endif
pinfo_fixup_after_fork ();
- signal_fixup_after_fork ();
+ _my_tls.fixup_after_fork ();
+ sigproc_init ();
/* Set thread local stuff to zero. Under Windows 95/98 this is sometimes
non-zero, for some reason.
@@ -320,6 +320,7 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
fixup_timers_after_fork ();
wait_for_sigthread ();
cygbench ("fork-child");
+ cygwin_finished_initializing = true;
return 0;
}
@@ -458,7 +459,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
myself->progname, myself->progname, c_flags, &si, &pi);
- __malloc_lock ();
+ bool locked = __malloc_lock ();
void *newheap;
newheap = cygheap_setup_for_child (&ch, cygheap->fdtab.need_fixup_before ());
rc = CreateProcess (myself->progname, /* image to run */
@@ -483,6 +484,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
/* Restore impersonation */
cygheap->user.reimpersonate ();
cygheap_setup_for_child_cleanup (newheap, &ch, 0);
+ __malloc_unlock ();
return -1;
}
@@ -573,6 +575,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
dll_bss_start, dll_bss_end, impure_beg, impure_end, NULL);
__malloc_unlock ();
+ locked = false;
MALLOC_CHECK;
if (!rc)
goto cleanup;
@@ -622,6 +625,9 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
/* Common cleanup code for failure cases */
cleanup:
+ if (locked)
+ __malloc_unlock ();
+
/* Remember to de-allocate the fd table. */
if (pi.hProcess)
ForceCloseHandle1 (pi.hProcess, childhProc);
@@ -725,7 +731,7 @@ vfork ()
debug_printf ("cygheap->ctty_on_hold %p, cygheap->open_fhs %d", cygheap->ctty_on_hold, cygheap->open_fhs);
int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1;
debug_printf ("%d = vfork()", res);
- call_signal_handler_now (); // FIXME: racy
+ _my_tls.call_signal_handler (); // FIXME: racy
vf->tls = _my_tls;
return res;
}
@@ -757,7 +763,7 @@ vfork ()
debug_printf ("exiting vfork, pid %d", pid);
sig_dispatch_pending ();
- call_signal_handler_now (); // FIXME: racy
+ _my_tls.call_signal_handler (); // FIXME: racy
_my_tls = vf->tls;
return pid;
#endif