mirror of
https://github.com/apache/nuttx.git
synced 2026-06-01 07:45:16 +08:00
Fix a whole in the logic from the previous check-in
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5718 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -4262,3 +4262,22 @@
|
|||||||
* arch/arm: Correct some bad syscall dispatching logic. This change
|
* arch/arm: Correct some bad syscall dispatching logic. This change
|
||||||
cannot be fully tested until there is a fielded NuttX kernel build.
|
cannot be fully tested until there is a fielded NuttX kernel build.
|
||||||
(2013-03-06).
|
(2013-03-06).
|
||||||
|
* net/net_poll.c: Correct logic that checks if the socket is
|
||||||
|
disconnected when the poll is setup. That is bad logic: Listen
|
||||||
|
sockets, for example, are not connected. In that case, the purpose of
|
||||||
|
the poll is to wait for connection events. As a result of this,
|
||||||
|
poll/select would return immediately with POLLHUP with it was used to
|
||||||
|
detect connection events. This fix for now was to check instead if
|
||||||
|
the socket is closed (meaning that it was connected at one time but
|
||||||
|
was closed by the remote peer). That excludes the listen socket which
|
||||||
|
was never connected. This does introduce a new problem, however. If
|
||||||
|
the socket was not closed, but lost the connection through an abnormal
|
||||||
|
event, then poll/select will hang. That needs to be revisited.\
|
||||||
|
(2013-03-07)
|
||||||
|
* fs/fs_selected.c: Was not checking if the timeout parameter was NULL
|
||||||
|
but would, instead, setup a bogus timeout based on whatever it found at
|
||||||
|
address zero. Also, improved some of the memory allocation logic so
|
||||||
|
that it will not use so much memory. (2013-03-07)
|
||||||
|
* net/net_poll.c: Handle the missing case. Now tests for not connected
|
||||||
|
AND not listening. I think that now covers all of the cases including
|
||||||
|
the missing case noted above. (2013-03-07)
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ struct socket
|
|||||||
socktimeo_t s_sndtimeo; /* Send timeout value (in deciseconds) */
|
socktimeo_t s_sndtimeo; /* Send timeout value (in deciseconds) */
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
void *s_conn; /* Connection: struct uip_conn or uip_udp_conn */
|
FAR void *s_conn; /* Connection: struct uip_conn or uip_udp_conn */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This defines a list of sockets indexed by the socket descriptor */
|
/* This defines a list of sockets indexed by the socket descriptor */
|
||||||
|
|||||||
+32
-4
@@ -258,20 +258,48 @@ static inline int net_pollsetup(FAR struct socket *psock,
|
|||||||
*
|
*
|
||||||
* 1) The socket is connected and we are waiting for data availability
|
* 1) The socket is connected and we are waiting for data availability
|
||||||
* events.
|
* events.
|
||||||
|
*
|
||||||
|
* __SS_ISCONNECTED(f) == true
|
||||||
|
* __SS_ISLISTENING(f) == false
|
||||||
|
* __SS_ISCLOSED(f) == false
|
||||||
|
*
|
||||||
|
* Action: Wait for data availability events
|
||||||
|
*
|
||||||
* 2) This is a listener socket that was never connected and we are
|
* 2) This is a listener socket that was never connected and we are
|
||||||
* waiting for connection events.
|
* waiting for connection events.
|
||||||
|
*
|
||||||
|
* __SS_ISCONNECTED(f) == false
|
||||||
|
* __SS_ISLISTENING(f) == true
|
||||||
|
* __SS_ISCLOSED(f) == false
|
||||||
|
*
|
||||||
|
* Action: Wait for connection events
|
||||||
|
*
|
||||||
* 3) This socket was previously connected, but the peer has gracefully
|
* 3) This socket was previously connected, but the peer has gracefully
|
||||||
* closed the connection.
|
* closed the connection.
|
||||||
|
*
|
||||||
|
* __SS_ISCONNECTED(f) == false
|
||||||
|
* __SS_ISLISTENING(f) == false
|
||||||
|
* __SS_ISCLOSED(f) == true
|
||||||
|
*
|
||||||
|
* Action: Return with POLLHUP|POLLERR events
|
||||||
|
*
|
||||||
* 4) This socket was previously connected, but we lost the connection
|
* 4) This socket was previously connected, but we lost the connection
|
||||||
* due to some exceptional event.
|
* due to some exceptional event.
|
||||||
*
|
*
|
||||||
* We can detect 1) and 3), but 2) and 4) appear the same. So we
|
* __SS_ISCONNECTED(f) == false
|
||||||
* do the best we can for now: We will report POLLHUP if the socket
|
* __SS_ISLISTENING(f) == false
|
||||||
* has been gracefully closed.
|
* __SS_ISCLOSED(f) == false
|
||||||
|
*
|
||||||
|
* Action: Return with POLLHUP|POLLERR events
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (_SS_ISCLOSED(psock->s_flags))
|
if (!_SS_ISCONNECTED(psock->s_flags) && !_SS_ISLISTENING(psock->s_flags))
|
||||||
{
|
{
|
||||||
|
/* We were previously connected but lost the connection either due
|
||||||
|
* to a graceful shutdown by the remote peer or because of some
|
||||||
|
* exceptional event.
|
||||||
|
*/
|
||||||
|
|
||||||
fds->revents |= (POLLERR | POLLHUP);
|
fds->revents |= (POLLERR | POLLHUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user