* 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>
|
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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue