Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2001-08-31 09:06:14 +0400
committerChristopher Faylor <me@cgf.cx>2001-08-31 09:06:14 +0400
commit5835f2cf8dfb01b93c233bfb5e486482a545aded (patch)
tree1384eb71caa42c16db5ae0ad966088417bed66fa
parent33bc82476eb92308590d03407cb1597eca8b0079 (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog31
-rw-r--r--winsup/cygwin/Makefile.in9
-rw-r--r--winsup/cygwin/autoload.cc2
-rw-r--r--winsup/cygwin/cygheap.cc47
-rw-r--r--winsup/cygwin/cygwin.sc110
-rw-r--r--winsup/cygwin/fhandler.h13
-rw-r--r--winsup/cygwin/net.cc14
-rw-r--r--winsup/cygwin/select.cc22
-rw-r--r--winsup/cygwin/sigproc.cc32
-rw-r--r--winsup/cygwin/winsup.h2
10 files changed, 236 insertions, 46 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 88bf06920..39e423619 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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.
diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in
index 317616bdc..5e2a5620e 100644
--- a/winsup/cygwin/Makefile.in
+++ b/winsup/cygwin/Makefile.in
@@ -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)
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 1cd0e7e12..336c4cb85 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -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 ()
{
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index 39e308217..dc2c72ed2 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -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);
}
diff --git a/winsup/cygwin/cygwin.sc b/winsup/cygwin/cygwin.sc
new file mode 100644
index 000000000..42fdffc98
--- /dev/null
+++ b/winsup/cygwin/cygwin.sc
@@ -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;
+ }
+}
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index dd1df2978..6fe6ffff0 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -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 ();
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc
index b9faa1bc9..7077220bc 100644
--- a/winsup/cygwin/net.cc
+++ b/winsup/cygwin/net.cc
@@ -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;
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index e72e63b68..94326dc41 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -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;
}
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 768d6f1fd..e6071e05d 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -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.
*/
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 1b73a2f52..32cecd0bf 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -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