* 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:
		@@ -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>
 | 
			
		||||
 | 
			
		||||
	* select.cc (select_read): Add setting read_ready flag.
 | 
			
		||||
 
 | 
			
		||||
@@ -65,6 +65,7 @@ LD:=@LD@
 | 
			
		||||
DLLTOOL:=@DLLTOOL@
 | 
			
		||||
WINDRES:=@WINDRES@
 | 
			
		||||
AS:=@AS@
 | 
			
		||||
LDSCRIPT=cygwin.sc
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Include common definitions for winsup directory
 | 
			
		||||
@@ -194,9 +195,11 @@ new-$(LIB_NAME): $(LIB_NAME)
 | 
			
		||||
 | 
			
		||||
# Rule to build cygwin.dll
 | 
			
		||||
 | 
			
		||||
new-$(DLL_NAME): $(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 \
 | 
			
		||||
	winver.o $(DLL_IMPORTS) $(MALLOC_OBJ) $(LIBM) $(LIBC) -lstdc++ -lgcc -lshell32 -luuid
 | 
			
		||||
new-$(DLL_NAME): $(LDSCRIPT) $(DLL_OFILES) $(DEF_FILE) $(DLL_IMPORTS) $(LIBC) $(LIBM) Makefile winver_stamp
 | 
			
		||||
	$(CXX) $(CXXFLAGS) -nostdlib -Wl,-T$(firstword $^) -shared -o $@ \
 | 
			
		||||
	-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)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -236,7 +236,7 @@ std_dll_init ()
 | 
			
		||||
 | 
			
		||||
/* Initialization function for winsock stuff. */
 | 
			
		||||
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
 | 
			
		||||
wsock_init ()
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@ struct cygheap_entry
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
#define NBUCKETS 32
 | 
			
		||||
char *buckets[NBUCKETS] = {0};
 | 
			
		||||
static char *buckets[NBUCKETS] = {0};
 | 
			
		||||
 | 
			
		||||
#define N0 ((_cmalloc_entry *) NULL)
 | 
			
		||||
#define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (int) (N0->data)))
 | 
			
		||||
@@ -46,28 +46,21 @@ char *buckets[NBUCKETS] = {0};
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
static void __stdcall _cfree (void *ptr) __attribute__((regparm(1)));
 | 
			
		||||
extern void *_cygheap_start;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline static void
 | 
			
		||||
init_cheap ()
 | 
			
		||||
{
 | 
			
		||||
  if (!iswinnt)
 | 
			
		||||
  cygheap = (init_cygheap *) VirtualAlloc ((void *) &_cygheap_start, CYGHEAPSIZE, MEM_RESERVE, PAGE_NOACCESS);
 | 
			
		||||
  if (!cygheap)
 | 
			
		||||
    {
 | 
			
		||||
      cygheap = (init_cygheap *) VirtualAlloc (NULL, CYGHEAPSIZE, MEM_RESERVE, PAGE_NOACCESS);
 | 
			
		||||
      if (!cygheap)
 | 
			
		||||
	    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);
 | 
			
		||||
      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");
 | 
			
		||||
    }
 | 
			
		||||
  cygheap_max = cygheap + 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -106,18 +99,30 @@ cygheap_fixup_in_child (child_info *ci, bool execed)
 | 
			
		||||
  cygheap_max = ci->cygheap_max;
 | 
			
		||||
  void *addr = iswinnt ? cygheap : NULL;
 | 
			
		||||
  void *newaddr;
 | 
			
		||||
 | 
			
		||||
  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;
 | 
			
		||||
      /* Reserve cygwin heap in same spot as parent */
 | 
			
		||||
      if (!VirtualAlloc (cygheap, CYGHEAPSIZE, MEM_RESERVE, PAGE_NOACCESS))
 | 
			
		||||
	    api_fatal ("Couldn't reserve space for cygwin's heap (%p <%p>) in child, %E", cygheap, newaddr);
 | 
			
		||||
      {
 | 
			
		||||
	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);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /* Allocate same amount of memory as parent */
 | 
			
		||||
      if (!VirtualAlloc (cygheap, n, MEM_COMMIT, PAGE_READWRITE))
 | 
			
		||||
	    api_fatal ("Couldn't allocate space for child's heap %p, size %d, %E",
 | 
			
		||||
			       cygheap, n);
 | 
			
		||||
	api_fatal ("Couldn't allocate space for child's heap %p, size %d, %E",
 | 
			
		||||
		   cygheap, n);
 | 
			
		||||
      memcpy (cygheap, newaddr, n);
 | 
			
		||||
      UnmapViewOfFile (newaddr);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										110
									
								
								winsup/cygwin/cygwin.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								winsup/cygwin/cygwin.sc
									
									
									
									
									
										Normal file
									
								
							@@ -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_FFIXUP	= 0x02000000,	/* Set if need to fixup after fork. */
 | 
			
		||||
  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_DCEXEC	= 0x20000000,	/* Don't care if this is executable */
 | 
			
		||||
  FH_HASACLS	= 0x40000000,	/* True if fs of file has ACLS */
 | 
			
		||||
@@ -157,7 +158,7 @@ enum executable_states
 | 
			
		||||
 | 
			
		||||
class fhandler_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
protected:
 | 
			
		||||
  DWORD status;
 | 
			
		||||
public:
 | 
			
		||||
  int cb;
 | 
			
		||||
@@ -398,6 +399,13 @@ public:
 | 
			
		||||
  ~fhandler_socket ();
 | 
			
		||||
  int get_socket () { return (int) get_handle(); }
 | 
			
		||||
  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 read (void *ptr, size_t len);
 | 
			
		||||
  int ioctl (unsigned int cmd, void *);
 | 
			
		||||
@@ -1066,6 +1074,7 @@ public:
 | 
			
		||||
		     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);
 | 
			
		||||
  void cleanup ();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int __stdcall set_console_state_for_spawn ();
 | 
			
		||||
 
 | 
			
		||||
@@ -1349,6 +1349,20 @@ cygwin_shutdown (int fd, int how)
 | 
			
		||||
      res = shutdown (sock->get_socket (), how);
 | 
			
		||||
      if (res)
 | 
			
		||||
	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);
 | 
			
		||||
  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))
 | 
			
		||||
    return -1;	/* some kind of error */
 | 
			
		||||
 | 
			
		||||
  sel.cleanup ();
 | 
			
		||||
  copyfd_set (readfds, r, maxfds);
 | 
			
		||||
  copyfd_set (writefds, w, maxfds);
 | 
			
		||||
  copyfd_set (exceptfds, e, maxfds);
 | 
			
		||||
  return timeout ? 0 : sel.poll (readfds, writefds, exceptfds);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Cleanup */
 | 
			
		||||
select_stuff::~select_stuff ()
 | 
			
		||||
/* Call cleanup functions for all inspected fds.  Gets rid of any
 | 
			
		||||
   executing threads. */
 | 
			
		||||
void
 | 
			
		||||
select_stuff::cleanup ()
 | 
			
		||||
{
 | 
			
		||||
  select_record *s = &start;
 | 
			
		||||
 | 
			
		||||
  select_printf ("calling cleanup routines");
 | 
			
		||||
  while ((s = s->next))
 | 
			
		||||
    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_printf ("deleting select records");
 | 
			
		||||
@@ -1375,6 +1387,7 @@ fhandler_socket::select_read (select_record *s)
 | 
			
		||||
      s->verify = verify_true;
 | 
			
		||||
      s->cleanup = socket_cleanup;
 | 
			
		||||
    }
 | 
			
		||||
  s->read_ready = saw_shutdown_read ();
 | 
			
		||||
  s->read_selected = TRUE;
 | 
			
		||||
  return s;
 | 
			
		||||
}
 | 
			
		||||
@@ -1390,6 +1403,7 @@ fhandler_socket::select_write (select_record *s)
 | 
			
		||||
      s->verify = verify_true;
 | 
			
		||||
      s->cleanup = socket_cleanup;
 | 
			
		||||
    }
 | 
			
		||||
  s->write_ready = saw_shutdown_write ();
 | 
			
		||||
  s->write_selected = TRUE;
 | 
			
		||||
  return s;
 | 
			
		||||
}
 | 
			
		||||
@@ -1405,6 +1419,8 @@ fhandler_socket::select_except (select_record *s)
 | 
			
		||||
      s->verify = verify_true;
 | 
			
		||||
      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;
 | 
			
		||||
  return s;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -74,46 +74,46 @@ HANDLE NO_COPY signal_arrived;		// Event signaled when a signal has
 | 
			
		||||
 | 
			
		||||
#define Static static NO_COPY
 | 
			
		||||
 | 
			
		||||
Static DWORD proc_loop_wait = 1000;	// Wait for subprocesses to exit
 | 
			
		||||
Static DWORD sig_loop_wait = INFINITE;	// Wait for signals to arrive
 | 
			
		||||
Static DWORD proc_loop_wait;		// Wait for subprocesses to exit
 | 
			
		||||
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
 | 
			
		||||
					//  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
 | 
			
		||||
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
 | 
			
		||||
					//  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
 | 
			
		||||
					//  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
 | 
			
		||||
					//  processing
 | 
			
		||||
Static HANDLE hwait_sig = NULL;		// Handle of wait_sig thread
 | 
			
		||||
Static HANDLE hwait_subproc = NULL;	// Handle of sig_subproc thread
 | 
			
		||||
Static HANDLE hwait_sig;		// Handle of wait_sig 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
 | 
			
		||||
 | 
			
		||||
/* 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
 | 
			
		||||
Static pinfo pchildren[PSIZE];		// All my children info
 | 
			
		||||
Static pinfo zombies[16384];		// All my deceased children info
 | 
			
		||||
Static int nchildren = 0;		// Number of active 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
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 */
 | 
			
		||||
@@ -543,6 +543,7 @@ sig_dispatch_pending (int justwake)
 | 
			
		||||
void __stdcall
 | 
			
		||||
sigproc_init ()
 | 
			
		||||
{
 | 
			
		||||
  sig_loop_wait = INFINITE;
 | 
			
		||||
  wait_sig_inited = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
 | 
			
		||||
  ProtectHandle (wait_sig_inited);
 | 
			
		||||
 | 
			
		||||
@@ -814,6 +815,7 @@ subproc_init (void)
 | 
			
		||||
  if (hwait_subproc)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  proc_loop_wait = 1000;
 | 
			
		||||
  /* A "wakeup" handle which can be toggled to make wait_subproc reexamine
 | 
			
		||||
   * the hchildren array.
 | 
			
		||||
   */
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ details. */
 | 
			
		||||
# define memset __builtin_memset
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define NO_COPY __attribute__((section(".data_cygwin_nocopy")))
 | 
			
		||||
#define NO_COPY __attribute__((section("COMMON")))
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user