summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-03-07 18:43:03 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-03-07 18:43:03 +0000
commit62bccf6b7538cafa63e0ea91ccb603f58417a49a (patch)
tree286f2aede6b0e5e1d6e68af582ac8c61836d1c09
parent76494a2d103c88d1c3888a6f0348a6b7e31b564d (diff)
downloadpx4-nuttx-62bccf6b7538cafa63e0ea91ccb603f58417a49a.tar.gz
px4-nuttx-62bccf6b7538cafa63e0ea91ccb603f58417a49a.tar.bz2
px4-nuttx-62bccf6b7538cafa63e0ea91ccb603f58417a49a.zip
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
-rw-r--r--nuttx/ChangeLog19
-rw-r--r--nuttx/include/nuttx/net/net.h2
-rw-r--r--nuttx/net/net_poll.c36
3 files changed, 52 insertions, 5 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 6e9434e19..753e4c88c 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -4262,3 +4262,22 @@
* arch/arm: Correct some bad syscall dispatching logic. This change
cannot be fully tested until there is a fielded NuttX kernel build.
(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)
diff --git a/nuttx/include/nuttx/net/net.h b/nuttx/include/nuttx/net/net.h
index d23fb8796..a7f8f0578 100644
--- a/nuttx/include/nuttx/net/net.h
+++ b/nuttx/include/nuttx/net/net.h
@@ -97,7 +97,7 @@ struct socket
socktimeo_t s_sndtimeo; /* Send timeout value (in deciseconds) */
#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 */
diff --git a/nuttx/net/net_poll.c b/nuttx/net/net_poll.c
index 583d469a7..55ede320d 100644
--- a/nuttx/net/net_poll.c
+++ b/nuttx/net/net_poll.c
@@ -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
* 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
* 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
* 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
* due to some exceptional event.
*
- * We can detect 1) and 3), but 2) and 4) appear the same. So we
- * do the best we can for now: We will report POLLHUP if the socket
- * has been gracefully closed.
+ * __SS_ISCONNECTED(f) == false
+ * __SS_ISLISTENING(f) == false
+ * __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);
}