diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2006-07-25 23:23:23 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2006-07-25 23:23:23 +0400 |
commit | 70e476d27be8e49146c49e8d6e1319100b84d5eb (patch) | |
tree | 1827e4d9dec3e1eb523db1df6a53e64c1c234518 /winsup/cygwin/select.cc | |
parent | e9d500b6a04e842ffaf04fd1cb6048b44fb99e67 (diff) |
2006-07-25 Corinna Vinschen <corinna@vinschen.de>
* include/cygwin/version.h: Bump DLL version to 1.7.0.
2006-07-25 Corinna Vinschen <corinna@vinschen.de>
* select.h: Remove.
* fhandler_socket.cc: Don't include select.h.
* select.cc: Ditto.
2006-07-25 Corinna Vinschen <corinna@vinschen.de>
* cygtls.h: Drop socket related includes.
(struct _local_storage): Remove exitsock and exitsock_sin. Add
select_sockevt.
* cygtls.cc: Accomodate above change throughout.
* fhandler.h (class fhandler_socket): Make wsock_evt public.
* fhandler_socket.cc (fhandler_socket::fhandler_socket): Accomodate
reordering members.
(fhandler_socket::evaluate_events): Drop FD_CONNECT event as soon as
it gets read once. Never remove FD_WRITE event here.
(fhandler_socket::wait_for_events): Wait 50 ms instead of INFINITE for
socket events.
(fhandler_socket::accept): Fix conditional. Set wsock_events members
of accepted socket to useful start values.
(fhandler_socket::recv_internal): Always drop FD_READ/FD_OOB events from
wsock_events after the call to WSARecvFrom.
(fhandler_socket::send_internal): Drop FD_WRITE event from wsock_events
if the call to WSASendTo fails with WSAEWOULDBLOCK. Fix return value
condition.
* select.cc (struct socketinf): Change to accomodate using socket event
handling.
(peek_socket): Use event handling for peeking socket.
(thread_socket): Ditto.
(start_thread_socket): Ditto.
(socket_cleanup): Same here.
* tlsoffsets.h: Regenerate.
2006-07-20 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (class fhandler_socket): Rearrange slightly to keep
event handling methods and members together. Drop owner status flag.
Split wait method. Rename event handling methods for readability.
* fhandler_socket.cc (struct wsa_event): Add owner field.
(LOCK_EVENTS): New macro.
(UNLOCK_EVENTS): Ditto.
(fhandler_socket::init_events): rename from prepare.
(fhandler_socket::evaluate_events): First half of former wait method.
Do everything but wait. Allow specifiying whether or not events from
event_mask should be erased from wsock_events->events. Simplify
OOB handling. Allow sending SIGURG to any process (group).
(fhandler_socket::wait_for_events): Second half of former wait method.
Call evaluate_events and wait in a loop if socket is blocking.
(fhandler_socket::release_events): Rename from release.
(fhandler_socket::connect): Accomodate above name changes.
(fhandler_socket::accept): Ditto.
(fhandler_socket::recv_internal): Ditto.
(fhandler_socket::send_internal): Ditto.
(fhandler_socket::close): Ditto.
(fhandler_socket::fcntl): Always set owner to given input value on
F_SETOWN. Handle F_GETOWN.
* net.cc (fdsock): Accomodate above name changes.
2006-07-20 Corinna Vinschen <corinna@vinschen.de>
* fhandler_socket.cc (fhandler_socket::wait): Set Winsock errno to
WSAEWOULDBLOCK instead of WSAEINPROGRESS.
2006-07-18 Brian Ford <Brian.Ford@FlightSafety.com>
Corinna Vinschen <corinna@vinschen.de>
* winsup.h (mmap_region_status): New enum.
(mmap_is_attached_or_noreserve_page): Adjust prototype and rename
as below.
* mmap.cc (mmap_is_attached_or_noreserve_page): Rename
mmap_is_attached_or_noreserve. Add region length parameter.
Return enum above.
* exceptions.cc (_cygtls::handle_exceptions): Accomodate above.
* fhandler.cc (fhandler_base::raw_read): Call above for NOACCESS
errors and retry on success to allow reads into untouched
MAP_NORESERVE buffers.
2006-07-18 Corinna Vinschen <corinna@vinschen.de>
* cygwin.din (posix_openpt): Export.
* tty.cc (posix_openpt): New function.
* include/cygwin/stdlib.h (posix_openpt): Declare.
* include/cygwin/version.h: Bump API minor number.
2006-07-14 Corinna Vinschen <corinna@vinschen.de>
* security.cc (get_token_group_sidlist): Always add the interactive
group to the token. Add comment. Create logon_id group SID by
copying it from incoming group list.
(create_token): Add subauth_token parameter. Use information in
subauth_token if present. Tweak SourceIdentifier if subauth_token
is present for debugging purposes.
* security.h (create_token): Add subauth_token parameter in declaration.
* syscalls.cc (seteuid32): Call subauth first. Call create_token
regardless. Use subauth token in call to create_token if subauth
succeeded.
2006-07-13 Corinna Vinschen <corinna@vinschen.de>
* include/netinet/in.h: Update copyright.
2006-07-13 Corinna Vinschen <corinna@vinschen.de>
* fhandler_socket.cc (fhandler_socket::wait): Rework function so that
WaitForMultipleObjects is really only called when necessary.
2006-07-12 Corinna Vinschen <corinna@vinschen.de>
* include/netdb.h: Declare rcmd, rcmd_af, rexec, rresvport,
rresvport_af, iruserok, iruserok_sa, ruserok.
2006-07-12 Corinna Vinschen <corinna@vinschen.de>
* Makefile.in (DLL_OFILES): Drop iruserok.o. Add rcmd.o.
* autoload.cc (rcmd): Drop definition.
* cygwin.din: Export bindresvport, bindresvport_sa, iruserok_sa,
rcmd_af, rresvport_af.
* net.cc (cygwin_rcmd): Remove.
(last_used_bindresvport): Rename from last_used_rrecvport.
(cygwin_bindresvport_sa): New function implementing bindresvport_sa.
(cygwin_bindresvport): New function implementing bindresvport.
(cygwin_rresvport): Remove.
* include/cygwin/version.h: Bump API minor number.
* include/netinet/in.h: Declare bindresvport and bindresvport_sa.
* libc/iruserok.c: Remove file.
* libc/rcmd.cc: New file implementing rcmd, rcmd_af, rresvport,
rresvport_af, iruserok_sa, iruserok and ruserok.
2006-07-12 Corinna Vinschen <corinna@vinschen.de>
* fhandler_socket.cc (fhandler_socket::getsockname): Return valid
result for unbound sockets.
2006-07-11 Corinna Vinschen <corinna@vinschen.de>
* fhandler_socket.cc (fhandler_socket::fixup_after_fork): Handle
wsock_mtx and wsock_evt on fork, thus handling close_on_exec correctly.
(fhandler_socket::fixup_after_exec): Drop misguided attempt to handle
close_on_exec here.
(fhandler_socket::dup): Call fixup_after_fork with NULL parent.
Add comment.
(fhandler_socket::set_close_on_exec): Handle wsock_mtx and wsock_evt.
2006-07-10 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (class fhandler_socket): Add wsock_mtx, wsock_evt
and wsock_events members. Remove closed status flag, add listener
status flag. Accomodate new implementation of socket event handling
methods. Declare recv* and send* functions ssize_t as the POSIX
equivalents.
(fhandler_socket::recv_internal): Declare.
(fhandler_socket::send_internal): Ditto.
* fhandler_socket.cc (EVENT_MASK): Define mask of selected events.
(fhandler_socket::fhandler_socket): Initialize new members.
(fhandler_socket::af_local_setblocking): Don't actually set the
socket to blocking mode. Keep sane event selection.
(fhandler_socket::af_local_unsetblocking): Don't actually set the
socket to previous blocking setting, just remember it.
(struct wsa_event): New structure to keep event data per shared
socket.
(NUM_SOCKS): Define number of shared sockets concurrently handled by
all active Cygwin processes.
(wsa_events): New shared datastructure keeping all wsa_event records.
(socket_serial_number): New shared variable to identify shared sockets.
(wsa_slot_mtx): Global mutex to serialize wsa_events access.
(search_wsa_event_slot): New static function to select a new wsa_event
slot for a new socket.
(fhandler_socket::prepare): Rewrite. Prepare event selection
per new socket.
(fhandler_socket::wait): Rewrite. Wait for socket events in thread
safe and multiple process safe.
(fhandler_socket::release): Rewrite. Close per-socket descriptor
mutex handle and event handle.
(fhandler_socket::dup): Duplicate wsock_mtx and wsock_evt. Fix
copy-paste error in debug output.
(fhandler_socket::connect): Accomodate new event handling.
(fhandler_socket::listen): Set listener flag on successful listen.
(fhandler_socket::accept): Accomodate new event handling.
(fhandler_socket::recv_internal): New inline method centralizing
common recv code.
(fhandler_socket::recvfrom): Call recv_internal now.
(fhandler_socket::recvmsg): Ditto. Streamline copying from iovec
to WSABUF.
(fhandler_socket::send_internal): New inline method centralizing
common send code.
(fhandler_socket::sendto): Call send_internal now.
(fhandler_socket::sendmsg): Ditto. Streamline copying from iovec
to WSABUF.
(fhandler_socket::close): Call release now.
(fhandler_socket::ioctl): Never actually switch to blocking mode.
Just keep track of the setting.
* net.cc (fdsock): Call prepare now.
(cygwin_connect): Revert again to event driven technique.
(cygwin_accept): Ditto.
* poll.cc (poll): Don't call recvfrom on a listening socket.
Remove special case for failing recvfrom.
* include/sys/socket.h: Declare recv* and send* functions ssize_t as
requested by POSIX.
2006-07-07 Corinna Vinschen <corinna@vinschen.de>
* net.cc (cygwin_inet_ntop): Fix data type of forth parameter.
2006-07-06 Corinna Vinschen <corinna@vinschen.de>
* include/cygwin/in6.h (struct in6_addr): Fix typo.
2006-07-06 Corinna Vinschen <corinna@vinschen.de>
* cygwin.din: Export in6addr_any, in6addr_loopback, freeaddrinfo,
gai_strerror, getaddrinfo, getnameinfo.
* fhandler_socket.cc: Include cygwin/in6.h.
(get_inet_addr): Accomodate AF_INET6 usage.
(fhandler_socket::connect): Ditto.
(fhandler_socket::listen): Ditto.
(fhandler_socket::sendto): Ditto.
* net.cc: Include cygwin/in6.h.
(in6addr_any): Define.
(in6addr_loopback): Define.
(cygwin_socket): Accomodate AF_INET6 usage.
(socketpair): Bind socketpairs only to loopback for security.
(inet_pton4): New static function.
(inet_pton6): Ditto.
(cygwin_inet_pton): New AF_INET6 aware inet_pton implementation.
(inet_ntop4): New static function.
(inet_ntop6): Ditto.
(cygwin_inet_ntop): New AF_INET6 aware inet_ntop implementation.
(ga_aistruct): New static function.
(ga_clone): Ditto.
(ga_echeck): Ditto.
(ga_nsearch): Ditto.
(ga_port): Ditto.
(ga_serv): Ditto.
(ga_unix): Ditto.
(gn_ipv46): Ditto.
(ipv4_freeaddrinfo): Ditto.
(ipv4_getaddrinfo): Ditto.
(ipv4_getnameinfo): Ditto.
(gai_errmap_t): New structure holding error code - error string mapping.
(cygwin_gai_strerror): New function implementing gai_strerror.
(w32_to_gai_err): New static function.
(get_ipv6_funcs): Ditto.
(load_ipv6_funcs): Ditto.
(cygwin_freeaddrinfo): New function implementing freeaddrinfo.
(cygwin_getaddrinfo): New function implementing getaddrinfo.
(cygwin_getnameinfo): New function implementing getnameinfo.
* include/netdb.h: Include stdint.h and cygwin/socket.h. Define
data types and macros used by getaddrinfo and friends. Declare
freeaddrinfo, gai_strerror, getaddrinfo and getnameinfo.
* include/cygwin/in.h: Add IPv6 related IPPROTOs. Remove definition
of struct sockaddr_in6. Include cygwin/in6.h instead.
* include/cygwin/in6.h: New header file defining IPv6 releated
data types and macros.
* include/cygwin/socket.h: Enable AF_INET6 and PF_INET6. Add
IPv6 related socket options.
* include/cygwin/version.h: Bump API minor number.
2006-07-06 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc (DsGetDcNameA): Define.
(NetGetAnyDCName): Define.
* security.cc: Include dsgetdc.h.
(DsGetDcNameA): Declare.
(DS_FORCE_REDISCOVERY): Define.
(get_logon_server): Add bool parameter to control rediscovery of DC.
Use DsGetDcNameA function if supported, NetGetDCName/NetGetAnyDCName
otherwise.
(get_server_groups): Rediscover DC if get_user_groups fails and
try again.
(get_reg_security): Use correct error code macro when testing
RegGetKeySecurity return value.
* security.h (get_logon_server): Remove default vaue from wserver
parameter. Add rediscovery parameter.
* uinfo.cc (cygheap_user::env_logsrv): Accomodate rediscovery parameter
in call to get_logon_server.
Diffstat (limited to 'winsup/cygwin/select.cc')
-rw-r--r-- | winsup/cygwin/select.cc | 214 |
1 files changed, 65 insertions, 149 deletions
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 63215ca75..a1abba610 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -30,7 +30,6 @@ details. */ #define USE_SYS_TYPES_FD_SET #include <winsock.h> #include "cygerrno.h" -#include "select.h" #include "security.h" #include "path.h" #include "fhandler.h" @@ -1260,105 +1259,69 @@ fhandler_base::select_except (select_record *s) return s; } -struct socketinf - { - cygthread *thread; - winsock_fd_set readfds, writefds, exceptfds; - SOCKET exitsock; - select_record *start; - }; - static int peek_socket (select_record *me, bool) { - winsock_fd_set ws_readfds, ws_writefds, ws_exceptfds; - struct timeval tv = {0, 0}; - WINSOCK_FD_ZERO (&ws_readfds); - WINSOCK_FD_ZERO (&ws_writefds); - WINSOCK_FD_ZERO (&ws_exceptfds); - - HANDLE h; - set_handle_or_return_if_not_open (h, me); - select_printf ("considering handle %p", h); - - if (me->read_selected && !me->read_ready) - { - select_printf ("adding read fd_set %s, fd %d", me->fh->get_name (), - me->fd); - WINSOCK_FD_SET (h, &ws_readfds); - } - if (me->write_selected && !me->write_ready) - { - select_printf ("adding write fd_set %s, fd %d", me->fh->get_name (), - me->fd); - WINSOCK_FD_SET (h, &ws_writefds); - } - if ((me->except_selected || me->except_on_write) && !me->except_ready) - { - select_printf ("adding except fd_set %s, fd %d", me->fh->get_name (), - me->fd); - WINSOCK_FD_SET (h, &ws_exceptfds); - } - int r; - if ((me->read_selected && !me->read_ready) - || (me->write_selected && !me->write_ready) - || ((me->except_selected || me->except_on_write) && !me->except_ready)) + fhandler_socket *fh = (fhandler_socket *) me->fh; + long events; + long evt_mask = (FD_CLOSE + | (me->read_selected ? (FD_READ | FD_ACCEPT) : 0) + | (me->write_selected ? (FD_WRITE | FD_CONNECT) : 0) + | (me->except_selected ? (FD_OOB | FD_CONNECT) : 0)); + int ret = fh->evaluate_events (evt_mask, events, false); + if (me->read_selected) + me->read_ready |= !!(events & (FD_READ | FD_ACCEPT | FD_CLOSE)); + if (me->write_selected) { - r = WINSOCK_SELECT (0, &ws_readfds, &ws_writefds, &ws_exceptfds, &tv); - select_printf ("WINSOCK_SELECT returned %d", r); - if (r == -1) - { - select_printf ("error %d", WSAGetLastError ()); - set_winsock_errno (); - return 0; - } - if (WINSOCK_FD_ISSET (h, &ws_readfds)) - me->read_ready = true; - if (WINSOCK_FD_ISSET (h, &ws_writefds)) + if ((events & FD_CONNECT) && !ret) me->write_ready = true; - if (WINSOCK_FD_ISSET (h, &ws_exceptfds)) - me->except_ready = true; + else + me->write_ready |= !!(events & (FD_WRITE | FD_CLOSE)); } + if (me->except_selected) + me->except_ready |= ret || !!(events & (FD_OOB | FD_CLOSE)); + return me->read_ready || me->write_ready || me->except_ready; } static int start_thread_socket (select_record *, select_stuff *); +struct socketinf + { + cygthread *thread; + int num_w4; + HANDLE w4[MAXIMUM_WAIT_OBJECTS]; + select_record *start; + }; + static DWORD WINAPI thread_socket (void *arg) { socketinf *si = (socketinf *) arg; + bool event = false; - select_printf ("stuff_start %p", &si->start); - int r = WINSOCK_SELECT (0, &si->readfds, &si->writefds, &si->exceptfds, NULL); - select_printf ("Win32 select returned %d", r); - if (r == -1) - select_printf ("error %d", WSAGetLastError ()); - select_record *s = si->start; - while ((s = s->next)) - if (s->startup == start_thread_socket) - { - HANDLE h = s->fh->get_handle (); - select_printf ("s %p, testing fd %d (%s)", s, s->fd, s->fh->get_name ()); - if (WINSOCK_FD_ISSET (h, &si->readfds)) - { - select_printf ("read_ready"); - s->read_ready = true; - } - if (WINSOCK_FD_ISSET (h, &si->writefds)) - { - select_printf ("write_ready"); - s->write_ready = true; - } - if (WINSOCK_FD_ISSET (h, &si->exceptfds)) + select_printf ("stuff_start %p", si->start); + while (!event) + { + for (select_record *s = si->start; (s = s->next); ) + if (s->startup == start_thread_socket) + if (peek_socket (s, false)) + event = true; + if (!event) + { + switch (WaitForMultipleObjects (si->num_w4, si->w4, FALSE, 50)) { - select_printf ("except_ready"); - s->except_ready = true; + case WAIT_OBJECT_0: + case WAIT_FAILED: + goto out; + case WAIT_TIMEOUT: + default: + break; } } - - if (WINSOCK_FD_ISSET (si->exitsock, &si->readfds)) - select_printf ("saw exitsock read"); + } +out: + select_printf ("leaving thread_socket"); return 0; } @@ -1374,68 +1337,29 @@ start_thread_socket (select_record *me, select_stuff *stuff) } si = new socketinf; - WINSOCK_FD_ZERO (&si->readfds); - WINSOCK_FD_ZERO (&si->writefds); - WINSOCK_FD_ZERO (&si->exceptfds); select_record *s = &stuff->start; + if (_my_tls.locals.select_sockevt != INVALID_HANDLE_VALUE) + si->w4[0] = _my_tls.locals.select_sockevt; + else if (!(si->w4[0] = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL))) + return 1; + else + _my_tls.locals.select_sockevt = si->w4[0]; + si->num_w4 = 1; while ((s = s->next)) if (s->startup == start_thread_socket) { - HANDLE h = s->fh->get_handle (); - select_printf ("Handle %p", h); - if (s->read_selected && !s->read_ready) - { - WINSOCK_FD_SET (h, &si->readfds); - select_printf ("Added to readfds"); - } - if (s->write_selected && !s->write_ready) - { - WINSOCK_FD_SET (h, &si->writefds); - select_printf ("Added to writefds"); - } - if ((s->except_selected || s->except_on_write) && !s->except_ready) - { - WINSOCK_FD_SET (h, &si->exceptfds); - select_printf ("Added to exceptfds"); - } - } - - if (_my_tls.locals.exitsock != INVALID_SOCKET) - si->exitsock = _my_tls.locals.exitsock; - else - { - si->exitsock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (si->exitsock == INVALID_SOCKET) - { - set_winsock_errno (); - select_printf ("cannot create socket, %E"); - return 0; - } - int sin_len = sizeof (_my_tls.locals.exitsock_sin); - memset (&_my_tls.locals.exitsock_sin, 0, sin_len); - _my_tls.locals.exitsock_sin.sin_family = AF_INET; - _my_tls.locals.exitsock_sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - if (bind (si->exitsock, (struct sockaddr *) &_my_tls.locals.exitsock_sin, sin_len) < 0) - { - select_printf ("cannot bind socket %p, %E", si->exitsock); + HANDLE evt = ((fhandler_socket *) me->fh)->wsock_evt; + /* No event/socket should show up multiple times. */ + for (int i = 1; i < si->num_w4; ++i) + if (si->w4[i] == evt) + goto continue_outer_loop; + if (si->num_w4 < MAXIMUM_WAIT_OBJECTS) + si->w4[si->num_w4++] = evt; + else /* for now */ goto err; - } - - if (getsockname (si->exitsock, (struct sockaddr *) &_my_tls.locals.exitsock_sin, &sin_len) < 0) - { - select_printf ("getsockname error"); - goto err; - } - if (wincap.has_set_handle_information ()) - SetHandleInformation ((HANDLE) si->exitsock, HANDLE_FLAG_INHERIT, 0); - /* else - too bad? */ - select_printf ("opened new socket %p", si->exitsock); - _my_tls.locals.exitsock = si->exitsock; - } - - select_printf ("exitsock %p", si->exitsock); - WINSOCK_FD_SET ((HANDLE) si->exitsock, &si->readfds); + continue_outer_loop: + ; + } stuff->device_specific_socket = (void *) si; si->start = &stuff->start; select_printf ("stuff_start %p", &stuff->start); @@ -1444,8 +1368,7 @@ start_thread_socket (select_record *me, select_stuff *stuff) return 1; err: - set_winsock_errno (); - closesocket (si->exitsock); + CloseHandle (si->w4[0]); return 0; } @@ -1456,17 +1379,10 @@ socket_cleanup (select_record *, select_stuff *stuff) select_printf ("si %p si->thread %p", si, si ? si->thread : NULL); if (si && si->thread) { - char buf[] = ""; - int res = sendto (_my_tls.locals.exitsock, buf, 1, 0, - (sockaddr *) &_my_tls.locals.exitsock_sin, - sizeof (_my_tls.locals.exitsock_sin)); - select_printf ("sent a byte to exitsock %p, res %d", _my_tls.locals.exitsock, res); + SetEvent (si->w4[0]); /* Wait for thread to go away */ si->thread->detach (); - /* empty the socket */ - select_printf ("reading a byte from exitsock %p", si->exitsock); - res = recv (si->exitsock, buf, 1, 0); - select_printf ("recv returned %d", res); + ResetEvent (si->w4[0]); stuff->device_specific_socket = NULL; delete si; } |