Add non-blocking capability for TCP sockets
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1996 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
297cb5e256
commit
b63c500c14
@ -820,10 +820,13 @@
|
||||
when creating test threads (16Kb stacksize). The stack size should
|
||||
be controlled by the .config file or the OSTest won't work on platforms
|
||||
with memory constraints.
|
||||
* netutils/thttpd: An initial port of Jef Poskanzer's THTTPD HTPPD server.
|
||||
* netutils/thttpd: An initial port of Jef Poskanzer's THTTPD HTTP server.
|
||||
See http://acme.com/software/thttpd/.
|
||||
* examples/thttpd: A basic test program for THTTPD
|
||||
* configs/eagle100/thttpd: A build configuration for THTTPD on the Micromint
|
||||
Eagle-100 LMS6918 (Cortex-M3) board.
|
||||
* lib/: Added strstr() and strpbrk().
|
||||
* net/recvfrom.c: Sockets now support some non-blocking operations --
|
||||
specifically only for TCP/IP read operations when read-ahead buffering
|
||||
is enabled.
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
<tr align="center" bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
||||
<p>Last Updated: July 18, 2009</p>
|
||||
<p>Last Updated: July 19, 2009</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -1493,12 +1493,15 @@ nuttx-0.4.10 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
when creating test threads (16Kb stacksize). The stack size should
|
||||
be controlled by the .config file or the OSTest won't work on platforms
|
||||
with memory constraints.
|
||||
* netutils/thttpd: An initial port of Jef Poskanzer's THTTPD HTPPD server.
|
||||
* netutils/thttpd: An initial port of Jef Poskanzer's THTTPD HTTP server.
|
||||
See http://acme.com/software/thttpd/.
|
||||
* examples/thttpd: A basic test program for THTTPD
|
||||
* configs/eagle100/thttpd: A build configuration for THTTPD on the Micromint
|
||||
Eagle-100 LMS6918 (Cortex-M3) board.
|
||||
* lib/: Added strstr() and strpbrk().
|
||||
* net/recvfrom.c: Sockets now support some non-blocking operations --
|
||||
specifically only for TCP/IP read operations when read-ahead buffering
|
||||
is enabled.
|
||||
|
||||
nuttx-0.4.10 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
|
@ -53,13 +53,14 @@
|
||||
|
||||
/* Definitions of 8-bit socket flags */
|
||||
|
||||
/* Bits 0:2 : Socket state */
|
||||
/* Bits 0-2: Socket state */
|
||||
#define _SF_IDLE 0x00 /* There is no socket activity */
|
||||
#define _SF_ACCEPT 0x01 /* Socket is waiting to accept a connection */
|
||||
#define _SF_RECV 0x02 /* Waiting for recv action to complete */
|
||||
#define _SF_SEND 0x03 /* Waiting for send action to complete */
|
||||
#define _SF_MASK 0x03 /* Mask to isolate the above actions */
|
||||
/* Bits 3:4 : unused */
|
||||
/* Bit 3: unused */
|
||||
#define _SF_NONBLOCK 0x10 /* Bit 4: Don't block if no data (TCP/READ only) */
|
||||
#define _SF_LISTENING 0x20 /* Bit 5: SOCK_STREAM is listening */
|
||||
#define _SF_BOUND 0x40 /* Bit 6: SOCK_STREAM is bound to an address */
|
||||
#define _SF_CONNECTED 0x80 /* Bit 7: SOCK_STREAM is connected */
|
||||
@ -69,6 +70,8 @@
|
||||
#define _SS_SETSTATE(s,f) (((s) & ~_SF_MASK) | (f))
|
||||
#define _SS_GETSTATE(s) ((s) & _SF_MASK)
|
||||
#define _SS_ISBUSY(s) (_SS_GETSTATE(s) != _SF_IDLE)
|
||||
|
||||
#define _SS_ISNONBLOCK(s) (((s) & _SF_NONBLOCK) != 0)
|
||||
#define _SS_ISLISTENING(s) (((s) & _SF_LISTENING) != 0)
|
||||
#define _SS_ISBOUND(s) (((s) & _SF_CONNECTED) != 0)
|
||||
#define _SS_ISCONNECTED(s) (((s) & _SF_CONNECTED) != 0)
|
||||
|
@ -39,11 +39,13 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
#include <nuttx/net.h>
|
||||
#include "net_internal.h"
|
||||
|
||||
@ -60,6 +62,7 @@
|
||||
int net_vfcntl(int sockfd, int cmd, va_list ap)
|
||||
{
|
||||
FAR struct socket *psock = sockfd_socket(sockfd);
|
||||
irqstate_t flags;
|
||||
int err = 0;
|
||||
int ret = 0;
|
||||
|
||||
@ -71,6 +74,10 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Interrupts must be disabled in order to perform operations on socket structures */
|
||||
|
||||
flags = irqsave();
|
||||
|
||||
#warning "Most fcntl() commands not yet implemented"
|
||||
switch (cmd)
|
||||
{
|
||||
@ -105,6 +112,9 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
|
||||
* successful execution of one of the exec functions.
|
||||
*/
|
||||
|
||||
err = ENOSYS; /* F_GETFD and F_SETFD not implemented */
|
||||
break;
|
||||
|
||||
case F_GETFL:
|
||||
/* Get the file status flags and file access modes, defined in <fcntl.h>,
|
||||
* for the file description associated with fildes. The file access modes
|
||||
@ -114,6 +124,22 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
|
||||
* refer to the same file with different open file descriptions.
|
||||
*/
|
||||
|
||||
{
|
||||
/* This summarizes the behavior of the NuttX/uIP sockets */
|
||||
|
||||
ret = O_RDWR | O_SYNC | O_RSYNC;
|
||||
|
||||
/* TCP/IP sockets may also be non-blocking if read-ahead is enabled */
|
||||
|
||||
#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
|
||||
if (psock->s_type == SOCK_STREAM && _SS_ISNONBLOCK(psock->s_flags))
|
||||
{
|
||||
ret |= O_NONBLOCK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case F_SETFL:
|
||||
/* Set the file status flags, defined in <fcntl.h>, for the file description
|
||||
* associated with fildes from the corresponding bits in the third argument,
|
||||
@ -123,6 +149,28 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
|
||||
* by the application, the result is unspecified.
|
||||
*/
|
||||
|
||||
{
|
||||
/* Non-blocking is the only configurable option. And it applies only to
|
||||
* read operations on TCP/IP sockets when read-ahead is enabled.
|
||||
*/
|
||||
|
||||
#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
|
||||
int mode = va_arg(ap, int);
|
||||
if (psock->s_type == SOCK_STREAM)
|
||||
{
|
||||
if ((mode & O_NONBLOCK) != 0)
|
||||
{
|
||||
psock->s_type |= _SF_NONBLOCK;
|
||||
}
|
||||
else
|
||||
{
|
||||
psock->s_type &= ~_SF_NONBLOCK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case F_GETOWN:
|
||||
/* If fildes refers to a socket, get the process or process group ID specified
|
||||
* to receive SIGURG signals when out-of-band data is available. Positive values
|
||||
@ -165,7 +213,7 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
|
||||
* not be done.
|
||||
*/
|
||||
|
||||
err = ENOSYS;
|
||||
err = ENOSYS; /* F_GETOWN, F_SETOWN, F_GETLK, F_SETLK, F_SETLKW */
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -173,6 +221,8 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
|
||||
break;
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
|
||||
errout:
|
||||
if (err != 0)
|
||||
{
|
||||
|
@ -868,7 +868,6 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the state structure. This is done with interrupts
|
||||
* disabled because we don't want anything to happen until we
|
||||
* are ready.
|
||||
@ -883,11 +882,29 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
|
||||
recvfrom_readahead(&state);
|
||||
|
||||
/* If there is space to receive anything more, then we will
|
||||
* wait to receive the data.
|
||||
/* In general, this uI-based implementation will not support non-blocking
|
||||
* socket operations... except in this one case: TCP receive with read-ahead
|
||||
* enabled. If this socket is configured as non-blocking then return EAGAIN
|
||||
* if no data was obtained from the read-ahead buffers.
|
||||
*/
|
||||
|
||||
if (state.rf_buflen > 0)
|
||||
if (_SS_ISNONBLOCK(psock->s_flags))
|
||||
{
|
||||
/* Return OK if something was received; EGAIN if not */
|
||||
|
||||
if (state.rf_recvlen <= 0)
|
||||
{
|
||||
/* Nothing was received */
|
||||
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
/* It is okay to block if we need to. If there is space to receive anything
|
||||
* more, then we will wait to receive the data.
|
||||
*/
|
||||
|
||||
else if (state.rf_buflen > 0)
|
||||
#endif
|
||||
{
|
||||
struct uip_conn *conn = (struct uip_conn *)psock->s_conn;
|
||||
|
@ -44,15 +44,10 @@
|
||||
|
||||
#undef CONFIG_THTTPD
|
||||
#if defined(CONFIG_NET) && defined(CONFIG_NET_TCP) && \
|
||||
defined(CONFIG_NET_TCPBACKLOG) && !defined(CONFIG_DISABLE_ENVIRONMENT)
|
||||
# define CONFIG_THTTPD
|
||||
#else
|
||||
# warning "THTTPD not built because dependenciesnot selected in configuration"
|
||||
#endif
|
||||
defined(CONFIG_NET_TCPBACKLOG) && !defined(CONFIG_DISABLE_ENVIRONMENT) && \
|
||||
CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
|
||||
|
||||
#if !defined(CONFIG_NET_NTCP_READAHEAD_BUFFERS) || CONFIG_NET_NTCP_READAHEAD_BUFFERS < 1
|
||||
# warning "CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 is recommended"
|
||||
#endif
|
||||
# define CONFIG_THTTPD 1
|
||||
|
||||
/* Check all THTTPD configuration settings. Complain on any that should have
|
||||
* been defined but were not. Supply some kind of reasonable value for all
|
||||
@ -201,5 +196,9 @@
|
||||
* referrers.
|
||||
*/
|
||||
|
||||
#else /* Dependencies not provided */
|
||||
# warning "THTTPD not built because dependencies not selected in configuration"
|
||||
#endif /* Dependencies not provided */
|
||||
|
||||
#endif /* __NETUTILS_THTTPD_VERSION_H */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user