* exceptions.cc (setup_handler): Always relinquish lock after we've

interrupted.
* fhandler.cc: Move pipe methods to pipe.cc.
* fhandler.h (fhandler_pipe): Add new methods.
* fork.cc (sync_with_parent): Make error messages more informative.
* pipe.cc (fhandler_pipe::fhandler_pipe): Move here from fhandler.cc.
(fhandler_pipe::lseek): Ditto.
(fhandler_pipe::set_close_on_exec): New method.
(fhandler_pipe::read): Ditto.
(fhandler_pipe::close): Ditto.
(fhandler_pipe::dup): Ditto.
(make_pipe): Create the guard mutex on the read side of the pipe.
* select.cc (peek_pipe): Use guard_mutex to discover if we have the right to
read on this pipe.
(fhandler_pipe::readh_for_read): Pass the read pipe guard mutex to peek_pipe.
* syscalls.cc (_read): Always detect signal catchers, for now.
* debug.cc (makethread): Eliminate hack to make thread inheritable.
* sigproc.cc (subproc_init): Don't use hack to make thread inheritable.
This commit is contained in:
Christopher Faylor 2001-09-22 16:55:02 +00:00
parent 142920f65a
commit 5e733918c0
10 changed files with 120 additions and 56 deletions

View File

@ -1,3 +1,26 @@
Sat Sep 22 12:44:57 2001 Christopher Faylor <cgf@cygnus.com>
* exceptions.cc (setup_handler): Always relinquish lock after we've
interrupted.
* fhandler.cc: Move pipe methods to pipe.cc.
* fhandler.h (fhandler_pipe): Add new methods.
* fork.cc (sync_with_parent): Make error messages more informative.
* pipe.cc (fhandler_pipe::fhandler_pipe): Move here from fhandler.cc.
(fhandler_pipe::lseek): Ditto.
(fhandler_pipe::set_close_on_exec): New method.
(fhandler_pipe::read): Ditto.
(fhandler_pipe::close): Ditto.
(fhandler_pipe::dup): Ditto.
(make_pipe): Create the guard mutex on the read side of the pipe.
* select.cc (peek_pipe): Use guard_mutex to discover if we have the
right to read on this pipe.
(fhandler_pipe::readh_for_read): Pass the read pipe guard mutex to
peek_pipe.
* syscalls.cc (_read): Always detect signal catchers, for now.
* debug.cc (makethread): Eliminate hack to make thread inheritable.
* sigproc.cc (subproc_init): Don't use hack to make thread inheritable.
Thu Sep 20 16:48:44 2001 Christopher Faylor <cgf@cygnus.com> Thu Sep 20 16:48:44 2001 Christopher Faylor <cgf@cygnus.com>
* fhandler.cc (fhandler_base::set_inheritance): Just use * fhandler.cc (fhandler_base::set_inheritance): Just use

View File

@ -105,7 +105,6 @@ makethread (LPTHREAD_START_ROUTINE start, LPVOID param, DWORD flags,
{ {
DWORD tid; DWORD tid;
HANDLE h; HANDLE h;
SECURITY_ATTRIBUTES *sa;
thread_start *info; /* Various information needed by the newly created thread */ thread_start *info; /* Various information needed by the newly created thread */
for (;;) for (;;)
@ -123,16 +122,9 @@ out:
info->func = start; /* Real function to start */ info->func = start; /* Real function to start */
info->arg = param; /* The single parameter to the thread */ info->arg = param; /* The single parameter to the thread */
if (*name != '+') if ((h = CreateThread (&sec_none_nih, 0, thread_stub, (VOID *) info, flags,
sa = &sec_none_nih; /* The handle should not be inherited by subprocesses. */ &tid)))
else regthread (name, tid); /* Register for debugging output. */
{
name++;
sa = &sec_none; /* The handle should be inherited by subprocesses. */
}
if ((h = CreateThread (sa, 0, thread_stub, (VOID *) info, flags, &tid)))
regthread (name, tid); /* Register this name/thread id for debugging output. */
return h; return h;
} }

View File

@ -849,8 +849,7 @@ setup_handler (int sig, void *handler, struct sigaction& siga)
if (th) if (th)
{ {
interrupted = interrupt_on_return (th, sig, handler, siga); interrupted = interrupt_on_return (th, sig, handler, siga);
if (!interrupted) LeaveCriticalSection (&th->lock);
LeaveCriticalSection (&th->lock);
} }
else if (interruptible (cx.Eip)) else if (interruptible (cx.Eip))
interrupted = interrupt_now (&cx, sig, handler, siga); interrupted = interrupt_now (&cx, sig, handler, siga);
@ -870,9 +869,6 @@ setup_handler (int sig, void *handler, struct sigaction& siga)
sigproc_printf ("couldn't send signal %d", sig); sigproc_printf ("couldn't send signal %d", sig);
} }
if (th)
LeaveCriticalSection (&th->lock);
if (!hth) if (!hth)
sigproc_printf ("good. Didn't suspend main thread, th %p", th); sigproc_printf ("good. Didn't suspend main thread, th %p", th);
else else

View File

@ -1289,8 +1289,8 @@ fhandler_disk_file::open (path_conv& real_path, int flags, mode_t mode)
which might return a valid HANDLE without having actually opened which might return a valid HANDLE without having actually opened
the file. the file.
The only known file system to date is the SUN NFS Solstice Client 3.1 The only known file system to date is the SUN NFS Solstice Client 3.1
which returns a valid handle when trying to open a file in a non which returns a valid handle when trying to open a file in a nonexistent
existant directory. */ directory. */
if (real_path.has_buggy_open () if (real_path.has_buggy_open ()
&& GetFileAttributes (win32_path_name) == (DWORD) -1) && GetFileAttributes (win32_path_name) == (DWORD) -1)
{ {
@ -1493,23 +1493,6 @@ fhandler_dev_null::dump (void)
paranoid_printf ("here"); paranoid_printf ("here");
} }
/**********************************************************************/
/* fhandler_pipe */
fhandler_pipe::fhandler_pipe (const char *name, DWORD devtype) :
fhandler_base (devtype, name)
{
set_cb (sizeof *this);
}
off_t
fhandler_pipe::lseek (off_t offset, int whence)
{
debug_printf ("(%d, %d)", offset, whence);
set_errno (ESPIPE);
return -1;
}
void void
fhandler_base::set_inheritance (HANDLE &h, int not_inheriting) fhandler_base::set_inheritance (HANDLE &h, int not_inheriting)
{ {

View File

@ -435,17 +435,20 @@ public:
class fhandler_pipe: public fhandler_base class fhandler_pipe: public fhandler_base
{ {
HANDLE guard;
public: public:
fhandler_pipe (const char *name = 0, DWORD devtype = FH_PIPE); 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
Windows shells to "do the right thing" with pipes. Apparently
the can keep one end of the pipe open when it shouldn't be. */
BOOL is_slow () {return !wincap.has_unreliable_pipes ();} BOOL is_slow () {return !wincap.has_unreliable_pipes ();}
select_record *select_read (select_record *s); select_record *select_read (select_record *s);
select_record *select_write (select_record *s); select_record *select_write (select_record *s);
select_record *select_except (select_record *s); select_record *select_except (select_record *s);
int ready_for_read (int fd, DWORD howlong, int ignra); int ready_for_read (int fd, DWORD howlong, int ignra);
void set_close_on_exec (int val);
int read (void *ptr, size_t len);
int close ();
void create_guard (SECURITY_ATTRIBUTES *sa) {guard = CreateMutex (sa, FALSE, NULL);}
int dup (fhandler_base *child);
}; };
class fhandler_dev_raw: public fhandler_base class fhandler_dev_raw: public fhandler_base

View File

@ -198,7 +198,7 @@ sync_with_parent(const char *s, bool hang_self)
debug_printf ("signalling parent: %s", s); debug_printf ("signalling parent: %s", s);
/* Tell our parent we're waiting. */ /* Tell our parent we're waiting. */
if (!SetEvent (child_proc_info->subproc_ready)) if (!SetEvent (child_proc_info->subproc_ready))
api_fatal ("fork child - SetEvent failed, %E"); api_fatal ("fork child - SetEvent for %s failed, %E", s);
if (hang_self) if (hang_self)
{ {
HANDLE h = child_proc_info->forker_finished; HANDLE h = child_proc_info->forker_finished;
@ -210,13 +210,14 @@ sync_with_parent(const char *s, bool hang_self)
switch (psync_rc) switch (psync_rc)
{ {
case WAIT_TIMEOUT: case WAIT_TIMEOUT:
api_fatal ("WFSO timed out"); api_fatal ("WFSO timed out for %s", s);
break; break;
case WAIT_FAILED: case WAIT_FAILED:
if (GetLastError () == ERROR_INVALID_HANDLE && if (GetLastError () == ERROR_INVALID_HANDLE &&
WaitForSingleObject (child_proc_info->forker_finished, 1) != WAIT_FAILED) WaitForSingleObject (child_proc_info->forker_finished, 1) != WAIT_FAILED)
break; break;
api_fatal ("WFSO failed, fork_finished %p, %E", child_proc_info->forker_finished); api_fatal ("WFSO failed for %s, fork_finished %p, %E", s,
child_proc_info->forker_finished);
break; break;
default: default:
debug_printf ("no problems"); debug_printf ("no problems");

View File

@ -19,6 +19,60 @@ details. */
#include "cygheap.h" #include "cygheap.h"
#include "thread.h" #include "thread.h"
fhandler_pipe::fhandler_pipe (const char *name, DWORD devtype) :
fhandler_base (devtype, name), guard (0)
{
set_cb (sizeof *this);
}
off_t
fhandler_pipe::lseek (off_t offset, int whence)
{
debug_printf ("(%d, %d)", offset, whence);
set_errno (ESPIPE);
return -1;
}
void
fhandler_pipe::set_close_on_exec (int val)
{
this->fhandler_base::set_close_on_exec (val);
set_inheritance (guard, val);
}
int
fhandler_pipe::read (void *in_ptr, size_t in_len)
{
int res = this->fhandler_base::read (in_ptr, in_len);
ReleaseMutex (guard);
return res;
}
int fhandler_pipe::close ()
{
int res = this->fhandler_base::close ();
if (guard)
CloseHandle (guard);
return res;
}
int
fhandler_pipe::dup (fhandler_base *child)
{
int res = this->fhandler_base::dup (child);
if (res)
return res;
fhandler_pipe *ftp = (fhandler_pipe *) child;
if (guard == NULL)
ftp->guard = NULL;
else if (!DuplicateHandle (hMainProc, guard, hMainProc, &ftp->guard, 0, 1,
DUPLICATE_SAME_ACCESS))
return -1;
return 0;
}
static int static int
make_pipe (int fildes[2], unsigned int psize, int mode) make_pipe (int fildes[2], unsigned int psize, int mode)
{ {
@ -53,6 +107,7 @@ make_pipe (int fildes[2], unsigned int psize, int mode)
fildes[1] = fdw; fildes[1] = fdw;
res = 0; res = 0;
fhr->create_guard (sa);
} }
syscall_printf ("%d = make_pipe ([%d, %d], %d, %p)", res, fdr, fdw, psize, mode); syscall_printf ("%d = make_pipe ([%d, %d], %d, %p)", res, fdr, fdw, psize, mode);

View File

@ -123,14 +123,6 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
fd_set *dummy_exceptfds = allocfd_set (maxfds); fd_set *dummy_exceptfds = allocfd_set (maxfds);
sigframe thisframe (mainthread); sigframe thisframe (mainthread);
#if 0
if (n > FD_SETSIZE)
{
set_errno (EINVAL);
return -1;
}
#endif
select_printf ("%d, %p, %p, %p, %p", maxfds, readfds, writefds, exceptfds, to); select_printf ("%d, %p, %p, %p, %p", maxfds, readfds, writefds, exceptfds, to);
if (!readfds) if (!readfds)
@ -407,7 +399,7 @@ no_verify (select_record *, fd_set *, fd_set *, fd_set *)
} }
static int static int
peek_pipe (select_record *s, int ignra) peek_pipe (select_record *s, int ignra, HANDLE guard_mutex = NULL)
{ {
int n = 0; int n = 0;
int gotone = 0; int gotone = 0;
@ -454,8 +446,15 @@ peek_pipe (select_record *s, int ignra)
} }
} }
if (fh->get_device() != FH_PIPEW && if (fh->get_device () == FH_PIPEW)
!PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL)) /* nothing */;
else if (guard_mutex && WaitForSingleObject (guard_mutex, 0) != WAIT_OBJECT_0)
{
select_printf ("%s, couldn't get mutex %p, %E", fh->get_name (),
guard_mutex);
n = 0;
}
else if (!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;
@ -496,8 +495,20 @@ poll_pipe (select_record *me, fd_set *readfds, fd_set *writefds,
set_bits (me, readfds, writefds, exceptfds) : set_bits (me, readfds, writefds, exceptfds) :
0; 0;
} }
int
MAKEready(pipe) fhandler_pipe::ready_for_read (int fd, DWORD howlong, int ignra)
{
select_record me (this);
me.fd = fd;
(void) select_read (&me);
while (!peek_pipe (&me, ignra, guard) && howlong == INFINITE)
if (fd >= 0 && cygheap->fdtab.not_open (fd))
break;
else if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0)
break;
select_printf ("returning %d", me.read_ready);
return me.read_ready;
}
static int start_thread_pipe (select_record *me, select_stuff *stuff); static int start_thread_pipe (select_record *me, select_stuff *stuff);

View File

@ -819,7 +819,7 @@ subproc_init (void)
* the hchildren array. * the hchildren array.
*/ */
events[0] = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); events[0] = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
if (!(hwait_subproc = makethread (wait_subproc, NULL, 0, "+proc"))) if (!(hwait_subproc = makethread (wait_subproc, NULL, 0, "proc")))
system_printf ("cannot create wait_subproc thread, %E"); system_printf ("cannot create wait_subproc thread, %E");
ProtectHandle (events[0]); ProtectHandle (events[0]);
ProtectHandle (hwait_subproc); ProtectHandle (hwait_subproc);

View File

@ -295,7 +295,7 @@ _read (int fd, void *ptr, size_t len)
/* Could block, so let user know we at least got here. */ /* Could block, so let user know we at least got here. */
syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d", fd, ptr, len, wait ? "" : "non", sigcatchers); syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d", fd, ptr, len, wait ? "" : "non", sigcatchers);
if (wait && (!sigcatchers || !fh->is_slow () || fh->get_r_no_interrupt ())) if (wait && (/*!sigcatchers || */!fh->is_slow () || fh->get_r_no_interrupt ()))
debug_printf ("non-interruptible read\n"); debug_printf ("non-interruptible read\n");
else if (!fh->ready_for_read (fd, wait, 0)) else if (!fh->ready_for_read (fd, wait, 0))
{ {