* cygwin.sc: New file -- linker script for building cygwin DLL.
* Makefile.in: Use linker script to control location of cygheap. * cygheap.cc (buckets): Make static. (init_cheap): Remove special iswinnt handling. Allocate cygheap at a fixed location. Display more info when allocation fails. (cygheap_fixup_in_child): Try harder to move cygheap to correct location. Display more info when allocation fails. * fhandler.h (fhandler_socket): Add macros for tracking socket shutdown state. * net.cc (cygwin_shutdown): Set appropriate shutdown value for future use. * select.cc (select_stuff::cleanup): New method. (cygwin_select): Call cleanup explicitly to avoid a race. (select_stuff:~select_stuff): Call cleanup chain via cleanup method. (fhandler_socket::select_read): Set *_ready when shutdown has been called on the socket. (fhandler_socket::select_write): Ditto. (fhandler_socket::select_except): Ditto. * winsup.h: Move NO_COPY to "COMMON" section. * autoload.cc (wsock_started): Avoid initializing NO_COPY value. * sigproc.cc: Remove initialization from NO_COPY variables. (sigproc_init): Initialize sig_loop_wait here, rather than via initialization. (subproc_init): Initialize proc_loop_wait here, rather than via initialization.
This commit is contained in:
parent
33bc82476e
commit
5835f2cf8d
|
@ -1,3 +1,34 @@
|
||||||
|
Fri Aug 31 00:56:26 2001 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* cygwin.sc: New file -- linker script for building cygwin DLL.
|
||||||
|
* Makefile.in: Use linker script to control location of cygheap.
|
||||||
|
* cygheap.cc (buckets): Make static.
|
||||||
|
(init_cheap): Remove special iswinnt handling. Allocate cygheap at a
|
||||||
|
fixed location. Display more info when allocation fails.
|
||||||
|
(cygheap_fixup_in_child): Try harder to move cygheap to correct
|
||||||
|
location. Display more info when allocation fails.
|
||||||
|
* fhandler.h (fhandler_socket): Add macros for tracking socket shutdown
|
||||||
|
state.
|
||||||
|
* net.cc (cygwin_shutdown): Set appropriate shutdown value for future
|
||||||
|
use.
|
||||||
|
* select.cc (select_stuff::cleanup): New method.
|
||||||
|
(cygwin_select): Call cleanup explicitly to avoid a race.
|
||||||
|
(select_stuff:~select_stuff): Call cleanup chain via cleanup method.
|
||||||
|
(fhandler_socket::select_read): Set *_ready when shutdown has been
|
||||||
|
called on the socket.
|
||||||
|
(fhandler_socket::select_write): Ditto.
|
||||||
|
(fhandler_socket::select_except): Ditto.
|
||||||
|
|
||||||
|
* winsup.h: Move NO_COPY to "COMMON" section.
|
||||||
|
* autoload.cc (wsock_started): Avoid initializing NO_COPY value.
|
||||||
|
* sigproc.cc: Remove initialization from NO_COPY variables.
|
||||||
|
(sigproc_init): Initialize sig_loop_wait here, rather than via
|
||||||
|
initialization.
|
||||||
|
(subproc_init): Initialize proc_loop_wait here, rather than via
|
||||||
|
initialization.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Thu Aug 30 10:19:00 2001 Christopher Faylor <cgf@cygnus.com>
|
Thu Aug 30 10:19:00 2001 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
* select.cc (select_read): Add setting read_ready flag.
|
* select.cc (select_read): Add setting read_ready flag.
|
||||||
|
|
|
@ -65,6 +65,7 @@ LD:=@LD@
|
||||||
DLLTOOL:=@DLLTOOL@
|
DLLTOOL:=@DLLTOOL@
|
||||||
WINDRES:=@WINDRES@
|
WINDRES:=@WINDRES@
|
||||||
AS:=@AS@
|
AS:=@AS@
|
||||||
|
LDSCRIPT=cygwin.sc
|
||||||
|
|
||||||
#
|
#
|
||||||
# Include common definitions for winsup directory
|
# Include common definitions for winsup directory
|
||||||
|
@ -194,9 +195,11 @@ new-$(LIB_NAME): $(LIB_NAME)
|
||||||
|
|
||||||
# Rule to build cygwin.dll
|
# Rule to build cygwin.dll
|
||||||
|
|
||||||
new-$(DLL_NAME): $(DLL_OFILES) $(DEF_FILE) $(DLL_IMPORTS) $(LIBC) $(LIBM) Makefile winver_stamp
|
new-$(DLL_NAME): $(LDSCRIPT) $(DLL_OFILES) $(DEF_FILE) $(DLL_IMPORTS) $(LIBC) $(LIBM) Makefile winver_stamp
|
||||||
$(CXX) $(CXXFLAGS) -nostdlib -Wl,-shared -o $@ -e $(DLL_ENTRY) $(DEF_FILE) $(DLL_OFILES) version.o \
|
$(CXX) $(CXXFLAGS) -nostdlib -Wl,-T$(firstword $^) -shared -o $@ \
|
||||||
winver.o $(DLL_IMPORTS) $(MALLOC_OBJ) $(LIBM) $(LIBC) -lstdc++ -lgcc -lshell32 -luuid
|
-e $(DLL_ENTRY) $(DEF_FILE) $(DLL_OFILES) version.o winver.o \
|
||||||
|
$(DLL_IMPORTS) $(MALLOC_OBJ) $(LIBM) $(LIBC) \
|
||||||
|
-lstdc++ -lgcc -lshell32 -luuid
|
||||||
|
|
||||||
dll_ofiles: $(DLL_OFILES)
|
dll_ofiles: $(DLL_OFILES)
|
||||||
|
|
||||||
|
|
|
@ -236,7 +236,7 @@ std_dll_init ()
|
||||||
|
|
||||||
/* Initialization function for winsock stuff. */
|
/* Initialization function for winsock stuff. */
|
||||||
static long long wsock_init () __asm__ ("wsock_init") __attribute__ ((unused, regparm(1)));
|
static long long wsock_init () __asm__ ("wsock_init") __attribute__ ((unused, regparm(1)));
|
||||||
bool NO_COPY wsock_started = 0;
|
bool NO_COPY wsock_started;
|
||||||
static long long
|
static long long
|
||||||
wsock_init ()
|
wsock_init ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,7 +36,7 @@ struct cygheap_entry
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NBUCKETS 32
|
#define NBUCKETS 32
|
||||||
char *buckets[NBUCKETS] = {0};
|
static char *buckets[NBUCKETS] = {0};
|
||||||
|
|
||||||
#define N0 ((_cmalloc_entry *) NULL)
|
#define N0 ((_cmalloc_entry *) NULL)
|
||||||
#define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (int) (N0->data)))
|
#define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (int) (N0->data)))
|
||||||
|
@ -46,29 +46,22 @@ char *buckets[NBUCKETS] = {0};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static void __stdcall _cfree (void *ptr) __attribute__((regparm(1)));
|
static void __stdcall _cfree (void *ptr) __attribute__((regparm(1)));
|
||||||
|
extern void *_cygheap_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static void
|
inline static void
|
||||||
init_cheap ()
|
init_cheap ()
|
||||||
{
|
{
|
||||||
if (!iswinnt)
|
cygheap = (init_cygheap *) VirtualAlloc ((void *) &_cygheap_start, CYGHEAPSIZE, MEM_RESERVE, PAGE_NOACCESS);
|
||||||
{
|
|
||||||
cygheap = (init_cygheap *) VirtualAlloc (NULL, CYGHEAPSIZE, MEM_RESERVE, PAGE_NOACCESS);
|
|
||||||
if (!cygheap)
|
if (!cygheap)
|
||||||
|
{
|
||||||
|
MEMORY_BASIC_INFORMATION m;
|
||||||
|
if (!VirtualQuery ((LPCVOID) &_cygheap_start, &m, sizeof m))
|
||||||
|
system_printf ("couldn't get memory info, %E");
|
||||||
|
small_printf ("AllocationBase %p, BaseAddress %p, RegionSize %p, State %p\n",
|
||||||
|
m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
|
||||||
api_fatal ("Couldn't reserve space for cygwin's heap, %E");
|
api_fatal ("Couldn't reserve space for cygwin's heap, %E");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
HANDLE h;
|
|
||||||
h = CreateFileMapping (INVALID_HANDLE_VALUE, &sec_none, PAGE_READWRITE,
|
|
||||||
0, CYGHEAPSIZE, NULL);
|
|
||||||
if (!h)
|
|
||||||
api_fatal ("CreateFileMapping failed, %E");
|
|
||||||
cygheap = (init_cygheap *) MapViewOfFile (h, FILE_MAP_WRITE, 0, 0, 0);
|
|
||||||
if (!cygheap)
|
|
||||||
api_fatal ("Couldn't allocate shared memory for cygwin heap, %E");
|
|
||||||
CloseHandle (h);
|
|
||||||
}
|
|
||||||
cygheap_max = cygheap + 1;
|
cygheap_max = cygheap + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,13 +99,25 @@ cygheap_fixup_in_child (child_info *ci, bool execed)
|
||||||
cygheap_max = ci->cygheap_max;
|
cygheap_max = ci->cygheap_max;
|
||||||
void *addr = iswinnt ? cygheap : NULL;
|
void *addr = iswinnt ? cygheap : NULL;
|
||||||
void *newaddr;
|
void *newaddr;
|
||||||
|
|
||||||
newaddr = MapViewOfFileEx (ci->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, addr);
|
newaddr = MapViewOfFileEx (ci->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, addr);
|
||||||
if (!iswinnt || newaddr != addr)
|
if (newaddr != cygheap)
|
||||||
{
|
{
|
||||||
|
if (!newaddr)
|
||||||
|
newaddr = MapViewOfFileEx (ci->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, NULL);
|
||||||
DWORD n = (DWORD) cygheap_max - (DWORD) cygheap;
|
DWORD n = (DWORD) cygheap_max - (DWORD) cygheap;
|
||||||
/* Reserve cygwin heap in same spot as parent */
|
/* Reserve cygwin heap in same spot as parent */
|
||||||
if (!VirtualAlloc (cygheap, CYGHEAPSIZE, MEM_RESERVE, PAGE_NOACCESS))
|
if (!VirtualAlloc (cygheap, CYGHEAPSIZE, MEM_RESERVE, PAGE_NOACCESS))
|
||||||
|
{
|
||||||
|
MEMORY_BASIC_INFORMATION m;
|
||||||
|
memset (&m, 0, sizeof m);
|
||||||
|
if (!VirtualQuery ((LPCVOID) cygheap, &m, sizeof m))
|
||||||
|
system_printf ("couldn't get memory info, %E");
|
||||||
|
|
||||||
|
small_printf ("m.AllocationBase %p, m.BaseAddress %p, m.RegionSize %p, m.State %p\n",
|
||||||
|
m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
|
||||||
api_fatal ("Couldn't reserve space for cygwin's heap (%p <%p>) in child, %E", cygheap, newaddr);
|
api_fatal ("Couldn't reserve space for cygwin's heap (%p <%p>) in child, %E", cygheap, newaddr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate same amount of memory as parent */
|
/* Allocate same amount of memory as parent */
|
||||||
if (!VirtualAlloc (cygheap, n, MEM_COMMIT, PAGE_READWRITE))
|
if (!VirtualAlloc (cygheap, n, MEM_COMMIT, PAGE_READWRITE))
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
OUTPUT_FORMAT(pei-i386)
|
||||||
|
SEARCH_DIR(/cygnus/i686-pc-cygwin/lib/w32api); SEARCH_DIR(/cygnus/i686-pc-cygwin/lib);
|
||||||
|
ENTRY(_mainCRTStartup)
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text __image_base__ + __section_alignment__ :
|
||||||
|
{
|
||||||
|
*(.init)
|
||||||
|
*(.text)
|
||||||
|
*(SORT(.text$*))
|
||||||
|
*(.glue_7t)
|
||||||
|
*(.glue_7)
|
||||||
|
___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
|
||||||
|
LONG (-1); *(.ctors); *(.ctor); LONG (0);
|
||||||
|
___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
|
||||||
|
LONG (-1); *(.dtors); *(.dtor); LONG (0);
|
||||||
|
*(.fini)
|
||||||
|
/* ??? Why is .gcc_exc here? */
|
||||||
|
*(.gcc_exc)
|
||||||
|
etext = .;
|
||||||
|
*(.gcc_except_table)
|
||||||
|
}
|
||||||
|
/* The Cygwin32 library uses a section to avoid copying certain data
|
||||||
|
on fork. This used to be named ".data". The linker used
|
||||||
|
to include this between __data_start__ and __data_end__, but that
|
||||||
|
breaks building the cygwin32 dll. Instead, we name the section
|
||||||
|
".data_cygwin_nocopy" and explictly include it after __data_end__. */
|
||||||
|
.data BLOCK(__section_alignment__) :
|
||||||
|
{
|
||||||
|
__data_start__ = . ;
|
||||||
|
*(.data)
|
||||||
|
*(.data2)
|
||||||
|
*(SORT(.data$*))
|
||||||
|
__data_end__ = . ;
|
||||||
|
*(COMMON)
|
||||||
|
}
|
||||||
|
.rdata BLOCK(__section_alignment__) :
|
||||||
|
{
|
||||||
|
*(.rdata)
|
||||||
|
*(SORT(.rdata$*))
|
||||||
|
*(.eh_frame)
|
||||||
|
}
|
||||||
|
.pdata BLOCK(__section_alignment__) :
|
||||||
|
{
|
||||||
|
*(.pdata)
|
||||||
|
}
|
||||||
|
.bss BLOCK(__section_alignment__) :
|
||||||
|
{
|
||||||
|
__bss_start__ = . ;
|
||||||
|
*(.bss)
|
||||||
|
__bss_end__ = . ;
|
||||||
|
}
|
||||||
|
.edata BLOCK(__section_alignment__) :
|
||||||
|
{
|
||||||
|
*(.edata)
|
||||||
|
}
|
||||||
|
/DISCARD/ :
|
||||||
|
{
|
||||||
|
*(.debug$S)
|
||||||
|
*(.debug$T)
|
||||||
|
*(.debug$F)
|
||||||
|
*(.drectve)
|
||||||
|
}
|
||||||
|
.idata BLOCK(__section_alignment__) :
|
||||||
|
{
|
||||||
|
/* This cannot currently be handled with grouped sections.
|
||||||
|
See pe.em:sort_sections. */
|
||||||
|
SORT(*)(.idata$2)
|
||||||
|
SORT(*)(.idata$3)
|
||||||
|
/* These zeroes mark the end of the import list. */
|
||||||
|
LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
|
||||||
|
SORT(*)(.idata$4)
|
||||||
|
SORT(*)(.idata$5)
|
||||||
|
SORT(*)(.idata$6)
|
||||||
|
SORT(*)(.idata$7)
|
||||||
|
}
|
||||||
|
.CRT BLOCK(__section_alignment__) :
|
||||||
|
{
|
||||||
|
*(SORT(.CRT$*))
|
||||||
|
}
|
||||||
|
.endjunk BLOCK(__section_alignment__) :
|
||||||
|
{
|
||||||
|
/* end is deprecated, don't use it */
|
||||||
|
end = .;
|
||||||
|
_end = .;
|
||||||
|
__end__ = .;
|
||||||
|
}
|
||||||
|
.rsrc BLOCK(__section_alignment__) :
|
||||||
|
{
|
||||||
|
*(.rsrc)
|
||||||
|
*(SORT(.rsrc$*))
|
||||||
|
}
|
||||||
|
.reloc BLOCK(__section_alignment__) :
|
||||||
|
{
|
||||||
|
*(.reloc)
|
||||||
|
}
|
||||||
|
.stab BLOCK(__section_alignment__) (NOLOAD) :
|
||||||
|
{
|
||||||
|
[ .stab ]
|
||||||
|
}
|
||||||
|
.stabstr BLOCK(__section_alignment__) (NOLOAD) :
|
||||||
|
{
|
||||||
|
[ .stabstr ]
|
||||||
|
}
|
||||||
|
.cygheap BLOCK(64 * 1024) :
|
||||||
|
{
|
||||||
|
__cygheap_start = ABSOLUTE(.) ;
|
||||||
|
__system_dlls__ = ABSOLUTE(.) + 4;
|
||||||
|
}
|
||||||
|
}
|
|
@ -70,7 +70,8 @@ enum
|
||||||
FH_NOEINTR = 0x01000000, /* Set if I/O should be uninterruptible. */
|
FH_NOEINTR = 0x01000000, /* Set if I/O should be uninterruptible. */
|
||||||
FH_FFIXUP = 0x02000000, /* Set if need to fixup after fork. */
|
FH_FFIXUP = 0x02000000, /* Set if need to fixup after fork. */
|
||||||
FH_LOCAL = 0x04000000, /* File is unix domain socket */
|
FH_LOCAL = 0x04000000, /* File is unix domain socket */
|
||||||
FH_FIFO = 0x08000000, /* File is FIFO */
|
FH_SHUTRD = 0x08000000, /* Socket saw a SHUT_RD */
|
||||||
|
FH_SHUTWR = 0x10000000, /* Socket saw a SHUT_WR */
|
||||||
FH_ISREMOTE = 0x10000000, /* File is on a remote drive */
|
FH_ISREMOTE = 0x10000000, /* File is on a remote drive */
|
||||||
FH_DCEXEC = 0x20000000, /* Don't care if this is executable */
|
FH_DCEXEC = 0x20000000, /* Don't care if this is executable */
|
||||||
FH_HASACLS = 0x40000000, /* True if fs of file has ACLS */
|
FH_HASACLS = 0x40000000, /* True if fs of file has ACLS */
|
||||||
|
@ -157,7 +158,7 @@ enum executable_states
|
||||||
|
|
||||||
class fhandler_base
|
class fhandler_base
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
DWORD status;
|
DWORD status;
|
||||||
public:
|
public:
|
||||||
int cb;
|
int cb;
|
||||||
|
@ -398,6 +399,13 @@ public:
|
||||||
~fhandler_socket ();
|
~fhandler_socket ();
|
||||||
int get_socket () { return (int) get_handle(); }
|
int get_socket () { return (int) get_handle(); }
|
||||||
fhandler_socket * is_socket () { return this; }
|
fhandler_socket * is_socket () { return this; }
|
||||||
|
|
||||||
|
int saw_shutdown_read () const {return FHISSETF (SHUTRD);}
|
||||||
|
int saw_shutdown_write () const {return FHISSETF (SHUTWR);}
|
||||||
|
|
||||||
|
void set_shutdown_read () {FHSETF (SHUTRD);}
|
||||||
|
void set_shutdown_write () {FHSETF (SHUTWR);}
|
||||||
|
|
||||||
int write (const void *ptr, size_t len);
|
int write (const void *ptr, size_t len);
|
||||||
int read (void *ptr, size_t len);
|
int read (void *ptr, size_t len);
|
||||||
int ioctl (unsigned int cmd, void *);
|
int ioctl (unsigned int cmd, void *);
|
||||||
|
@ -1066,6 +1074,7 @@ public:
|
||||||
fd_set *exceptfds);
|
fd_set *exceptfds);
|
||||||
int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
|
int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
|
||||||
int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
|
int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
|
||||||
|
void cleanup ();
|
||||||
};
|
};
|
||||||
|
|
||||||
int __stdcall set_console_state_for_spawn ();
|
int __stdcall set_console_state_for_spawn ();
|
||||||
|
|
|
@ -1349,6 +1349,20 @@ cygwin_shutdown (int fd, int how)
|
||||||
res = shutdown (sock->get_socket (), how);
|
res = shutdown (sock->get_socket (), how);
|
||||||
if (res)
|
if (res)
|
||||||
set_winsock_errno ();
|
set_winsock_errno ();
|
||||||
|
else
|
||||||
|
switch (how)
|
||||||
|
{
|
||||||
|
case SHUT_RD:
|
||||||
|
sock->set_shutdown_read ();
|
||||||
|
break;
|
||||||
|
case SHUT_WR:
|
||||||
|
sock->set_shutdown_write ();
|
||||||
|
break;
|
||||||
|
case SHUT_RDWR:
|
||||||
|
sock->set_shutdown_read ();
|
||||||
|
sock->set_shutdown_write ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
syscall_printf ("%d = shutdown (%d, %d)", res, fd, how);
|
syscall_printf ("%d = shutdown (%d, %d)", res, fd, how);
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -181,22 +181,34 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||||
else if ((timeout = sel.wait (r, w, e, ms) < 0))
|
else if ((timeout = sel.wait (r, w, e, ms) < 0))
|
||||||
return -1; /* some kind of error */
|
return -1; /* some kind of error */
|
||||||
|
|
||||||
|
sel.cleanup ();
|
||||||
copyfd_set (readfds, r, maxfds);
|
copyfd_set (readfds, r, maxfds);
|
||||||
copyfd_set (writefds, w, maxfds);
|
copyfd_set (writefds, w, maxfds);
|
||||||
copyfd_set (exceptfds, e, maxfds);
|
copyfd_set (exceptfds, e, maxfds);
|
||||||
return timeout ? 0 : sel.poll (readfds, writefds, exceptfds);
|
return timeout ? 0 : sel.poll (readfds, writefds, exceptfds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup */
|
/* Call cleanup functions for all inspected fds. Gets rid of any
|
||||||
select_stuff::~select_stuff ()
|
executing threads. */
|
||||||
|
void
|
||||||
|
select_stuff::cleanup ()
|
||||||
{
|
{
|
||||||
select_record *s = &start;
|
select_record *s = &start;
|
||||||
|
|
||||||
select_printf ("calling cleanup routines");
|
select_printf ("calling cleanup routines");
|
||||||
while ((s = s->next))
|
while ((s = s->next))
|
||||||
if (s->cleanup)
|
if (s->cleanup)
|
||||||
|
{
|
||||||
s->cleanup (s, this);
|
s->cleanup (s, this);
|
||||||
|
s->cleanup = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Destroy all storage associated with select stuff. */
|
||||||
|
select_stuff::~select_stuff ()
|
||||||
|
{
|
||||||
|
cleanup ();
|
||||||
|
select_record *s = &start;
|
||||||
select_record *snext = start.next;
|
select_record *snext = start.next;
|
||||||
|
|
||||||
select_printf ("deleting select records");
|
select_printf ("deleting select records");
|
||||||
|
@ -1375,6 +1387,7 @@ fhandler_socket::select_read (select_record *s)
|
||||||
s->verify = verify_true;
|
s->verify = verify_true;
|
||||||
s->cleanup = socket_cleanup;
|
s->cleanup = socket_cleanup;
|
||||||
}
|
}
|
||||||
|
s->read_ready = saw_shutdown_read ();
|
||||||
s->read_selected = TRUE;
|
s->read_selected = TRUE;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -1390,6 +1403,7 @@ fhandler_socket::select_write (select_record *s)
|
||||||
s->verify = verify_true;
|
s->verify = verify_true;
|
||||||
s->cleanup = socket_cleanup;
|
s->cleanup = socket_cleanup;
|
||||||
}
|
}
|
||||||
|
s->write_ready = saw_shutdown_write ();
|
||||||
s->write_selected = TRUE;
|
s->write_selected = TRUE;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -1405,6 +1419,8 @@ fhandler_socket::select_except (select_record *s)
|
||||||
s->verify = verify_true;
|
s->verify = verify_true;
|
||||||
s->cleanup = socket_cleanup;
|
s->cleanup = socket_cleanup;
|
||||||
}
|
}
|
||||||
|
/* FIXME: Is this right? Should these be used as criteria for except? */
|
||||||
|
s->except_ready = saw_shutdown_write () || saw_shutdown_read ();
|
||||||
s->except_selected = TRUE;
|
s->except_selected = TRUE;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,46 +74,46 @@ HANDLE NO_COPY signal_arrived; // Event signaled when a signal has
|
||||||
|
|
||||||
#define Static static NO_COPY
|
#define Static static NO_COPY
|
||||||
|
|
||||||
Static DWORD proc_loop_wait = 1000; // Wait for subprocesses to exit
|
Static DWORD proc_loop_wait; // Wait for subprocesses to exit
|
||||||
Static DWORD sig_loop_wait = INFINITE; // Wait for signals to arrive
|
Static DWORD sig_loop_wait; // Wait for signals to arrive
|
||||||
|
|
||||||
Static HANDLE sigcatch_nonmain = NULL; // The semaphore signaled when
|
Static HANDLE sigcatch_nonmain; // The semaphore signaled when
|
||||||
// signals are available for
|
// signals are available for
|
||||||
// processing from non-main thread
|
// processing from non-main thread
|
||||||
Static HANDLE sigcatch_main = NULL; // Signalled when main thread sends a
|
Static HANDLE sigcatch_main; // Signalled when main thread sends a
|
||||||
// signal
|
// signal
|
||||||
Static HANDLE sigcatch_nosync = NULL; // Signal wait_sig to scan sigtodo
|
Static HANDLE sigcatch_nosync; // Signal wait_sig to scan sigtodo
|
||||||
// but not to bother with any
|
// but not to bother with any
|
||||||
// synchronization
|
// synchronization
|
||||||
Static HANDLE sigcomplete_main = NULL; // Event signaled when a signal has
|
Static HANDLE sigcomplete_main; // Event signaled when a signal has
|
||||||
// finished processing for the main
|
// finished processing for the main
|
||||||
// thread
|
// thread
|
||||||
Static HANDLE sigcomplete_nonmain = NULL;// Semaphore raised for non-main
|
Static HANDLE sigcomplete_nonmain; // Semaphore raised for non-main
|
||||||
// threads when a signal has finished
|
// threads when a signal has finished
|
||||||
// processing
|
// processing
|
||||||
Static HANDLE hwait_sig = NULL; // Handle of wait_sig thread
|
Static HANDLE hwait_sig; // Handle of wait_sig thread
|
||||||
Static HANDLE hwait_subproc = NULL; // Handle of sig_subproc thread
|
Static HANDLE hwait_subproc; // Handle of sig_subproc thread
|
||||||
|
|
||||||
Static HANDLE wait_sig_inited = NULL; // Control synchronization of
|
Static HANDLE wait_sig_inited; // Control synchronization of
|
||||||
// message queue startup
|
// message queue startup
|
||||||
|
|
||||||
/* Used by WaitForMultipleObjects. These are handles to child processes.
|
/* Used by WaitForMultipleObjects. These are handles to child processes.
|
||||||
*/
|
*/
|
||||||
Static HANDLE events[PSIZE + 1] = {0}; // All my children's handles++
|
Static HANDLE events[PSIZE + 1]; // All my children's handles++
|
||||||
#define hchildren (events + 1) // Where the children handles begin
|
#define hchildren (events + 1) // Where the children handles begin
|
||||||
Static pinfo pchildren[PSIZE]; // All my children info
|
Static pinfo pchildren[PSIZE]; // All my children info
|
||||||
Static pinfo zombies[16384]; // All my deceased children info
|
Static pinfo zombies[16384]; // All my deceased children info
|
||||||
Static int nchildren = 0; // Number of active children
|
Static int nchildren = 0; // Number of active children
|
||||||
Static int nzombies = 0; // Number of deceased children
|
Static int nzombies = 0; // Number of deceased children
|
||||||
|
|
||||||
Static waitq waitq_head = {0, 0, 0, 0, 0, 0, 0};// Start of queue for wait'ing threads
|
Static waitq waitq_head; // Start of queue for wait'ing threads
|
||||||
Static waitq waitq_main; // Storage for main thread
|
Static waitq waitq_main; // Storage for main thread
|
||||||
|
|
||||||
muto NO_COPY *sync_proc_subproc = NULL; // Control access to subproc stuff
|
muto NO_COPY *sync_proc_subproc; // Control access to subproc stuff
|
||||||
|
|
||||||
DWORD NO_COPY sigtid = 0; // ID of the signal thread
|
DWORD NO_COPY sigtid; // ID of the signal thread
|
||||||
|
|
||||||
int NO_COPY pending_signals = 0; // TRUE if signals pending
|
int NO_COPY pending_signals; // TRUE if signals pending
|
||||||
|
|
||||||
/* Functions
|
/* Functions
|
||||||
*/
|
*/
|
||||||
|
@ -543,6 +543,7 @@ sig_dispatch_pending (int justwake)
|
||||||
void __stdcall
|
void __stdcall
|
||||||
sigproc_init ()
|
sigproc_init ()
|
||||||
{
|
{
|
||||||
|
sig_loop_wait = INFINITE;
|
||||||
wait_sig_inited = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
wait_sig_inited = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||||
ProtectHandle (wait_sig_inited);
|
ProtectHandle (wait_sig_inited);
|
||||||
|
|
||||||
|
@ -814,6 +815,7 @@ subproc_init (void)
|
||||||
if (hwait_subproc)
|
if (hwait_subproc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
proc_loop_wait = 1000;
|
||||||
/* A "wakeup" handle which can be toggled to make wait_subproc reexamine
|
/* A "wakeup" handle which can be toggled to make wait_subproc reexamine
|
||||||
* the hchildren array.
|
* the hchildren array.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,7 +24,7 @@ details. */
|
||||||
# define memset __builtin_memset
|
# define memset __builtin_memset
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NO_COPY __attribute__((section(".data_cygwin_nocopy")))
|
#define NO_COPY __attribute__((section("COMMON")))
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue