Don't need monitor IOB buffer empty event for POLLOUT implementation

It's enough to check the buffer available in the net event handler

Change-Id: I2d7c7a03675cf6eff6ffb42a81b7c7245253e92c
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2019-12-31 14:44:44 +08:00 committed by patacongo
parent 3d7678ad9b
commit 63e3054ced
4 changed files with 21 additions and 203 deletions

View File

@ -130,9 +130,6 @@ struct tcp_poll_s
FAR struct socket *psock; /* Needed to handle loss of connection */ FAR struct socket *psock; /* Needed to handle loss of connection */
struct pollfd *fds; /* Needed to handle poll events */ struct pollfd *fds; /* Needed to handle poll events */
FAR struct devif_callback_s *cb; /* Needed to teardown the poll */ FAR struct devif_callback_s *cb; /* Needed to teardown the poll */
#if defined(CONFIG_NET_TCP_WRITE_BUFFERS) && defined(CONFIG_IOB_NOTIFIER)
int16_t key; /* Needed to cancel pending notification */
#endif
}; };
struct tcp_conn_s struct tcp_conn_s
@ -159,10 +156,10 @@ struct tcp_conn_s
* TCP_NEWDATA - May be cleared to indicate that the data was consumed * TCP_NEWDATA - May be cleared to indicate that the data was consumed
* and that no further process of the new data should be * and that no further process of the new data should be
* attempted. * attempted.
* TCP_SNDACK - If TCP_NEWDATA is cleared, then TCP_SNDACK may be set * TCP_SNDACK - If TCP_NEWDATA is cleared, then TCP_SNDACK may be set to
* to indicate that an ACK should be included in the response. * indicate that an ACK should be included in the response.
* (In TCP_NEWDATA is cleared bu TCP_SNDACK is not set, then * (In TCP_NEWDATA is cleared bu TCP_SNDACK is not set,
* dev->d_len should also be cleared). * then dev->d_len should also be cleared).
*/ */
FAR struct devif_callback_s *list; FAR struct devif_callback_s *list;
@ -282,7 +279,8 @@ struct tcp_conn_s
*/ */
FAR void *accept_private; FAR void *accept_private;
int (*accept)(FAR struct tcp_conn_s *listener, FAR struct tcp_conn_s *conn); int (*accept)(FAR struct tcp_conn_s *listener,
FAR struct tcp_conn_s *conn);
/* The following is a list of poll structures of threads waiting for /* The following is a list of poll structures of threads waiting for
* socket events. * socket events.
@ -550,7 +548,8 @@ int tcp_bind(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr);
* *
****************************************************************************/ ****************************************************************************/
int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr); int tcp_connect(FAR struct tcp_conn_s *conn,
FAR const struct sockaddr *addr);
/**************************************************************************** /****************************************************************************
* Name: psock_tcp_connect * Name: psock_tcp_connect
@ -559,7 +558,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr);
* Perform a TCP connection * Perform a TCP connection
* *
* Input Parameters: * Input Parameters:
* psock - A reference to the socket structure of the socket to be connected * psock - A reference to the structure of the socket to be connected
* addr - The address of the remote server to connect to * addr - The address of the remote server to connect to
* *
* Returned Value: * Returned Value:
@ -1251,7 +1250,8 @@ int tcp_backlogdelete(FAR struct tcp_conn_s *conn,
* Input Parameters: * Input Parameters:
* psock The listening TCP socket structure * psock The listening TCP socket structure
* addr Receives the address of the connecting client * addr Receives the address of the connecting client
* addrlen Input: allocated size of 'addr', Return: returned size of 'addr' * addrlen Input: allocated size of 'addr'
* Return: returned size of 'addr'
* newconn The new, accepted TCP connection structure * newconn The new, accepted TCP connection structure
* *
* Returned Value: * Returned Value:

View File

@ -113,7 +113,7 @@ static uint16_t tcp_poll_eventhandler(FAR struct net_driver_s *dev,
/* A poll is a sign that we are free to send data. */ /* A poll is a sign that we are free to send data. */
else if ((flags & TCP_POLL) != 0 && psock_tcp_cansend(info->psock) >= 0) else if (psock_tcp_cansend(info->psock) >= 0)
{ {
eventset |= (POLLOUT & info->fds->events); eventset |= (POLLOUT & info->fds->events);
} }
@ -136,77 +136,6 @@ static uint16_t tcp_poll_eventhandler(FAR struct net_driver_s *dev,
return flags; return flags;
} }
/****************************************************************************
* Name: tcp_iob_work
*
* Description:
* Work thread callback function execute when an IOB because available.
*
* Input Parameters:
* psock - Socket state structure
*
* Returned Value:
* None
*
****************************************************************************/
#if defined(CONFIG_NET_TCP_WRITE_BUFFERS) && defined(CONFIG_IOB_NOTIFIER)
static inline void tcp_iob_work(FAR void *arg)
{
FAR struct tcp_poll_s *pinfo;
FAR struct socket *psock;
FAR struct pollfd *fds;
pinfo = (FAR struct tcp_poll_s *)arg;
DEBUGASSERT(pinfo->psock != NULL && pinfo->fds != NULL);
psock = pinfo->psock;
fds = pinfo->fds;
/* Verify that we still have a connection */
if (!_SS_ISCONNECTED(psock->s_flags) && !_SS_ISLISTENING(psock->s_flags))
{
/* Don't report more than once. Might happen in a race condition */
if ((fds->revents & (POLLERR | POLLHUP)) == 0)
{
/* 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);
nxsem_post(fds->sem);
}
}
/* Handle a race condition. Check if we have already posted the POLLOUT
* event. If so, don't do it again and don't setup notification again.
*/
else if ((fds->events & POLLWRNORM) != 0 &&
(fds->revents & POLLWRNORM) == 0)
{
/* Check if we are now able to send */
if (psock_tcp_cansend(psock) >= 0)
{
/* Yes.. then signal the poll logic */
fds->revents |= POLLWRNORM;
nxsem_post(fds->sem);
}
else
{
/* No.. ask for the IOB free notification again */
pinfo->key = iob_notifier_setup(LPWORK, tcp_iob_work, pinfo);
}
}
}
#endif
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@ -273,9 +202,6 @@ int tcp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
info->psock = psock; info->psock = psock;
info->fds = fds; info->fds = fds;
info->cb = cb; info->cb = cb;
#if defined(CONFIG_NET_TCP_WRITE_BUFFERS) && defined(CONFIG_IOB_NOTIFIER)
info->key = 0;
#endif
/* Initialize the callback structure. Save the reference to the info /* Initialize the callback structure. Save the reference to the info
* structure as callback private data so that it will be available during * structure as callback private data so that it will be available during
@ -374,20 +300,6 @@ int tcp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
nxsem_post(fds->sem); nxsem_post(fds->sem);
} }
#if defined(CONFIG_NET_TCP_WRITE_BUFFERS) && defined(CONFIG_IOB_NOTIFIER)
/* If (1) revents == 0, (2) write buffering is enabled, and (3) the
* POLLOUT event is needed, then setup to receive a notification when an
* IOB is freed.
*/
else if ((fds->events & POLLOUT) != 0)
{
/* Ask for the IOB free notification */
info->key = iob_notifier_setup(LPWORK, tcp_iob_work, info);
}
#endif
errout_with_lock: errout_with_lock:
net_unlock(); net_unlock();
return ret; return ret;
@ -429,17 +341,6 @@ int tcp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds)
DEBUGASSERT(info != NULL && info->fds != NULL && info->cb != NULL); DEBUGASSERT(info != NULL && info->fds != NULL && info->cb != NULL);
if (info != NULL) if (info != NULL)
{ {
#if defined(CONFIG_NET_TCP_WRITE_BUFFERS) && defined(CONFIG_IOB_NOTIFIER)
/* Cancel any pending IOB free notification */
if (info->key > 0)
{
/* Ask for the IOB free notification */
iob_notifier_teardown(info->key);
}
#endif
/* Release the callback */ /* Release the callback */
tcp_callback_free(conn, info->cb); tcp_callback_free(conn, info->cb);

View File

@ -107,9 +107,6 @@ struct udp_poll_s
FAR struct net_driver_s *dev; /* Needed to free the callback structure */ FAR struct net_driver_s *dev; /* Needed to free the callback structure */
struct pollfd *fds; /* Needed to handle poll events */ struct pollfd *fds; /* Needed to handle poll events */
FAR struct devif_callback_s *cb; /* Needed to teardown the poll */ FAR struct devif_callback_s *cb; /* Needed to teardown the poll */
#if defined(CONFIG_NET_UDP_WRITE_BUFFERS) && defined(CONFIG_IOB_NOTIFIER)
int16_t key; /* Needed to cancel pending notification */
#endif
}; };
struct udp_conn_s struct udp_conn_s
@ -298,7 +295,8 @@ int udp_bind(FAR struct udp_conn_s *conn, FAR const struct sockaddr *addr);
* *
****************************************************************************/ ****************************************************************************/
int udp_connect(FAR struct udp_conn_s *conn, FAR const struct sockaddr *addr); int udp_connect(FAR struct udp_conn_s *conn,
FAR const struct sockaddr *addr);
/**************************************************************************** /****************************************************************************
* Name: udp_close * Name: udp_close
@ -688,9 +686,9 @@ ssize_t psock_udp_recvfrom(FAR struct socket *psock, FAR void *buf,
* *
****************************************************************************/ ****************************************************************************/
ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, ssize_t psock_udp_sendto(FAR struct socket *psock,
size_t len, int flags, FAR const struct sockaddr *to, FAR const void *buf, size_t len, int flags,
socklen_t tolen); FAR const struct sockaddr *to, socklen_t tolen);
/**************************************************************************** /****************************************************************************
* Name: udp_pollsetup * Name: udp_pollsetup
@ -797,8 +795,8 @@ int udp_writebuffer_notifier_setup(worker_t worker,
* *
* Description: * Description:
* Eliminate a UDP read-ahead notification previously setup by * Eliminate a UDP read-ahead notification previously setup by
* udp_readahead_notifier_setup(). This function should only be called if the * udp_readahead_notifier_setup(). This function should only be called if
* notification should be aborted prior to the notification. The * the notification should be aborted prior to the notification. The
* notification will automatically be torn down after the notification. * notification will automatically be torn down after the notification.
* *
* Input Parameters: * Input Parameters:
@ -825,7 +823,7 @@ int udp_notifier_teardown(int key);
* When read-ahead data becomes available, *all* of the workers waiting * When read-ahead data becomes available, *all* of the workers waiting
* for read-ahead data will be executed. If there are multiple workers * 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 * waiting for read-ahead data then only the first to execute will get the
* data. Others will need to call udp_readahead_notifier_setup() once again. * data. Others will need to call udp_readahead_notifier_setup once again.
* *
* Input Parameters: * Input Parameters:
* conn - The UDP connection where read-ahead data was just buffered. * conn - The UDP connection where read-ahead data was just buffered.

View File

@ -109,7 +109,7 @@ static uint16_t udp_poll_eventhandler(FAR struct net_driver_s *dev,
/* A poll is a sign that we are free to send data. */ /* A poll is a sign that we are free to send data. */
else if ((flags & UDP_POLL) != 0 && psock_udp_cansend(info->psock) >= 0) else if (psock_udp_cansend(info->psock) >= 0)
{ {
eventset |= (POLLOUT & info->fds->events); eventset |= (POLLOUT & info->fds->events);
} }
@ -126,59 +126,6 @@ static uint16_t udp_poll_eventhandler(FAR struct net_driver_s *dev,
return flags; return flags;
} }
/****************************************************************************
* Name: udp_iob_work
*
* Description:
* Work thread callback function execute when an IOB because available.
*
* Input Parameters:
* psock - Socket state structure
*
* Returned Value:
* None
*
****************************************************************************/
#if defined(CONFIG_NET_UDP_WRITE_BUFFERS) && defined(CONFIG_IOB_NOTIFIER)
static inline void udp_iob_work(FAR void *arg)
{
FAR struct udp_poll_s *pinfo;
FAR struct socket *psock;
FAR struct pollfd *fds;
pinfo = (FAR struct udp_poll_s *)arg;
DEBUGASSERT(pinfo->psock != NULL && pinfo->fds != NULL);
psock = pinfo->psock;
fds = pinfo->fds;
/* Handle a race condition. Check if we have already posted the POLLOUT
* event. If so, don't do it again.
*/
if ((fds->events & POLLWRNORM) != 0 &&
(fds->revents & POLLWRNORM) == 0)
{
/* Check if we are now able to send */
if (psock_udp_cansend(psock) >= 0)
{
/* Yes.. then signal the poll logic */
fds->revents |= POLLWRNORM;
nxsem_post(fds->sem);
}
else
{
/* No.. ask for the IOB free notification again */
pinfo->key = iob_notifier_setup(LPWORK, udp_iob_work, pinfo);
}
}
}
#endif
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@ -252,9 +199,6 @@ int udp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
info->psock = psock; info->psock = psock;
info->fds = fds; info->fds = fds;
info->cb = cb; info->cb = cb;
#if defined(CONFIG_NET_UDP_WRITE_BUFFERS) && defined(CONFIG_IOB_NOTIFIER)
info->key = 0;
#endif
/* Initialize the callback structure. Save the reference to the info /* Initialize the callback structure. Save the reference to the info
* structure as callback private data so that it will be available during * structure as callback private data so that it will be available during
@ -306,20 +250,6 @@ int udp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
nxsem_post(fds->sem); nxsem_post(fds->sem);
} }
#if defined(CONFIG_NET_UDP_WRITE_BUFFERS) && defined(CONFIG_IOB_NOTIFIER)
/* If (1) revents == 0, (2) write buffering is enabled, and (3) the
* POLLOUT event is needed, then setup to receive a notification an IOB
* is freed.
*/
else if ((fds->events & POLLOUT) != 0)
{
/* Ask for the IOB free notification */
info->key = iob_notifier_setup(LPWORK, udp_iob_work, info);
}
#endif
errout_with_lock: errout_with_lock:
net_unlock(); net_unlock();
return ret; return ret;
@ -361,17 +291,6 @@ int udp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds)
DEBUGASSERT(info != NULL && info->fds != NULL && info->cb != NULL); DEBUGASSERT(info != NULL && info->fds != NULL && info->cb != NULL);
if (info != NULL) if (info != NULL)
{ {
#if defined(CONFIG_NET_UDP_WRITE_BUFFERS) && defined(CONFIG_IOB_NOTIFIER)
/* Cancel any pending IOB free notification */
if (info->key > 0)
{
/* Ask for the IOB free notification */
iob_notifier_teardown(info->key);
}
#endif
/* Release the callback */ /* Release the callback */
udp_callback_free(info->dev, conn, info->cb); udp_callback_free(info->dev, conn, info->cb);