* 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.
+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.
void
threadname_init ()
{
- threadname_lock = new_muto (FALSE, NULL);
+ threadname_lock = new_muto (FALSE, "threadname_lock");
}
void __stdcall
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. */
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);
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);
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
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;
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))
{
sigproc_printf ("ResumeThread returned %d", res);
}
-out1:
sigproc_printf ("returning %d", interrupted);
return interrupted;
}
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');
/**********************************************************************/
/* 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);
}
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
fhandler_tty_common (FH_TTYS, name, 0)
{
set_cb (sizeof *this);
- debug_printf ("here");
inuse = NULL;
}
fhandler_tty_slave *fts = (fhandler_tty_slave *) child;
int errind;
- termios_printf ("here");
fts->ttynum = ttynum;
fts->tcinit (get_ttyp ());
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))
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
__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);
}
}
- 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;
/* 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
{
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;
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)
#ifndef NOSTRACE
-#ifndef STRACE_HHMMSS
int
strace::microseconds()
{
first_microsec = microsec;
return microsec - first_microsec;
}
-#endif
/* sprintf analog for use by output routines. */
int
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)))
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
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