net/TCP: Extend the TCP notification logic logic so that it will also report loss of connection events.
This commit is contained in:
parent
9d3148406c
commit
09d5d05b95
@ -47,6 +47,17 @@ config NET_MAX_LISTENPORTS
|
||||
---help---
|
||||
Maximum number of listening TCP/IP ports (all tasks). Default: 20
|
||||
|
||||
config TCP_NOTIFIER
|
||||
bool "Support TCP notifications"
|
||||
default n
|
||||
depends on SCHED_HPWORK
|
||||
---help---
|
||||
Enable building of TCP notifier logic that will execute a worker
|
||||
function on the high priority work queue when read-ahead data
|
||||
is available or when a TCP connection is lost. This is is a general
|
||||
purpose notifier, but was developed specifically to support poll()
|
||||
logic where the poll must wait for these events.
|
||||
|
||||
config NET_TCP_READAHEAD
|
||||
bool "Enable TCP/IP read-ahead buffering"
|
||||
default y
|
||||
@ -66,17 +77,6 @@ config NET_TCP_READAHEAD
|
||||
These settings are critical to the reasonable operation of read-
|
||||
ahead buffering.
|
||||
|
||||
config TCP_READAHEAD_NOTIFIER
|
||||
bool "Support TCP read-ahead notifications"
|
||||
default n
|
||||
depends on NET_TCP_READAHEAD && SCHED_HPWORK
|
||||
---help---
|
||||
Enable building of TCP read-ahead notifier logic that will execute a
|
||||
worker function on the high priority work queue when read-ahead data
|
||||
is available. This is is a general purpose notifier, but was
|
||||
developed specifically to support poll() logic where the poll must
|
||||
wait for read-ahead data to become available.
|
||||
|
||||
config NET_TCP_WRITE_BUFFERS
|
||||
bool "Enable TCP/IP write buffering"
|
||||
default n
|
||||
|
@ -55,7 +55,7 @@ endif
|
||||
ifneq ($(CONFIG_DISABLE_POLL),y)
|
||||
ifeq ($(CONFIG_NET_TCP_READAHEAD),y)
|
||||
SOCK_CSRCS += tcp_netpoll.c
|
||||
ifeq ($(CONFIG_TCP_READAHEAD_NOTIFIER),y)
|
||||
ifeq ($(CONFIG_TCP_NOTIFIER),y)
|
||||
SOCK_CSRCS += tcp_notifier.c
|
||||
endif
|
||||
endif
|
||||
|
@ -49,7 +49,7 @@
|
||||
#include <nuttx/mm/iob.h>
|
||||
#include <nuttx/net/ip.h>
|
||||
|
||||
#ifdef CONFIG_TCP_READAHEAD_NOTIFIER
|
||||
#ifdef CONFIG_TCP_NOTIFIER
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
@ -1547,7 +1547,7 @@ int tcp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_notifier_setup
|
||||
* Name: tcp_readahead_notifier_setup
|
||||
*
|
||||
* Description:
|
||||
* Set up to perform a callback to the worker function when an TCP data
|
||||
@ -1556,7 +1556,7 @@ int tcp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds);
|
||||
*
|
||||
* Input Parameters:
|
||||
* worker - The worker function to execute on the high priority work
|
||||
* queue when data is available in the TCP readahead buffer.
|
||||
* queue when data is available in the TCP read-ahead buffer.
|
||||
* conn - The TCP connection where read-ahead data is needed.
|
||||
* arg - A user-defined argument that will be available to the worker
|
||||
* function when it runs.
|
||||
@ -1573,9 +1573,42 @@ int tcp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_TCP_READAHEAD_NOTIFIER
|
||||
int tcp_notifier_setup(worker_t worker, FAR struct tcp_conn_s *conn,
|
||||
FAR void *arg);
|
||||
#ifdef CONFIG_TCP_NOTIFIER
|
||||
int tcp_readahead_notifier_setup(worker_t worker,
|
||||
FAR struct tcp_conn_s *conn,
|
||||
FAR void *arg);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_readahead_disconnect_setup
|
||||
*
|
||||
* Description:
|
||||
* Set up to perform a callback to the worker function if the TCP
|
||||
* connection is lost.
|
||||
*
|
||||
* Input Parameters:
|
||||
* worker - The worker function to execute on the high priority work
|
||||
* queue when data is available in the TCP read-ahead buffer.
|
||||
* conn - The TCP connection where read-ahead data is needed.
|
||||
* arg - A user-defined argument that will be available to the worker
|
||||
* function when it runs.
|
||||
*
|
||||
* 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_NOTIFIER
|
||||
int tcp_readahead_disconnect_setup(worker_t worker,
|
||||
FAR struct tcp_conn_s *conn,
|
||||
FAR void *arg);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@ -1583,13 +1616,13 @@ int tcp_notifier_setup(worker_t worker, FAR struct tcp_conn_s *conn,
|
||||
*
|
||||
* 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
|
||||
* tcp_readahead_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().
|
||||
* tcp_readahead_notifier_setup().
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
@ -1597,12 +1630,12 @@ int tcp_notifier_setup(worker_t worker, FAR struct tcp_conn_s *conn,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_TCP_READAHEAD_NOTIFIER
|
||||
#ifdef CONFIG_TCP_NOTIFIER
|
||||
int tcp_notifier_teardown(int key);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_notifier_signal
|
||||
* Name: tcp_readahead_signal
|
||||
*
|
||||
* Description:
|
||||
* Read-ahead data has been buffered. Signal all threads waiting for
|
||||
@ -1611,7 +1644,8 @@ int tcp_notifier_teardown(int key);
|
||||
* When read-ahead data becomes available, *all* of the workers waiting
|
||||
* for read-ahead data will be executed. If there are multiple workers
|
||||
* waiting for read-ahead data then only the first to execute will get the
|
||||
* data. Others will need to call tcp_notifier_setup() once again.
|
||||
* data. Others will need to call tcp_readahead_notifier_setup() once
|
||||
* again.
|
||||
*
|
||||
* Input Parameters:
|
||||
* conn - The TCP connection where read-ahead data was just buffered.
|
||||
@ -1621,8 +1655,27 @@ int tcp_notifier_teardown(int key);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_TCP_READAHEAD_NOTIFIER
|
||||
void tcp_notifier_signal(FAR struct tcp_conn_s *conn);
|
||||
#ifdef CONFIG_TCP_NOTIFIER
|
||||
void tcp_readahead_signal(FAR struct tcp_conn_s *conn);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_disconnect_signal
|
||||
*
|
||||
* Description:
|
||||
* The TCP connection has been lost. Signal all threads monitoring TCP
|
||||
* state events.
|
||||
*
|
||||
* Input Parameters:
|
||||
* conn - The TCP connection where read-ahead data was just buffered.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_TCP_NOTIFIER
|
||||
void tcp_disconnect_signal(FAR struct tcp_conn_s *conn);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
|
@ -145,6 +145,10 @@ tcp_data_event(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
|
||||
uint16_t tcp_callback(FAR struct net_driver_s *dev,
|
||||
FAR struct tcp_conn_s *conn, uint16_t flags)
|
||||
{
|
||||
#ifdef CONFIG_TCP_NOTIFIER
|
||||
uint16_t orig = flags;
|
||||
#endif
|
||||
|
||||
/* Preserve the TCP_ACKDATA, TCP_CLOSE, and TCP_ABORT in the response.
|
||||
* These is needed by the network to handle responses and buffer state. The
|
||||
* TCP_NEWDATA indication will trigger the ACK response, but must be
|
||||
@ -199,6 +203,15 @@ uint16_t tcp_callback(FAR struct net_driver_s *dev,
|
||||
flags = devif_conn_event(dev, conn, flags, conn->connevents);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TCP_NOTIFIER
|
||||
/* Provide notification(s) if the TCP connection has been lost. */
|
||||
|
||||
if ((orig & TCP_DISCONN_EVENTS) != 0)
|
||||
{
|
||||
tcp_disconnect_signal(conn);
|
||||
}
|
||||
#endif
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
@ -273,12 +286,12 @@ uint16_t tcp_datahandler(FAR struct tcp_conn_s *conn, FAR uint8_t *buffer,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TCP_READAHEAD_NOTIFIER
|
||||
/* Provided notification(s) that additional TCP read-ahead data is
|
||||
#ifdef CONFIG_TCP_NOTIFIER
|
||||
/* Provide notification(s) that additional TCP read-ahead data is
|
||||
* available.
|
||||
*/
|
||||
|
||||
tcp_notifier_signal(conn);
|
||||
tcp_readahead_signal(conn);
|
||||
#endif
|
||||
|
||||
ninfo("Buffered %d bytes\n", buflen);
|
||||
|
@ -44,17 +44,18 @@
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/mm/iob.h>
|
||||
#include <nuttx/net/tcp.h>
|
||||
|
||||
#include "tcp/tcp.h"
|
||||
|
||||
#ifdef CONFIG_TCP_READAHEAD_NOTIFIER
|
||||
#ifdef CONFIG_TCP_NOTIFIER
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_notifier_setup
|
||||
* Name: tcp_readahead_notifier_setup
|
||||
*
|
||||
* Description:
|
||||
* Set up to perform a callback to the worker function when an TCP data
|
||||
@ -63,7 +64,7 @@
|
||||
*
|
||||
* Input Parameters:
|
||||
* worker - The worker function to execute on the high priority work
|
||||
* queue when data is available in the TCP readahead buffer.
|
||||
* queue when data is available in the TCP read-ahead buffer.
|
||||
* conn - The TCP connection where read-ahead data is needed.
|
||||
* arg - A user-defined argument that will be available to the worker
|
||||
* function when it runs.
|
||||
@ -80,8 +81,9 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int tcp_notifier_setup(worker_t worker, FAR struct tcp_conn_s *conn,
|
||||
FAR void *arg)
|
||||
int tcp_readahead_notifier_setup(worker_t worker,
|
||||
FAR struct tcp_conn_s *conn,
|
||||
FAR void *arg)
|
||||
{
|
||||
struct work_notifier_s info;
|
||||
|
||||
@ -106,18 +108,69 @@ int tcp_notifier_setup(worker_t worker, FAR struct tcp_conn_s *conn,
|
||||
return work_notifier_setup(&info);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_readahead_disconnect_setup
|
||||
*
|
||||
* Description:
|
||||
* Set up to perform a callback to the worker function if the TCP
|
||||
* connection is lost.
|
||||
*
|
||||
* Input Parameters:
|
||||
* worker - The worker function to execute on the high priority work
|
||||
* queue when data is available in the TCP read-ahead buffer.
|
||||
* conn - The TCP connection where read-ahead data is needed.
|
||||
* arg - A user-defined argument that will be available to the worker
|
||||
* function when it runs.
|
||||
*
|
||||
* 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_readahead_disconnect_setup(worker_t worker,
|
||||
FAR struct tcp_conn_s *conn,
|
||||
FAR void *arg)
|
||||
{
|
||||
struct work_notifier_s info;
|
||||
|
||||
DEBUGASSERT(worker != NULL);
|
||||
|
||||
/* If connection has not been established, then return 0. */
|
||||
|
||||
if (conn->tcpstateflags != TCP_ESTABLISHED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Otherwise, this is just a simple wrapper around work_notifer_setup(). */
|
||||
|
||||
info.evtype = WORK_TCP_DISCONNECT;
|
||||
info.qualifier = conn;
|
||||
info.arg = arg;
|
||||
info.worker = worker;
|
||||
|
||||
return work_notifier_setup(&info);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
* tcp_readahead_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().
|
||||
* tcp_readahead_notifier_setup().
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
@ -133,7 +186,7 @@ int tcp_notifier_teardown(int key)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tcp_notifier_signal
|
||||
* Name: tcp_readahead_signal
|
||||
*
|
||||
* Description:
|
||||
* Read-ahead data has been buffered. Signal all threads waiting for
|
||||
@ -142,7 +195,8 @@ int tcp_notifier_teardown(int key)
|
||||
* When read-ahead data becomes available, *all* of the workers waiting
|
||||
* for read-ahead data will be executed. If there are multiple workers
|
||||
* waiting for read-ahead data then only the first to execute will get the
|
||||
* data. Others will need to call tcp_notifier_setup() once again.
|
||||
* data. Others will need to call tcp_readahead_notifier_setup() once
|
||||
* again.
|
||||
*
|
||||
* Input Parameters:
|
||||
* conn - The TCP connection where read-ahead data was just buffered.
|
||||
@ -152,11 +206,33 @@ int tcp_notifier_teardown(int key)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void tcp_notifier_signal(FAR struct tcp_conn_s *conn)
|
||||
void tcp_readahead_signal(FAR struct tcp_conn_s *conn)
|
||||
{
|
||||
/* This is just a simple wrapper around work_notifier_signal(). */
|
||||
|
||||
return work_notifier_signal(WORK_TCP_READAHEAD, conn);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TCP_READAHEAD_NOTIFIER */
|
||||
/****************************************************************************
|
||||
* Name: tcp_disconnect_signal
|
||||
*
|
||||
* Description:
|
||||
* The TCP connection has been lost. Signal all threads monitoring TCP
|
||||
* state events.
|
||||
*
|
||||
* Input Parameters:
|
||||
* conn - The TCP connection where read-ahead data was just buffered.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void tcp_disconnect_signal(FAR struct tcp_conn_s *conn)
|
||||
{
|
||||
/* This is just a simple wrapper around work_notifier_signal(). */
|
||||
|
||||
return work_notifier_signal(WORK_TCP_DISCONNECT, conn);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TCP_NOTIFIER */
|
||||
|
@ -314,7 +314,13 @@ int work_notifier_setup(FAR struct work_notifier_s *info)
|
||||
|
||||
key = work_notifier_key();
|
||||
|
||||
/* Add the notification to the head of the pending list */
|
||||
/* Add the notification to the head of the pending list
|
||||
*
|
||||
* REVISIT: Work will be processed in LIFO order. Perhaps
|
||||
* we should should consider saving the notification is the
|
||||
* order of the caller's execution priority so that the
|
||||
* notifications executed in a saner order?
|
||||
*/
|
||||
|
||||
notifier->flink = g_notifier_pending;
|
||||
notifier->alloc = alloc;
|
||||
|
Loading…
x
Reference in New Issue
Block a user