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:
parent
3d7678ad9b
commit
63e3054ced
@ -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:
|
||||||
|
@ -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);
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user