Pipe changes throughout suggested by Eric Fifer <EFifer@sanwaint.com>

* 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.
This commit is contained in:
Christopher Faylor 2000-03-15 04:49:36 +00:00
parent 31b3dbe174
commit 332600d80c
15 changed files with 106 additions and 88 deletions

View File

@ -1,3 +1,26 @@
Tue Mar 14 23:41:16 2000 Christopher Faylor <cgf@cygnus.com>
Pipe changes throughout suggested by Eric Fifer <EFifer@sanwaint.com>
* 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 <cgf@cygnus.com> Sun Mar 12 01:14:33 2000 Christopher Faylor <cgf@cygnus.com>
* fhandler.cc (fhandler_base::get_readahead_into_buffer): New function. * fhandler.cc (fhandler_base::get_readahead_into_buffer): New function.

View File

@ -30,7 +30,7 @@ static NO_COPY thread_info threads[32] = {{0, NULL}}; // increase as necessary
void void
threadname_init () threadname_init ()
{ {
threadname_lock = new_muto (FALSE, NULL); threadname_lock = new_muto (FALSE, "threadname_lock");
} }
void __stdcall void __stdcall
@ -202,7 +202,7 @@ static muto NO_COPY *debug_lock = NULL;
void void
debug_init () 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. */ /* Find a registered handle in the linked list of handles. */

View File

@ -233,7 +233,8 @@ hinfo::build_fhandler (int fd, DWORD dev, const char *name, int unit)
fhandler_base *fh; fhandler_base *fh;
void *buf = calloc (1, sizeof (fhandler_union) + 100); void *buf = calloc (1, sizeof (fhandler_union) + 100);
switch (dev & FH_DEVMASK) dev &= FH_DEVMASK;
switch (dev)
{ {
case FH_TTYM: case FH_TTYM:
fh = new (buf) fhandler_tty_master (name, unit); 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); fh = new (buf) fhandler_windows (name);
break; break;
case FH_SERIAL: case FH_SERIAL:
fh = new (buf) fhandler_serial (name, FH_SERIAL, unit); fh = new (buf) fhandler_serial (name, dev, unit);
break; break;
case FH_PIPE: case FH_PIPE:
case FH_PIPER: case FH_PIPER:
case FH_PIPEW: case FH_PIPEW:
fh = new (buf) fhandler_pipe (name); fh = new (buf) fhandler_pipe (name, dev);
break; break;
case FH_SOCKET: case FH_SOCKET:
fh = new (buf) fhandler_socket (name); fh = new (buf) fhandler_socket (name);

View File

@ -652,14 +652,6 @@ call_handler (int sig, struct sigaction& siga, void *handler, int nonmain)
HANDLE hth = NULL; HANDLE hth = NULL;
int res; 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) if (!nonmain)
ebp = sigsave.ebp; ebp = sigsave.ebp;
else else
@ -675,15 +667,16 @@ call_handler (int sig, struct sigaction& siga, void *handler, int nonmain)
sigproc_printf ("suspending mainthread"); sigproc_printf ("suspending mainthread");
res = SuspendThread (hth); res = SuspendThread (hth);
muto *m;
/* FIXME: Make multi-thread aware */ /* 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) if (m->unstable () || m->owner () == maintid)
goto keep_looping; goto keep_looping;
break; break;
keep_looping: keep_looping:
sigproc_printf ("suspended thread owns a muto"); sigproc_printf ("suspended thread owns a muto (%s)", m->name);
if (res) if (res)
goto set_pending; goto set_pending;
@ -702,7 +695,7 @@ call_handler (int sig, struct sigaction& siga, void *handler, int nonmain)
ebp = cx.Ebp; ebp = cx.Ebp;
} }
if (nonmain && interruptible (cx.Eip)) if (hExeced != NULL || (nonmain && interruptible (cx.Eip)))
interrupt_now (&cx, sig, siga, handler); interrupt_now (&cx, sig, siga, handler);
else if (!interrupt_on_return (ebp, sig, siga, handler)) else if (!interrupt_on_return (ebp, sig, siga, handler))
{ {
@ -729,7 +722,6 @@ out:
sigproc_printf ("ResumeThread returned %d", res); sigproc_printf ("ResumeThread returned %d", res);
} }
out1:
sigproc_printf ("returning %d", interrupted); sigproc_printf ("returning %d", interrupted);
return interrupted; return interrupted;
} }
@ -974,7 +966,7 @@ events_init (void)
api_fatal ("can't create title mutex, %E"); api_fatal ("can't create title mutex, %E");
ProtectHandle (title_mutex); ProtectHandle (title_mutex);
mask_sync = new_muto (FALSE, NULL); mask_sync = new_muto (FALSE, "mask_sync");
windows_system_directory[0] = '\0'; windows_system_directory[0] = '\0';
(void) GetSystemDirectory (windows_system_directory, sizeof (windows_system_directory) - 2); (void) GetSystemDirectory (windows_system_directory, sizeof (windows_system_directory) - 2);
char *end = strchr (windows_system_directory, '\0'); char *end = strchr (windows_system_directory, '\0');

View File

@ -1456,8 +1456,8 @@ fhandler_dev_null::dump (void)
/**********************************************************************/ /**********************************************************************/
/* fhandler_pipe */ /* fhandler_pipe */
fhandler_pipe::fhandler_pipe (const char *name) : fhandler_pipe::fhandler_pipe (const char *name, DWORD devtype) :
fhandler_base (FH_PIPE, name) fhandler_base (devtype, name)
{ {
set_cb (sizeof *this); set_cb (sizeof *this);
} }

View File

@ -327,7 +327,7 @@ public:
class fhandler_pipe: public fhandler_base class fhandler_pipe: public fhandler_base
{ {
public: 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); off_t lseek (off_t offset, int whence);
/* This strange test is due to the fact that we can't rely on /* This strange test is due to the fact that we can't rely on
Windows shells to "do the right thing" with pipes. Apparently Windows shells to "do the right thing" with pipes. Apparently

View File

@ -437,7 +437,6 @@ fhandler_tty_slave::fhandler_tty_slave(const char *name) :
fhandler_tty_common (FH_TTYS, name, 0) fhandler_tty_common (FH_TTYS, name, 0)
{ {
set_cb (sizeof *this); set_cb (sizeof *this);
debug_printf ("here");
inuse = NULL; inuse = NULL;
} }
@ -682,7 +681,6 @@ fhandler_tty_common::dup (fhandler_base *child)
fhandler_tty_slave *fts = (fhandler_tty_slave *) child; fhandler_tty_slave *fts = (fhandler_tty_slave *) child;
int errind; int errind;
termios_printf ("here");
fts->ttynum = ttynum; fts->ttynum = ttynum;
fts->tcinit (get_ttyp ()); fts->tcinit (get_ttyp ());
@ -867,7 +865,6 @@ fhandler_pty_master::open (const char *, int flags, mode_t)
int int
fhandler_tty_common::close () fhandler_tty_common::close ()
{ {
termios_printf ("here %p", this);
if (output_done_event && !CloseHandle (output_done_event)) if (output_done_event && !CloseHandle (output_done_event))
termios_printf ("CloseHandle (output_done_event), %E"); termios_printf ("CloseHandle (output_done_event), %E");
if (ioctl_done_event && !CloseHandle (ioctl_done_event)) if (ioctl_done_event && !CloseHandle (ioctl_done_event))

View File

@ -206,7 +206,7 @@ static NO_COPY muto *mprotect = NULL;
void void
malloc_init () malloc_init ()
{ {
mprotect = new_muto (FALSE, NULL); mprotect = new_muto (FALSE, "mprotect");
/* Check if mallock is provided by application. If so, redirect all /* Check if mallock is provided by application. If so, redirect all
calls to export_malloc/free/realloc to application provided. This may calls to export_malloc/free/realloc to application provided. This may
happen if some other dll calls cygwin's malloc, but main code provides happen if some other dll calls cygwin's malloc, but main code provides

View File

@ -30,8 +30,8 @@ make_pipe (int fildes[2], unsigned int psize, int mode)
__seterrno (); __seterrno ();
else else
{ {
fhandler_base *fhr = dtable.build_fhandler (fdr, FH_PIPE, "/dev/piper"); fhandler_base *fhr = dtable.build_fhandler (fdr, FH_PIPER, "/dev/piper");
fhandler_base *fhw = dtable.build_fhandler (fdw, FH_PIPE, "/dev/pipew"); fhandler_base *fhw = dtable.build_fhandler (fdw, FH_PIPEW, "/dev/pipew");
int binmode = mode & O_TEXT ? 0 : 1; int binmode = mode & O_TEXT ? 0 : 1;
fhr->init (r, GENERIC_READ, binmode); fhr->init (r, GENERIC_READ, binmode);

View File

@ -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 ()); select_printf ("%s, PeekNamedPipe failed, %E", fh->get_name ());
n = -1; n = -1;

View File

@ -616,7 +616,7 @@ sigproc_init ()
/* sync_proc_subproc is used by proc_subproc. It serialises /* sync_proc_subproc is used by proc_subproc. It serialises
* access to the children and zombie arrays. * 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 /* Initialize waitq structure for main thread. A waitq structure is
* allocated for each thread that executes a wait to allow multiple threads * allocated for each thread that executes a wait to allow multiple threads

View File

@ -635,8 +635,8 @@ skip_arg_parsing:
{ {
BOOL exited; BOOL exited;
HANDLE waitbuf[3] = {pi.hProcess, signal_arrived, spr}; HANDLE waitbuf[2] = {pi.hProcess, spr};
int nwait = 3; int nwait = 2;
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST); SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
res = 0; res = 0;
@ -644,61 +644,60 @@ skip_arg_parsing:
exec_exit = 1; exec_exit = 1;
exited = FALSE; exited = FALSE;
MALLOC_CHECK; MALLOC_CHECK;
waitfor: for (int i = 0; i < 100; i++)
switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, timeout))
{ {
case WAIT_TIMEOUT: switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, timeout))
syscall_printf ("WFMO timed out after signal");
if (WaitForSingleObject (pi.hProcess, 0) != WAIT_OBJECT_0)
{ {
sigproc_printf ("subprocess still alive after signal"); case WAIT_TIMEOUT:
res = exec_exit; syscall_printf ("WFMO timed out after signal");
} if (WaitForSingleObject (pi.hProcess, 0) != WAIT_OBJECT_0)
else {
{ sigproc_printf ("subprocess still alive after signal");
sigproc_printf ("subprocess exited after signal"); res = exec_exit;
case WAIT_OBJECT_0: }
sigproc_printf ("subprocess exited"); else
if (!GetExitCodeProcess (pi.hProcess, &res)) {
res = exec_exit; sigproc_printf ("subprocess exited after signal");
exited = TRUE; case WAIT_OBJECT_0:
} sigproc_printf ("subprocess exited");
if (nwait > 2) if (!GetExitCodeProcess (pi.hProcess, &res))
if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0) res = exec_exit;
res |= EXIT_REPARENTING; exited = TRUE;
else if (!(res & EXIT_REPARENTING)) }
{ if (nwait > 2)
MALLOC_CHECK; if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0)
close_all_files (); res |= EXIT_REPARENTING;
MALLOC_CHECK; else if (!(res & EXIT_REPARENTING))
} {
break; MALLOC_CHECK;
case WAIT_OBJECT_0 + 1: close_all_files ();
sigproc_printf ("signal arrived"); MALLOC_CHECK;
timeout = 10; }
goto waitfor; break;
case WAIT_OBJECT_0 + 2: case WAIT_OBJECT_0 + 1:
res = EXIT_REPARENTING; res = EXIT_REPARENTING;
MALLOC_CHECK; MALLOC_CHECK;
ForceCloseHandle (spr); ForceCloseHandle (spr);
MALLOC_CHECK; MALLOC_CHECK;
if (!parent_alive) if (!parent_alive)
{ {
nwait = 1; nwait = 1;
sigproc_terminate (); sigproc_terminate ();
goto waitfor; 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; 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) if (nwait > 2)

View File

@ -24,7 +24,6 @@ class strace NO_COPY strace;
#ifndef NOSTRACE #ifndef NOSTRACE
#ifndef STRACE_HHMMSS
int int
strace::microseconds() strace::microseconds()
{ {
@ -58,7 +57,6 @@ strace::microseconds()
first_microsec = microsec; first_microsec = microsec;
return microsec - first_microsec; return microsec - first_microsec;
} }
#endif
/* sprintf analog for use by output routines. */ /* sprintf analog for use by output routines. */
int int

View File

@ -25,7 +25,7 @@ details. */
muto NO_COPY muto_start; muto NO_COPY muto_start;
/* Constructor */ /* 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 */ /* 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))) 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); SetLastError (oerr);
return; return;
} }
name = s;
} }
/* Destructor */ /* Destructor (racy?) */
muto::~muto () muto::~muto ()
{ {
while (visits)
release ();
HANDLE h = bruteforce;
h = NULL;
/* Just need to close the event handle */ /* Just need to close the event handle */
if (bruteforce) if (h)
CloseHandle (bruteforce); CloseHandle (h);
} }
/* Acquire the lock. Argument is the number of milliseconds to wait for /* Acquire the lock. Argument is the number of milliseconds to wait for

View File

@ -21,6 +21,7 @@ class muto
DWORD tid; /* Thread Id of lock owner. */ DWORD tid; /* Thread Id of lock owner. */
public: public:
class muto *next; class muto *next;
const char *name;
void *operator new (size_t, void *p) {return p;} void *operator new (size_t, void *p) {return p;}
void *operator new (size_t) {return ::new muto; } void *operator new (size_t) {return ::new muto; }
void operator delete (void *) {;} /* can't handle allocated mutos void operator delete (void *) {;} /* can't handle allocated mutos