* 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:
parent
142920f65a
commit
5e733918c0
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue