* fhandler_socket.cc (fhandler_socket::af_local_connect): Drop outdated
comment. (fhandler_socket::evaluate_events): Only set connect_state and call af_local_connect if connect_state is connect_pending. Explain why. Drop redundant test for socket family and type. (fhandler_socket::connect): Extend comment.
This commit is contained in:
parent
2483fa2719
commit
a85ab1d482
@ -1,3 +1,12 @@
|
|||||||
|
2014-10-11 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler_socket.cc (fhandler_socket::af_local_connect): Drop outdated
|
||||||
|
comment.
|
||||||
|
(fhandler_socket::evaluate_events): Only set connect_state and call
|
||||||
|
af_local_connect if connect_state is connect_pending. Explain why.
|
||||||
|
Drop redundant test for socket family and type.
|
||||||
|
(fhandler_socket::connect): Extend comment.
|
||||||
|
|
||||||
2014-10-11 Corinna Vinschen <corinna@vinschen.de>
|
2014-10-11 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_socket.cc (fhandler_socket::evaluate_events): Handle
|
* fhandler_socket.cc (fhandler_socket::evaluate_events): Handle
|
||||||
|
@ -398,7 +398,6 @@ fhandler_socket::af_local_connect ()
|
|||||||
{
|
{
|
||||||
bool orig_async_io, orig_is_nonblocking;
|
bool orig_async_io, orig_is_nonblocking;
|
||||||
|
|
||||||
/* This keeps the test out of select. */
|
|
||||||
if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
|
if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -623,17 +622,25 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
|
|||||||
if (evts.lNetworkEvents & FD_CONNECT)
|
if (evts.lNetworkEvents & FD_CONNECT)
|
||||||
{
|
{
|
||||||
wsock_events->connect_errorcode = evts.iErrorCode[FD_CONNECT_BIT];
|
wsock_events->connect_errorcode = evts.iErrorCode[FD_CONNECT_BIT];
|
||||||
|
|
||||||
/* Setting the connect_state and calling the AF_LOCAL handshake
|
/* Setting the connect_state and calling the AF_LOCAL handshake
|
||||||
here allows to handle this stuff from a single point. This
|
here allows to handle this stuff from a single point. This
|
||||||
is independent of FD_CONNECT being requested. Consider a
|
is independent of FD_CONNECT being requested. Consider a
|
||||||
server calling connect(2) and then immediately poll(2) with
|
server calling connect(2) and then immediately poll(2) with
|
||||||
only polling for POLLIN (example: postfix), or select(2) just
|
only polling for POLLIN (example: postfix), or select(2) just
|
||||||
asking for descriptors ready to read). */
|
asking for descriptors ready to read.
|
||||||
|
|
||||||
|
Something weird occurs in Winsock: If you fork off and call
|
||||||
|
recv/send on the duplicated, already connected socket, another
|
||||||
|
FD_CONNECT event is generated in the child process. This
|
||||||
|
would trigger a call to af_local_connect which obviously fail.
|
||||||
|
Avoid this by calling set_connect_state only if connect_state
|
||||||
|
is connect_pending. */
|
||||||
|
if (connect_state () == connect_pending)
|
||||||
|
{
|
||||||
if (wsock_events->connect_errorcode)
|
if (wsock_events->connect_errorcode)
|
||||||
connect_state (connect_failed);
|
connect_state (connect_failed);
|
||||||
else if (get_addr_family () == AF_LOCAL
|
else if (af_local_connect ())
|
||||||
&& get_socket_type () == SOCK_STREAM
|
|
||||||
&& af_local_connect ())
|
|
||||||
{
|
{
|
||||||
wsock_events->connect_errorcode = WSAGetLastError ();
|
wsock_events->connect_errorcode = WSAGetLastError ();
|
||||||
connect_state (connect_failed);
|
connect_state (connect_failed);
|
||||||
@ -641,6 +648,7 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
|
|||||||
else
|
else
|
||||||
connect_state (connected);
|
connect_state (connected);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
UNLOCK_EVENTS;
|
UNLOCK_EVENTS;
|
||||||
if ((evts.lNetworkEvents & FD_OOB) && wsock_events->owner)
|
if ((evts.lNetworkEvents & FD_OOB) && wsock_events->owner)
|
||||||
kill (wsock_events->owner, SIGURG);
|
kill (wsock_events->owner, SIGURG);
|
||||||
@ -1130,7 +1138,9 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
|
|||||||
|
|
||||||
/* Initialize connect state to "connect_pending". State is ultimately set
|
/* Initialize connect state to "connect_pending". State is ultimately set
|
||||||
to "connected" or "connect_failed" in wait_for_events when the FD_CONNECT
|
to "connected" or "connect_failed" in wait_for_events when the FD_CONNECT
|
||||||
event occurs. */
|
event occurs. Note that the underlying OS sockets are always non-blocking
|
||||||
|
and a successfully initiated non-blocking Winsock connect always returns
|
||||||
|
WSAEWOULDBLOCK. Thus it's safe to rely on event handling. */
|
||||||
connect_state (connect_pending);
|
connect_state (connect_pending);
|
||||||
|
|
||||||
int res = ::connect (get_socket (), (struct sockaddr *) &sst, namelen);
|
int res = ::connect (get_socket (), (struct sockaddr *) &sst, namelen);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user