udp:add tls cleanup protection to protect waitsem in udp_txdrain

Signed-off-by: wangchen <wangchen41@xiaomi.com>
This commit is contained in:
wangchen 2024-05-15 11:34:59 +08:00 committed by archer
parent 3146ea04b8
commit b0d8fd9d75
3 changed files with 14 additions and 4 deletions

View file

@ -897,7 +897,7 @@ int udp_writebuffer_notifier_setup(worker_t worker,
****************************************************************************/
#ifdef CONFIG_NET_UDP_NOTIFIER
void udp_notifier_teardown(int key);
void udp_notifier_teardown(FAR void *key);
#endif
/****************************************************************************

View file

@ -170,11 +170,11 @@ int udp_writebuffer_notifier_setup(worker_t worker,
*
****************************************************************************/
void udp_notifier_teardown(int key)
void udp_notifier_teardown(FAR void *key)
{
/* This is just a simple wrapper around work_notifier_teardown(). */
work_notifier_teardown(key);
work_notifier_teardown(*(FAR int *)key);
}
/****************************************************************************

View file

@ -31,8 +31,10 @@
#include <assert.h>
#include <errno.h>
#include <nuttx/cancelpt.h>
#include <nuttx/net/net.h>
#include <nuttx/semaphore.h>
#include <nuttx/tls.h>
#include "utils/utils.h"
#include "udp/udp.h"
@ -96,6 +98,10 @@ int udp_txdrain(FAR struct socket *psock, unsigned int timeout)
DEBUGASSERT(psock->s_type == SOCK_DGRAM);
/* udp_txdrain() is a cancellation point */
enter_cancellation_point();
conn = psock->s_conn;
/* Initialize the wait semaphore */
@ -112,18 +118,22 @@ int udp_txdrain(FAR struct socket *psock, unsigned int timeout)
/* There is pending write data.. wait for it to drain. */
tls_cleanup_push(tls_get_info(), udp_notifier_teardown, &key);
ret = net_sem_timedwait_uninterruptible(&waitsem, timeout);
/* Tear down the notifier (in case we timed out or were canceled) */
if (ret < 0)
{
udp_notifier_teardown(key);
udp_notifier_teardown(&key);
}
tls_cleanup_pop(tls_get_info(), 0);
}
net_unlock();
nxsem_destroy(&waitsem);
leave_cancellation_point();
return ret;
}