net/tcp and udp: Add logic to signal events when TCP or UDP read-ahead data is buffered.

Squashed commit of the following:

    net/tcp:  Add signal notification for the case when UDP read-ahead data is buffered.  This is basically of clone of the TCP notification logic with naming adapted for UDP.

    net/tcp:  Add signal notification for the case when TCP read-ahead data is buffered.
This commit is contained in:
Gregory Nutt
2018-09-09 09:21:39 -06:00
parent fc127fd297
commit 28f73bd928
11 changed files with 508 additions and 3 deletions
+1 -1
View File
@@ -64,7 +64,7 @@ config IOB_NOTIFIER
default n default n
select SIG_NOTIFIER select SIG_NOTIFIER
---help--- ---help---
Enable building of IOB notifier logic that will send a signla to Enable building of IOB notifier logic that will send a signal to
a kernel thread when an IOB is available. This is is a general a kernel thread when an IOB is available. This is is a general
purpose notifier, but was developed specifically to support poll() purpose notifier, but was developed specifically to support poll()
logic where the poll must wait for an IOB to become available. logic where the poll must wait for an IOB to become available.
+11 -2
View File
@@ -66,8 +66,17 @@ config NET_TCP_READAHEAD
These settings are critical to the reasonable operation of read- These settings are critical to the reasonable operation of read-
ahead buffering. ahead buffering.
if NET_TCP_READAHEAD config TCP_READAHEAD_NOTIFIER
endif # NET_TCP_READAHEAD bool "Support TCP read-ahead notifications"
default n
select SIG_NOTIFIER
depends on NET_TCP_READAHEAD && !DISABLE_POLL
---help---
Enable building of TCP read-ahead notifier logic that will send a
signal to a kernel thread when an TCP read-ahead data has been
buffered. This is is a general purpose notifier, but was developed
specifically to support TCP poll() logic where the poll must wait
for incoming TCP data to be buffered.
config NET_TCP_WRITE_BUFFERS config NET_TCP_WRITE_BUFFERS
bool "Enable TCP/IP write buffering" bool "Enable TCP/IP write buffering"
+3
View File
@@ -55,6 +55,9 @@ endif
ifneq ($(CONFIG_DISABLE_POLL),y) ifneq ($(CONFIG_DISABLE_POLL),y)
ifeq ($(CONFIG_NET_TCP_READAHEAD),y) ifeq ($(CONFIG_NET_TCP_READAHEAD),y)
SOCK_CSRCS += tcp_netpoll.c SOCK_CSRCS += tcp_netpoll.c
ifeq ($(CONFIG_TCP_READAHEAD_NOTIFIER),y)
SOCK_CSRCS += tcp_notifier.c
endif
endif endif
endif endif
+79
View File
@@ -1542,6 +1542,85 @@ int tcp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds);
int tcp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds); int tcp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds);
#endif #endif
/****************************************************************************
* Name: tcp_notifier_setup
*
* Description:
* Set up to notify the specified PID with the provided signal number.
*
* NOTE: To avoid race conditions, the caller should set the sigprocmask
* to block signal delivery. The signal will be delivered once the
* signal is removed from the sigprocmask.
*
* Input Parameters:
* pid - The PID to be notified. If a zero value is provided, then the
* PID of the calling thread will be used.
* signo - The signal number to use with the notification.
* conn - The TCP connection where read-ahead data is needed.
*
* Returned Value:
* > 0 - The signal notification is in place. The returned value is a
* key that may be used later in a call to
* tcp_notifier_teardown().
* == 0 - There is already buffered read-ahead data. No signal
* notification will be provided.
* < 0 - An unexpected error occurred and no signal will be sent. The
* returned value is a negated errno value that indicates the
* nature of the failure.
*
****************************************************************************/
#ifdef CONFIG_TCP_READAHEAD_NOTIFIER
int tcp_notifier_setup(int pid, int signo, FAR struct tcp_conn_s *conn);
#endif
/****************************************************************************
* Name: tcp_notifier_teardown
*
* Description:
* Eliminate a TCP read-ahead notification previously setup by
* tcp_notifier_setup(). This function should only be called if the
* notification should be aborted prior to the notification. The
* notification will automatically be torn down after the signal is sent.
*
* Input Parameters:
* key - The key value returned from a previous call to
* tcp_notifier_setup().
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
#ifdef CONFIG_TCP_READAHEAD_NOTIFIER
int tcp_notifier_teardown(int key);
#endif
/****************************************************************************
* Name: tcp_notifier_signal
*
* Description:
* Read-ahead data has been buffered. Signal all threads waiting for
* read-ahead data to become available.
*
* When the read-ahead data becomes available, *all* of the waiters in
* this thread will be signaled. If there are multiple waiters then only
* the highest priority thread will get the data. Lower priority threads
* will need to call tcp_notifier_setup() once again.
*
* Input Parameters:
* conn - The TCP connection where read-ahead data was just buffered.
*
* Returned Value:
* None.
*
****************************************************************************/
#ifdef CONFIG_TCP_READAHEAD_NOTIFIER
void tcp_notifier_signal(FAR struct tcp_conn_s *conn);
#endif
#undef EXTERN #undef EXTERN
#ifdef __cplusplus #ifdef __cplusplus
} }
+8
View File
@@ -273,6 +273,14 @@ uint16_t tcp_datahandler(FAR struct tcp_conn_s *conn, FAR uint8_t *buffer,
return 0; return 0;
} }
#ifdef CONFIG_TCP_READAHEAD_NOTIFIER
/* Provided notification(s) that additional TCP read-ahead data is
* available.
*/
tcp_notifier_signal(conn);
#endif
ninfo("Buffered %d bytes\n", buflen); ninfo("Buffered %d bytes\n", buflen);
return buflen; return buflen;
} }
+152
View File
@@ -0,0 +1,152 @@
/****************************************************************************
* net/tcp/tcp_notifier.c
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <nuttx/signal.h>
#include <nuttx/mm/iob.h>
#include "tcp/tcp.h"
#ifdef CONFIG_TCP_READAHEAD_NOTIFIER
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: tcp_notifier_setup
*
* Description:
* Set up to notify the specified PID with the provided signal number.
*
* NOTE: To avoid race conditions, the caller should set the sigprocmask
* to block signal delivery. The signal will be delivered once the
* signal is removed from the sigprocmask.
*
* Input Parameters:
* pid - The PID to be notified. If a zero value is provided, then the
* PID of the calling thread will be used.
* signo - The signal number to use with the notification.
* conn - The TCP connection where read-ahead data is needed.
*
* Returned Value:
* > 0 - The signal notification is in place. The returned value is a
* key that may be used later in a call to
* tcp_notifier_teardown().
* == 0 - There is already buffered read-ahead data. No signal
* notification will be provided.
* < 0 - An unexpected error occurred and no signal will be sent. The
* returned value is a negated errno value that indicates the
* nature of the failure.
*
****************************************************************************/
int tcp_notifier_setup(int pid, int signo, FAR struct tcp_conn_s *conn)
{
/* If there is already buffered read-ahead data, then return zero without
* setting up the notification.
*/
if (conn->readahead.qh_head != NULL)
{
return 0;
}
/* Otherwise, this is just a simple wrapper around nxsig_notifer_setup(). */
return nxsig_notifier_setup(pid, signo, NXSIG_TCP_READAHEAD, conn);
}
/****************************************************************************
* Name: tcp_notifier_teardown
*
* Description:
* Eliminate a TCP read-ahead notification previously setup by
* tcp_notifier_setup(). This function should only be called if the
* notification should be aborted prior to the notification. The
* notification will automatically be torn down after the signal is sent.
*
* Input Parameters:
* key - The key value returned from a previous call to
* tcp_notifier_setup().
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int tcp_notifier_teardown(int key)
{
/* This is just a simple wrapper around nxsig_notifier_teardown(). */
return nxsig_notifier_teardown(key);
}
/****************************************************************************
* Name: tcp_notifier_signal
*
* Description:
* Read-ahead data has been buffered. Signal all threads waiting for
* read-ahead data to become available.
*
* When the read-ahead data becomes available, *all* of the waiters in
* this thread will be signaled. If there are multiple waiters then only
* the highest priority thread will get the data. Lower priority threads
* will need to call tcp_notifier_setup() once again.
*
* Input Parameters:
* conn - The TCP connection where read-ahead data was just buffered.
*
* Returned Value:
* None.
*
****************************************************************************/
void tcp_notifier_signal(FAR struct tcp_conn_s *conn)
{
/* This is just a simple wrapper around nxsig_notifier_signal(). */
return nxsig_notifier_signal(NXSIG_TCP_READAHEAD, conn);
}
#endif /* CONFIG_TCP_READAHEAD_NOTIFIER */
+12
View File
@@ -57,6 +57,18 @@ config NET_UDP_READAHEAD
select NET_READAHEAD select NET_READAHEAD
select MM_IOB select MM_IOB
config UDP_READAHEAD_NOTIFIER
bool "Support UDP read-ahead notifications"
default n
select SIG_NOTIFIER
depends on NET_UDP_READAHEAD && !DISABLE_POLL
---help---
Enable building of UDP read-ahead notifier logic that will send a
signal to a kernel thread when an UDP read-ahead data has been
buffered. This is is a general purpose notifier, but was developed
specifically to support UDP poll() logic where the poll must wait
for incoming UDP data to be buffered.
config NET_UDP_WRITE_BUFFERS config NET_UDP_WRITE_BUFFERS
bool "Enable UDP/IP write buffering" bool "Enable UDP/IP write buffering"
default n default n
+3
View File
@@ -55,6 +55,9 @@ endif
ifneq ($(CONFIG_DISABLE_POLL),y) ifneq ($(CONFIG_DISABLE_POLL),y)
ifeq ($(CONFIG_NET_UDP_READAHEAD),y) ifeq ($(CONFIG_NET_UDP_READAHEAD),y)
SOCK_CSRCS += udp_netpoll.c SOCK_CSRCS += udp_netpoll.c
ifeq ($(CONFIG_UDP_READAHEAD_NOTIFIER),y)
SOCK_CSRCS += udp_notifier.c
endif
endif endif
endif endif
+79
View File
@@ -643,6 +643,85 @@ int udp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds);
int udp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds); int udp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds);
#endif #endif
/****************************************************************************
* Name: udp_notifier_setup
*
* Description:
* Set up to notify the specified PID with the provided signal number.
*
* NOTE: To avoid race conditions, the caller should set the sigprocmask
* to block signal delivery. The signal will be delivered once the
* signal is removed from the sigprocmask.
*
* Input Parameters:
* pid - The PID to be notified. If a zero value is provided, then the
* PID of the calling thread will be used.
* signo - The signal number to use with the notification.
* conn - The UDP connection where read-ahead data is needed.
*
* Returned Value:
* > 0 - The signal notification is in place. The returned value is a
* key that may be used later in a call to
* udp_notifier_teardown().
* == 0 - There is already buffered read-ahead data. No signal
* notification will be provided.
* < 0 - An unexpected error occurred and no signal will be sent. The
* returned value is a negated errno value that indicates the
* nature of the failure.
*
****************************************************************************/
#ifdef CONFIG_UDP_READAHEAD_NOTIFIER
int udp_notifier_setup(int pid, int signo, FAR struct udp_conn_s *conn);
#endif
/****************************************************************************
* Name: udp_notifier_teardown
*
* Description:
* Eliminate a UDP read-ahead notification previously setup by
* udp_notifier_setup(). This function should only be called if the
* notification should be aborted prior to the notification. The
* notification will automatically be torn down after the signal is sent.
*
* Input Parameters:
* key - The key value returned from a previous call to
* udp_notifier_setup().
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
#ifdef CONFIG_UDP_READAHEAD_NOTIFIER
int udp_notifier_teardown(int key);
#endif
/****************************************************************************
* Name: udp_notifier_signal
*
* Description:
* Read-ahead data has been buffered. Signal all threads waiting for
* read-ahead data to become available.
*
* When the read-ahead data becomes available, *all* of the waiters in
* this thread will be signaled. If there are multiple waiters then only
* the highest priority thread will get the data. Lower priority threads
* will need to call udp_notifier_setup() once again.
*
* Input Parameters:
* conn - The UDP connection where read-ahead data was just buffered.
*
* Returned Value:
* None.
*
****************************************************************************/
#ifdef CONFIG_UDP_READAHEAD_NOTIFIER
void udp_notifier_signal(FAR struct udp_conn_s *conn);
#endif
#undef EXTERN #undef EXTERN
#ifdef __cplusplus #ifdef __cplusplus
} }
+8
View File
@@ -224,6 +224,14 @@ static uint16_t udp_datahandler(FAR struct net_driver_s *dev, FAR struct udp_con
return 0; return 0;
} }
#ifdef CONFIG_UDP_READAHEAD_NOTIFIER
/* Provided notification(s) that additional UDP read-ahead data is
* available.
*/
udp_notifier_signal(conn);
#endif
ninfo("Buffered %d bytes\n", buflen); ninfo("Buffered %d bytes\n", buflen);
return buflen; return buflen;
} }
+152
View File
@@ -0,0 +1,152 @@
/****************************************************************************
* net/udp/udp_notifier.c
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <nuttx/signal.h>
#include <nuttx/mm/iob.h>
#include "udp/udp.h"
#ifdef CONFIG_UDP_READAHEAD_NOTIFIER
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: udp_notifier_setup
*
* Description:
* Set up to notify the specified PID with the provided signal number.
*
* NOTE: To avoid race conditions, the caller should set the sigprocmask
* to block signal delivery. The signal will be delivered once the
* signal is removed from the sigprocmask.
*
* Input Parameters:
* pid - The PID to be notified. If a zero value is provided, then the
* PID of the calling thread will be used.
* signo - The signal number to use with the notification.
* conn - The UDP connection where read-ahead data is needed.
*
* Returned Value:
* > 0 - The signal notification is in place. The returned value is a
* key that may be used later in a call to
* udp_notifier_teardown().
* == 0 - There is already buffered read-ahead data. No signal
* notification will be provided.
* < 0 - An unexpected error occurred and no signal will be sent. The
* returned value is a negated errno value that indicates the
* nature of the failure.
*
****************************************************************************/
int udp_notifier_setup(int pid, int signo, FAR struct udp_conn_s *conn)
{
/* If there is already buffered read-ahead data, then return zero without
* setting up the notification.
*/
if (conn->readahead.qh_head != NULL)
{
return 0;
}
/* Otherwise, this is just a simple wrapper around nxsig_notifer_setup(). */
return nxsig_notifier_setup(pid, signo, NXSIG_UDP_READAHEAD, conn);
}
/****************************************************************************
* Name: udp_notifier_teardown
*
* Description:
* Eliminate a UDP read-ahead notification previously setup by
* udp_notifier_setup(). This function should only be called if the
* notification should be aborted prior to the notification. The
* notification will automatically be torn down after the signal is sent.
*
* Input Parameters:
* key - The key value returned from a previous call to
* udp_notifier_setup().
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int udp_notifier_teardown(int key)
{
/* This is just a simple wrapper around nxsig_notifier_teardown(). */
return nxsig_notifier_teardown(key);
}
/****************************************************************************
* Name: udp_notifier_signal
*
* Description:
* Read-ahead data has been buffered. Signal all threads waiting for
* read-ahead data to become available.
*
* When the read-ahead data becomes available, *all* of the waiters in
* this thread will be signaled. If there are multiple waiters then only
* the highest priority thread will get the data. Lower priority threads
* will need to call udp_notifier_setup() once again.
*
* Input Parameters:
* conn - The UDP connection where read-ahead data was just buffered.
*
* Returned Value:
* None.
*
****************************************************************************/
void udp_notifier_signal(FAR struct udp_conn_s *conn)
{
/* This is just a simple wrapper around nxsig_notifier_signal(). */
return nxsig_notifier_signal(NXSIG_UDP_READAHEAD, conn);
}
#endif /* CONFIG_UDP_READAHEAD_NOTIFIER */