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:
parent
31b3dbe174
commit
332600d80c
|
@ -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.
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue