diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 5ed168267..c04ecc297 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,26 @@ +Tue Mar 14 23:41:16 2000 Christopher Faylor + + Pipe changes throughout suggested by Eric Fifer + * debug.cc (threadname_init): Pass name of lock as arg 2 of new_muto. + * malloc.cc (malloc_init): Ditto. + * sigproc.cc (sigproc_init): Ditto. + * exceptions.cc (events_init): Ditto. + (call_handler): Eliminate special case for hExeced. Report locked + thread in debugging output. + * fhandler.cc (fhandker_pipe::fhandler_pipe): Propagate device type to + base class. + * fhandler.h (fhandler_pipe): Ditto. + * hinfo.cc (hinfo::build_fhandler): Pass specific type of pipe to + constructor. + * spawn.cc (spawn_guts): Eliminate dependency on signal when waiting + for subprocess. + * strace.cc: Remove obsolete #ifdef. + * sync.cc (muto::muto): Save the name of the muto. + (muto:~muto): Also release the muto. + * sync.h: Add a muto name field. + * select.cc (peek_pipe): Avoid doing a PeekNamedPipe on the write end + of a pipe. + Sun Mar 12 01:14:33 2000 Christopher Faylor * fhandler.cc (fhandler_base::get_readahead_into_buffer): New function. diff --git a/winsup/cygwin/debug.cc b/winsup/cygwin/debug.cc index e7ddec8af..99fe1152e 100644 --- a/winsup/cygwin/debug.cc +++ b/winsup/cygwin/debug.cc @@ -30,7 +30,7 @@ static NO_COPY thread_info threads[32] = {{0, NULL}}; // increase as necessary void threadname_init () { - threadname_lock = new_muto (FALSE, NULL); + threadname_lock = new_muto (FALSE, "threadname_lock"); } void __stdcall @@ -202,7 +202,7 @@ static muto NO_COPY *debug_lock = NULL; void debug_init () { - debug_lock = new_muto (FALSE, NULL); + debug_lock = new_muto (FALSE, "debug_lock"); } /* Find a registered handle in the linked list of handles. */ diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 385553a65..f3dd1fb94 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -233,7 +233,8 @@ hinfo::build_fhandler (int fd, DWORD dev, const char *name, int unit) fhandler_base *fh; void *buf = calloc (1, sizeof (fhandler_union) + 100); - switch (dev & FH_DEVMASK) + dev &= FH_DEVMASK; + switch (dev) { case FH_TTYM: fh = new (buf) fhandler_tty_master (name, unit); @@ -256,12 +257,12 @@ hinfo::build_fhandler (int fd, DWORD dev, const char *name, int unit) fh = new (buf) fhandler_windows (name); break; case FH_SERIAL: - fh = new (buf) fhandler_serial (name, FH_SERIAL, unit); + fh = new (buf) fhandler_serial (name, dev, unit); break; case FH_PIPE: case FH_PIPER: case FH_PIPEW: - fh = new (buf) fhandler_pipe (name); + fh = new (buf) fhandler_pipe (name, dev); break; case FH_SOCKET: fh = new (buf) fhandler_socket (name); diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 57cb232c9..4e9cc64cd 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -652,14 +652,6 @@ call_handler (int sig, struct sigaction& siga, void *handler, int nonmain) HANDLE hth = NULL; int res; - if (hExeced != NULL && hExeced != INVALID_HANDLE_VALUE) - { - SetEvent (signal_arrived); // For an EINTR case - sigproc_printf ("armed signal_arrived"); - exec_exit = sig; // Maybe we'll exit with this value - goto out1; - } - if (!nonmain) ebp = sigsave.ebp; else @@ -675,15 +667,16 @@ call_handler (int sig, struct sigaction& siga, void *handler, int nonmain) sigproc_printf ("suspending mainthread"); res = SuspendThread (hth); + muto *m; /* FIXME: Make multi-thread aware */ - for (muto *m = muto_start.next; m != NULL; m = m->next) + for (m = muto_start.next; m != NULL; m = m->next) if (m->unstable () || m->owner () == maintid) goto keep_looping; break; keep_looping: - sigproc_printf ("suspended thread owns a muto"); + sigproc_printf ("suspended thread owns a muto (%s)", m->name); if (res) goto set_pending; @@ -702,7 +695,7 @@ call_handler (int sig, struct sigaction& siga, void *handler, int nonmain) ebp = cx.Ebp; } - if (nonmain && interruptible (cx.Eip)) + if (hExeced != NULL || (nonmain && interruptible (cx.Eip))) interrupt_now (&cx, sig, siga, handler); else if (!interrupt_on_return (ebp, sig, siga, handler)) { @@ -729,7 +722,6 @@ out: sigproc_printf ("ResumeThread returned %d", res); } -out1: sigproc_printf ("returning %d", interrupted); return interrupted; } @@ -974,7 +966,7 @@ events_init (void) api_fatal ("can't create title mutex, %E"); ProtectHandle (title_mutex); - mask_sync = new_muto (FALSE, NULL); + mask_sync = new_muto (FALSE, "mask_sync"); windows_system_directory[0] = '\0'; (void) GetSystemDirectory (windows_system_directory, sizeof (windows_system_directory) - 2); char *end = strchr (windows_system_directory, '\0'); diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 4fbe8d33a..c3219aa7c 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1456,8 +1456,8 @@ fhandler_dev_null::dump (void) /**********************************************************************/ /* fhandler_pipe */ -fhandler_pipe::fhandler_pipe (const char *name) : - fhandler_base (FH_PIPE, name) +fhandler_pipe::fhandler_pipe (const char *name, DWORD devtype) : + fhandler_base (devtype, name) { set_cb (sizeof *this); } diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 9ebfa104e..f92ee88ba 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -327,7 +327,7 @@ public: class fhandler_pipe: public fhandler_base { public: - fhandler_pipe (const char *name = 0); + fhandler_pipe (const char *name = 0, DWORD devtype = FH_PIPE); off_t lseek (off_t offset, int whence); /* This strange test is due to the fact that we can't rely on Windows shells to "do the right thing" with pipes. Apparently diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 0cc9b5284..ef031b10f 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -437,7 +437,6 @@ fhandler_tty_slave::fhandler_tty_slave(const char *name) : fhandler_tty_common (FH_TTYS, name, 0) { set_cb (sizeof *this); - debug_printf ("here"); inuse = NULL; } @@ -682,7 +681,6 @@ fhandler_tty_common::dup (fhandler_base *child) fhandler_tty_slave *fts = (fhandler_tty_slave *) child; int errind; - termios_printf ("here"); fts->ttynum = ttynum; fts->tcinit (get_ttyp ()); @@ -867,7 +865,6 @@ fhandler_pty_master::open (const char *, int flags, mode_t) int fhandler_tty_common::close () { -termios_printf ("here %p", this); if (output_done_event && !CloseHandle (output_done_event)) termios_printf ("CloseHandle (output_done_event), %E"); if (ioctl_done_event && !CloseHandle (ioctl_done_event)) diff --git a/winsup/cygwin/malloc_wrapper.cc b/winsup/cygwin/malloc_wrapper.cc index 3fa5e064f..7e17fd9ec 100644 --- a/winsup/cygwin/malloc_wrapper.cc +++ b/winsup/cygwin/malloc_wrapper.cc @@ -206,7 +206,7 @@ static NO_COPY muto *mprotect = NULL; void malloc_init () { - mprotect = new_muto (FALSE, NULL); + mprotect = new_muto (FALSE, "mprotect"); /* Check if mallock is provided by application. If so, redirect all calls to export_malloc/free/realloc to application provided. This may happen if some other dll calls cygwin's malloc, but main code provides diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index fc1db5e3a..decd1bd6c 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -30,8 +30,8 @@ make_pipe (int fildes[2], unsigned int psize, int mode) __seterrno (); else { - fhandler_base *fhr = dtable.build_fhandler (fdr, FH_PIPE, "/dev/piper"); - fhandler_base *fhw = dtable.build_fhandler (fdw, FH_PIPE, "/dev/pipew"); + fhandler_base *fhr = dtable.build_fhandler (fdr, FH_PIPER, "/dev/piper"); + fhandler_base *fhw = dtable.build_fhandler (fdw, FH_PIPEW, "/dev/pipew"); int binmode = mode & O_TEXT ? 0 : 1; fhr->init (r, GENERIC_READ, binmode); diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 5067006fa..1199b1c55 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -426,7 +426,8 @@ peek_pipe (select_record *s, int ignra) } } - if (!PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL)) + if (fh->get_device() != FH_PIPEW && + !PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL)) { select_printf ("%s, PeekNamedPipe failed, %E", fh->get_name ()); n = -1; diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index a58bf0fcb..bb6be1237 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -616,7 +616,7 @@ sigproc_init () /* sync_proc_subproc is used by proc_subproc. It serialises * access to the children and zombie arrays. */ - sync_proc_subproc = new_muto (FALSE, NULL); + sync_proc_subproc = new_muto (FALSE, "sync_proc_subproc"); /* Initialize waitq structure for main thread. A waitq structure is * allocated for each thread that executes a wait to allow multiple threads diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 59b1e81c5..e4f41b26c 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -635,8 +635,8 @@ skip_arg_parsing: { BOOL exited; - HANDLE waitbuf[3] = {pi.hProcess, signal_arrived, spr}; - int nwait = 3; + HANDLE waitbuf[2] = {pi.hProcess, spr}; + int nwait = 2; SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST); res = 0; @@ -644,61 +644,60 @@ skip_arg_parsing: exec_exit = 1; exited = FALSE; MALLOC_CHECK; - waitfor: - switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, timeout)) + for (int i = 0; i < 100; i++) { - case WAIT_TIMEOUT: - syscall_printf ("WFMO timed out after signal"); - if (WaitForSingleObject (pi.hProcess, 0) != WAIT_OBJECT_0) + switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, timeout)) { - sigproc_printf ("subprocess still alive after signal"); - res = exec_exit; - } - else - { - sigproc_printf ("subprocess exited after signal"); - case WAIT_OBJECT_0: - sigproc_printf ("subprocess exited"); - if (!GetExitCodeProcess (pi.hProcess, &res)) - res = exec_exit; - exited = TRUE; - } - if (nwait > 2) - if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0) - res |= EXIT_REPARENTING; - else if (!(res & EXIT_REPARENTING)) - { - MALLOC_CHECK; - close_all_files (); - MALLOC_CHECK; - } - break; - case WAIT_OBJECT_0 + 1: - sigproc_printf ("signal arrived"); - timeout = 10; - goto waitfor; - case WAIT_OBJECT_0 + 2: - res = EXIT_REPARENTING; - MALLOC_CHECK; - ForceCloseHandle (spr); - MALLOC_CHECK; - if (!parent_alive) - { - nwait = 1; - sigproc_terminate (); - goto waitfor; + case WAIT_TIMEOUT: + syscall_printf ("WFMO timed out after signal"); + if (WaitForSingleObject (pi.hProcess, 0) != WAIT_OBJECT_0) + { + sigproc_printf ("subprocess still alive after signal"); + res = exec_exit; + } + else + { + sigproc_printf ("subprocess exited after signal"); + case WAIT_OBJECT_0: + sigproc_printf ("subprocess exited"); + if (!GetExitCodeProcess (pi.hProcess, &res)) + res = exec_exit; + exited = TRUE; + } + if (nwait > 2) + if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0) + res |= EXIT_REPARENTING; + else if (!(res & EXIT_REPARENTING)) + { + MALLOC_CHECK; + close_all_files (); + MALLOC_CHECK; + } + break; + case WAIT_OBJECT_0 + 1: + res = EXIT_REPARENTING; + MALLOC_CHECK; + ForceCloseHandle (spr); + MALLOC_CHECK; + if (!parent_alive) + { + nwait = 1; + sigproc_terminate (); + continue; + } + break; + case WAIT_FAILED: + DWORD r; + system_printf ("wait failed: nwait %d, pid %d, winpid %d, %E", + nwait, myself->pid, myself->dwProcessId); + system_printf ("waitbuf[0] %p %d", waitbuf[0], + GetHandleInformation (waitbuf[0], &r)); + system_printf ("waitbuf[1] %p = %d", waitbuf[1], + GetHandleInformation (waitbuf[1], &r)); + set_errno (ECHILD); + return -1; } break; - case WAIT_FAILED: - DWORD r; - system_printf ("wait failed: nwait %d, pid %d, winpid %d, %E", - nwait, myself->pid, myself->dwProcessId); - system_printf ("waitbuf[0] %p %d", waitbuf[0], - GetHandleInformation (waitbuf[0], &r)); - system_printf ("waitbuf[1] %p = %d", waitbuf[1], - GetHandleInformation (waitbuf[1], &r)); - set_errno (ECHILD); - return -1; } if (nwait > 2) diff --git a/winsup/cygwin/strace.cc b/winsup/cygwin/strace.cc index e13845e51..bafd4e38d 100644 --- a/winsup/cygwin/strace.cc +++ b/winsup/cygwin/strace.cc @@ -24,7 +24,6 @@ class strace NO_COPY strace; #ifndef NOSTRACE -#ifndef STRACE_HHMMSS int strace::microseconds() { @@ -58,7 +57,6 @@ strace::microseconds() first_microsec = microsec; return microsec - first_microsec; } -#endif /* sprintf analog for use by output routines. */ int diff --git a/winsup/cygwin/sync.cc b/winsup/cygwin/sync.cc index aa3978fe0..31bb27bdc 100644 --- a/winsup/cygwin/sync.cc +++ b/winsup/cygwin/sync.cc @@ -25,7 +25,7 @@ details. */ muto NO_COPY muto_start; /* Constructor */ -muto::muto(int inh, const char *name) : sync (0), visits(0), waiters(-1), tid (0), next (NULL) +muto::muto(int inh, const char *s) : sync (0), visits(0), waiters(-1), tid (0), next (NULL) { /* Create event which is used in the fallback case when blocking is necessary */ if (!(bruteforce = CreateEvent (inh ? &sec_all_nih : &sec_none_nih, FALSE, FALSE, name))) @@ -34,14 +34,20 @@ muto::muto(int inh, const char *name) : sync (0), visits(0), waiters(-1), tid (0 SetLastError (oerr); return; } + name = s; } -/* Destructor */ +/* Destructor (racy?) */ muto::~muto () { + while (visits) + release (); + + HANDLE h = bruteforce; + h = NULL; /* Just need to close the event handle */ - if (bruteforce) - CloseHandle (bruteforce); + if (h) + CloseHandle (h); } /* Acquire the lock. Argument is the number of milliseconds to wait for diff --git a/winsup/cygwin/sync.h b/winsup/cygwin/sync.h index c7ada834a..138b767bb 100644 --- a/winsup/cygwin/sync.h +++ b/winsup/cygwin/sync.h @@ -21,6 +21,7 @@ class muto DWORD tid; /* Thread Id of lock owner. */ public: class muto *next; + const char *name; void *operator new (size_t, void *p) {return p;} void *operator new (size_t) {return ::new muto; } void operator delete (void *) {;} /* can't handle allocated mutos