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

View File

@ -849,8 +849,7 @@ setup_handler (int sig, void *handler, struct sigaction& siga)
if (th)
{
interrupted = interrupt_on_return (th, sig, handler, siga);
if (!interrupted)
LeaveCriticalSection (&th->lock);
LeaveCriticalSection (&th->lock);
}
else if (interruptible (cx.Eip))
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);
}
if (th)
LeaveCriticalSection (&th->lock);
if (!hth)
sigproc_printf ("good. Didn't suspend main thread, th %p", th);
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
the file.
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
existant directory. */
which returns a valid handle when trying to open a file in a nonexistent
directory. */
if (real_path.has_buggy_open ()
&& GetFileAttributes (win32_path_name) == (DWORD) -1)
{
@ -1493,23 +1493,6 @@ fhandler_dev_null::dump (void)
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
fhandler_base::set_inheritance (HANDLE &h, int not_inheriting)
{

View File

@ -435,17 +435,20 @@ public:
class fhandler_pipe: public fhandler_base
{
HANDLE guard;
public:
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
the can keep one end of the pipe open when it shouldn't be. */
BOOL is_slow () {return !wincap.has_unreliable_pipes ();}
select_record *select_read (select_record *s);
select_record *select_write (select_record *s);
select_record *select_except (select_record *s);
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

View File

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

View File

@ -19,6 +19,60 @@ details. */
#include "cygheap.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
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;
res = 0;
fhr->create_guard (sa);
}
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);
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);
if (!readfds)
@ -407,7 +399,7 @@ no_verify (select_record *, fd_set *, fd_set *, fd_set *)
}
static int
peek_pipe (select_record *s, int ignra)
peek_pipe (select_record *s, int ignra, HANDLE guard_mutex = NULL)
{
int n = 0;
int gotone = 0;
@ -454,8 +446,15 @@ peek_pipe (select_record *s, int ignra)
}
}
if (fh->get_device() != FH_PIPEW &&
!PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL))
if (fh->get_device () == FH_PIPEW)
/* 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 ());
n = -1;
@ -496,8 +495,20 @@ poll_pipe (select_record *me, fd_set *readfds, fd_set *writefds,
set_bits (me, readfds, writefds, exceptfds) :
0;
}
MAKEready(pipe)
int
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);

View File

@ -819,7 +819,7 @@ subproc_init (void)
* the hchildren array.
*/
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");
ProtectHandle (events[0]);
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. */
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");
else if (!fh->ready_for_read (fd, wait, 0))
{