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>
* 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
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. */

View File

@ -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);

View File

@ -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');

View File

@ -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);
}

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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);

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 ());
n = -1;

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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