diff --git a/net/arp/arp_notify.c b/net/arp/arp_notify.c index a4568ed136721..aa6dce1fa12dd 100644 --- a/net/arp/arp_notify.c +++ b/net/arp/arp_notify.c @@ -156,7 +156,7 @@ int arp_wait(FAR struct arp_notify_s *notify, unsigned int timeout) /* And wait for the ARP response (or a timeout). */ - net_sem_timedwait_uninterruptible(¬ify->nt_sem, timeout); + nxsem_tickwait_uninterruptible(¬ify->nt_sem, MSEC2TICK(timeout)); /* Then get the real result of the transfer */ diff --git a/net/arp/arp_send.c b/net/arp/arp_send.c index 17cf96d221851..2825a708ce5ca 100644 --- a/net/arp/arp_send.c +++ b/net/arp/arp_send.c @@ -374,15 +374,15 @@ int arp_send(in_addr_t ipaddr) netdev_txnotify_dev(dev, ARP_POLL); /* Wait for the send to complete or an error to occur. - * net_sem_wait will also terminate if a signal is received. + * nxsem_tickwait will also terminate if a signal is received. */ netdev_unlock(dev); do { - ret = net_sem_timedwait_uninterruptible(&state.snd_sem, - CONFIG_ARP_SEND_DELAYMSEC); + ret = nxsem_tickwait(&state.snd_sem, + MSEC2TICK(CONFIG_ARP_SEND_DELAYMSEC)); if (ret == -ETIMEDOUT) { arp_wait_cancel(¬ify); diff --git a/net/bluetooth/bluetooth.h b/net/bluetooth/bluetooth.h index 11c0606e3fac7..c45c433323813 100644 --- a/net/bluetooth/bluetooth.h +++ b/net/bluetooth/bluetooth.h @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -119,6 +120,40 @@ extern "C" EXTERN const struct sock_intf_s g_bluetooth_sockif; +/* The Bluetooth connections rmutex */ + +extern rmutex_t g_bluetooth_connections_lock; + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: bluetooth_conn_list_lock + * + * Description: + * Lock the Bluetooth connection list. + * + ****************************************************************************/ + +static inline_function void bluetooth_conn_list_lock(void) +{ + nxrmutex_lock(&g_bluetooth_connections_lock); +} + +/**************************************************************************** + * Name: bluetooth_conn_list_unlock + * + * Description: + * Unlock the Bluetooth connection list. + * + ****************************************************************************/ + +static inline_function void bluetooth_conn_list_unlock(void) +{ + nxrmutex_unlock(&g_bluetooth_connections_lock); +} + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/net/bluetooth/bluetooth_callback.c b/net/bluetooth/bluetooth_callback.c index 50487c769cbc4..c3f675238b7b7 100644 --- a/net/bluetooth/bluetooth_callback.c +++ b/net/bluetooth/bluetooth_callback.c @@ -37,6 +37,7 @@ #include #include "devif/devif.h" +#include "utils/utils.h" #include "bluetooth/bluetooth.h" #ifdef CONFIG_NET_BLUETOOTH @@ -71,7 +72,9 @@ uint32_t bluetooth_callback(FAR struct radio_driver_s *radio, { /* Perform the callback */ + conn_lock(&conn->bc_conn); flags = devif_conn_event(&radio->r_dev, flags, conn->bc_conn.list); + conn_unlock(&conn->bc_conn); } return flags; diff --git a/net/bluetooth/bluetooth_conn.c b/net/bluetooth/bluetooth_conn.c index 9deb36247ce6e..abd7b6cc7611f 100644 --- a/net/bluetooth/bluetooth_conn.c +++ b/net/bluetooth/bluetooth_conn.c @@ -55,6 +55,14 @@ # define CONFIG_NET_BLUETOOTH_MAX_CONNS 0 #endif +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* The Bluetooth connections rmutex */ + +rmutex_t g_bluetooth_connections_lock = NXRMUTEX_INITIALIZER; + /**************************************************************************** * Private Data ****************************************************************************/ @@ -96,7 +104,7 @@ FAR struct bluetooth_conn_s *bluetooth_conn_alloc(void) /* The free list is protected by the network lock */ - net_lock(); + bluetooth_conn_list_lock(); conn = NET_BUFPOOL_TRYALLOC(g_bluetooth_connections); if (conn) @@ -110,7 +118,7 @@ FAR struct bluetooth_conn_s *bluetooth_conn_alloc(void) dq_addlast(&conn->bc_conn.node, &g_active_bluetooth_connections); } - net_unlock(); + bluetooth_conn_list_unlock(); return conn; } @@ -134,7 +142,7 @@ void bluetooth_conn_free(FAR struct bluetooth_conn_s *conn) /* Remove the connection from the active list */ - net_lock(); + bluetooth_conn_list_lock(); dq_rem(&conn->bc_conn.node, &g_active_bluetooth_connections); /* Check if there any any frames attached to the container */ @@ -162,7 +170,7 @@ void bluetooth_conn_free(FAR struct bluetooth_conn_s *conn) NET_BUFPOOL_FREE(g_bluetooth_connections, conn); - net_unlock(); + bluetooth_conn_list_unlock(); } /**************************************************************************** diff --git a/net/bluetooth/bluetooth_container.c b/net/bluetooth/bluetooth_container.c index 3a337b1454a52..6ef1f4ce16270 100644 --- a/net/bluetooth/bluetooth_container.c +++ b/net/bluetooth/bluetooth_container.c @@ -133,17 +133,17 @@ FAR struct bluetooth_container_s *bluetooth_container_allocate(void) /* Try the free list first */ - net_lock(); + bluetooth_conn_list_lock(); if (g_free_container != NULL) { container = g_free_container; g_free_container = container->bn_flink; pool = BLUETOOTH_POOL_PREALLOCATED; - net_unlock(); + bluetooth_conn_list_unlock(); } else { - net_unlock(); + bluetooth_conn_list_unlock(); container = (FAR struct bluetooth_container_s *) kmm_malloc((sizeof(struct bluetooth_container_s))); pool = BLUETOOTH_POOL_DYNAMIC; @@ -188,12 +188,12 @@ void bluetooth_container_free(FAR struct bluetooth_container_s *container) * in the free list. */ - net_lock(); + bluetooth_conn_list_lock(); if (container->bn_pool == BLUETOOTH_POOL_PREALLOCATED) { container->bn_flink = g_free_container; g_free_container = container; - net_unlock(); + bluetooth_conn_list_unlock(); } else { @@ -201,7 +201,7 @@ void bluetooth_container_free(FAR struct bluetooth_container_s *container) /* Otherwise, deallocate it. */ - net_unlock(); + bluetooth_conn_list_unlock(); kmm_free(container); } } diff --git a/net/bluetooth/bluetooth_recvmsg.c b/net/bluetooth/bluetooth_recvmsg.c index da42b2a28a672..48eac303e4730 100644 --- a/net/bluetooth/bluetooth_recvmsg.c +++ b/net/bluetooth/bluetooth_recvmsg.c @@ -47,6 +47,7 @@ #include "netdev/netdev.h" #include "devif/devif.h" #include "socket/socket.h" +#include "utils/utils.h" #include "bluetooth/bluetooth.h" #ifdef CONFIG_NET_BLUETOOTH @@ -341,7 +342,6 @@ ssize_t bluetooth_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, * locked because we don't want anything to happen until we are ready. */ - net_lock(); memset(&state, 0, sizeof(struct bluetooth_recvfrom_s)); state.ir_buflen = len; @@ -358,6 +358,8 @@ ssize_t bluetooth_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, goto errout_with_lock; } + conn_dev_lock(&conn->bc_conn, &radio->r_dev); + /* Before we wait for data, let's check if there are already frame(s) * waiting in the RX queue. */ @@ -367,7 +369,7 @@ ssize_t bluetooth_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, { /* Good newe! We have a frame and we are done. */ - net_unlock(); + conn_dev_unlock(&conn->bc_conn, &radio->r_dev); return ret; } @@ -383,12 +385,14 @@ ssize_t bluetooth_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, state.ir_cb->event = bluetooth_recvfrom_eventhandler; /* Wait for either the receive to complete or for an error/timeout to - * occur. NOTES: (1) net_sem_wait will also terminate if a signal - * is received, (2) the network is locked! It will be un-locked while - * the task sleeps and automatically re-locked when the task restarts. + * occur. NOTES: (1) conn_dev_sem_timedwait will also terminate if a + * signal is received, (2) the network is locked! It will be un-locked + * while the task sleeps and automatically re-locked when the task + * restarts. */ - net_sem_wait(&state.ir_sem); + conn_dev_sem_timedwait(&state.ir_sem, true, UINT_MAX, + &conn->bc_conn, &radio->r_dev); /* Make sure that no further events are processed */ @@ -403,7 +407,7 @@ ssize_t bluetooth_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, nxsem_destroy(&state.ir_sem); errout_with_lock: - net_unlock(); + conn_dev_unlock(&conn->bc_conn, &radio->r_dev); return ret; } diff --git a/net/bluetooth/bluetooth_sendmsg.c b/net/bluetooth/bluetooth_sendmsg.c index 201393b72c733..da4df8cc5b486 100644 --- a/net/bluetooth/bluetooth_sendmsg.c +++ b/net/bluetooth/bluetooth_sendmsg.c @@ -302,7 +302,7 @@ static ssize_t bluetooth_sendto(FAR struct socket *psock, * because we don't want anything to happen until we are ready. */ - net_lock(); + conn_dev_lock(&conn->bc_conn, &radio->r_dev); memset(&state, 0, sizeof(struct bluetooth_sendto_s)); nxsem_init(&state.is_sem, 0, 0); /* Doesn't really fail */ @@ -347,10 +347,12 @@ static ssize_t bluetooth_sendto(FAR struct socket *psock, netdev_txnotify_dev(&radio->r_dev, BLUETOOTH_POLL); /* Wait for the send to complete or an error to occur. - * net_sem_wait will also terminate if a signal is received. + * conn_dev_sem_timedwait will also terminate if a signal is + * received. */ - ret = net_sem_wait(&state.is_sem); + ret = conn_dev_sem_timedwait(&state.is_sem, true, UINT_MAX, + &conn->bc_conn, &radio->r_dev); /* Make sure that no further events are processed */ @@ -359,7 +361,7 @@ static ssize_t bluetooth_sendto(FAR struct socket *psock, } nxsem_destroy(&state.is_sem); - net_unlock(); + conn_dev_unlock(&conn->bc_conn, &radio->r_dev); /* Check for a errors, Errors are signaled by negative errno values * for the send length @@ -370,9 +372,9 @@ static ssize_t bluetooth_sendto(FAR struct socket *psock, return state.is_sent; } - /* If net_sem_wait failed, then we were probably reawakened by a signal. - * In this case, net_sem_wait will have returned negated errno - * appropriately. + /* If conn_dev_sem_timedwait failed, then we were probably reawakened by + * a signal. In this case, conn_dev_sem_timedwait will have returned + * negated errno appropriately. */ if (ret < 0) @@ -386,7 +388,7 @@ static ssize_t bluetooth_sendto(FAR struct socket *psock, err_with_net: nxsem_destroy(&state.is_sem); - net_unlock(); + conn_dev_unlock(&conn->bc_conn, &radio->r_dev); return ret; } diff --git a/net/can/can_recvmsg.c b/net/can/can_recvmsg.c index 3d9f90eaac925..de6768cc75b68 100644 --- a/net/can/can_recvmsg.c +++ b/net/can/can_recvmsg.c @@ -360,7 +360,8 @@ static uint32_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev, * Evaluate the result of the recv operations * * Input Parameters: - * result The result of the net_sem_wait operation (may indicate EINTR) + * result The result of the conn_dev_sem_timedwait operation + * (may indicate EINTR) * pstate A pointer to the state structure to be initialized * * Returned Value: @@ -384,9 +385,9 @@ static ssize_t can_recvfrom_result(int result, return pstate->pr_result; } - /* If net_sem_wait failed, then we were probably reawakened by a signal. - * In this case, net_sem_wait will have returned negated errno - * appropriately. + /* If conn_dev_sem_timedwait failed, then we were probably reawakened by + * a signal. In this case, conn_dev_sem_timedwait will have returned + * negated errno appropriately. */ if (result < 0) @@ -518,14 +519,14 @@ ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, state.pr_cb->event = can_recvfrom_eventhandler; /* Wait for either the receive to complete or for an error/timeout to - * occur. NOTES: (1) net_sem_wait will also terminate if a signal - * is received, (2) the network is locked! It will be un-locked while - * the task sleeps and automatically re-locked when the task restarts. + * occur. NOTES: (1) conn_dev_sem_timedwait will also terminate if a + * signal is received, (2) the network is locked! It will be un-locked + * while the task sleeps and automatically re-locked when the task + * restarts. */ - conn_dev_unlock(&conn->sconn, dev); - ret = net_sem_wait(&state.pr_sem); - conn_dev_lock(&conn->sconn, dev); + ret = conn_dev_sem_timedwait(&state.pr_sem, true, UINT_MAX, + &conn->sconn, dev); /* Make sure that no further events are processed */ diff --git a/net/can/can_sendmsg.c b/net/can/can_sendmsg.c index 846d8ecc2d349..1f3054618a724 100644 --- a/net/can/can_sendmsg.c +++ b/net/can/can_sendmsg.c @@ -264,21 +264,20 @@ ssize_t can_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, netdev_txnotify_dev(dev, CAN_POLL); /* Wait for the send to complete or an error to occur. - * net_sem_timedwait will also terminate if a signal is received. + * conn_dev_sem_timedwait will also terminate if a signal is received. */ - conn_dev_unlock(&conn->sconn, dev); if (_SS_ISNONBLOCK(conn->sconn.s_flags) || (flags & MSG_DONTWAIT) != 0) { - ret = net_sem_timedwait(&state.snd_sem, 0); + ret = conn_dev_sem_timedwait(&state.snd_sem, true, 0, + &conn->sconn, dev); } else { - ret = net_sem_timedwait(&state.snd_sem, UINT_MAX); + ret = conn_dev_sem_timedwait(&state.snd_sem, true, UINT_MAX, + &conn->sconn, dev); } - conn_dev_lock(&conn->sconn, dev); - /* Make sure that no further events are processed */ can_callback_free(dev, conn, state.snd_cb); @@ -296,9 +295,9 @@ ssize_t can_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, return state.snd_sent; } - /* If net_sem_wait failed, then we were probably reawakened by a signal. - * In this case, net_sem_wait will have returned negated errno - * appropriately. + /* If conn_dev_sem_timedwait failed, then we were probably reawakened by + * a signal. In this case, conn_dev_sem_timedwait will have returned + * negated errno appropriately. */ if (ret < 0) diff --git a/net/can/can_sendmsg_buffered.c b/net/can/can_sendmsg_buffered.c index b5977c2a9bad2..7b0df1ad8739e 100644 --- a/net/can/can_sendmsg_buffered.c +++ b/net/can/can_sendmsg_buffered.c @@ -263,8 +263,9 @@ ssize_t can_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, goto errout_with_lock; } - ret = net_sem_timedwait_uninterruptible(&conn->sndsem, - _SO_TIMEOUT(conn->sconn.s_sndtimeo)); + ret = conn_dev_sem_timedwait(&conn->sndsem, false, + _SO_TIMEOUT(conn->sconn.s_sndtimeo), + &conn->sconn, dev); if (ret < 0) { goto errout_with_lock; diff --git a/net/devif/devif_callback.c b/net/devif/devif_callback.c index 01c49878a51e8..d9423ea16d109 100644 --- a/net/devif/devif_callback.c +++ b/net/devif/devif_callback.c @@ -256,11 +256,12 @@ devif_callback_alloc(FAR struct net_driver_s *dev, */ /* Note: dev->d_flags may be asynchronously changed by netdev_ifdown() - * (in net/netdev/netdev_ioctl.c). Nevertheless, net_lock() / net_unlock() - * are not required in netdev_ifdown() to prevent dev->d_flags from - * asynchronous change here. There is not an issue because net_lock() and - * net_unlock() present inside of devif_dev_event(). That should be enough - * to de-allocate connection callbacks reliably on NETDEV_DOWN event. + * (in net/netdev/netdev_ioctl.c). Nevertheless, netdev_lock() / + * netdev_unlock() are not required in netdev_ifdown() to prevent + * dev->d_flags from asynchronous change here. There is not an issue + * because netdev_lock() and netdev_unlock() present inside of + * devif_dev_event(). That should be enough to de-allocate connection + * callbacks reliably on NETDEV_DOWN event. */ if (dev && !netdev_verify(dev)) diff --git a/net/devif/devif_poll.c b/net/devif/devif_poll.c index 777c31c7cc7aa..91721991e4c81 100644 --- a/net/devif/devif_poll.c +++ b/net/devif/devif_poll.c @@ -340,6 +340,7 @@ devif_poll_bluetooth_connections(FAR struct net_driver_s *dev, * action. */ + bluetooth_conn_list_lock(); while (!bstop && (bluetooth_conn = bluetooth_conn_next(bluetooth_conn))) { /* Perform the packet TX poll */ @@ -354,6 +355,8 @@ devif_poll_bluetooth_connections(FAR struct net_driver_s *dev, } } + bluetooth_conn_list_unlock(); + return bstop; } #endif /* CONFIG_NET_BLUETOOTH */ @@ -382,6 +385,7 @@ devif_poll_ieee802154_connections(FAR struct net_driver_s *dev, * action. */ + ieee802154_conn_list_lock(); while (!bstop && (ieee802154_conn = ieee802154_conn_next(ieee802154_conn))) { /* Perform the packet TX poll */ @@ -396,6 +400,7 @@ devif_poll_ieee802154_connections(FAR struct net_driver_s *dev, } } + ieee802154_conn_list_unlock(); return bstop; } #endif /* CONFIG_NET_IEEE802154 */ diff --git a/net/icmp/icmp_recvmsg.c b/net/icmp/icmp_recvmsg.c index 83ca75e5a6ee3..0bff47c08ac33 100644 --- a/net/icmp/icmp_recvmsg.c +++ b/net/icmp/icmp_recvmsg.c @@ -374,14 +374,13 @@ ssize_t icmp_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, state.recv_cb->event = recvfrom_eventhandler; /* Wait for either the response to be received or for timeout to - * occur. net_sem_timedwait will also terminate if a signal is + * occur. conn_dev_sem_timedwait will also terminate if a signal is * received. */ - conn_dev_unlock(&conn->sconn, dev); - ret = net_sem_timedwait(&state.recv_sem, - _SO_TIMEOUT(conn->sconn.s_rcvtimeo)); - conn_dev_lock(&conn->sconn, dev); + ret = conn_dev_sem_timedwait(&state.recv_sem, true, + _SO_TIMEOUT(conn->sconn.s_rcvtimeo), + &conn->sconn, dev); if (ret < 0) { state.recv_result = ret; diff --git a/net/icmp/icmp_sendmsg.c b/net/icmp/icmp_sendmsg.c index 808db35ac9653..0aaeacdf4387b 100644 --- a/net/icmp/icmp_sendmsg.c +++ b/net/icmp/icmp_sendmsg.c @@ -406,13 +406,12 @@ ssize_t icmp_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, netdev_txnotify_dev(dev, ICMP_POLL); /* Wait for either the send to complete or for timeout to occur. - * net_sem_timedwait will also terminate if a signal is received. + * conn_dev_sem_timedwait will also terminate if a signal is received. */ - conn_dev_unlock(&conn->sconn, dev); - ret = net_sem_timedwait(&state.snd_sem, - _SO_TIMEOUT(conn->sconn.s_sndtimeo)); - conn_dev_lock(&conn->sconn, dev); + ret = conn_dev_sem_timedwait(&state.snd_sem, true, + _SO_TIMEOUT(conn->sconn.s_sndtimeo), + &conn->sconn, dev); if (ret < 0) { if (ret == -ETIMEDOUT) diff --git a/net/icmpv6/icmpv6.h b/net/icmpv6/icmpv6.h index 6f0c0e582266d..6c3b6eb67639a 100644 --- a/net/icmpv6/icmpv6.h +++ b/net/icmpv6/icmpv6.h @@ -417,9 +417,10 @@ int icmpv6_wait_cancel(FAR struct icmpv6_notify_s *notify); ****************************************************************************/ #ifdef CONFIG_NET_ICMPv6_NEIGHBOR -int icmpv6_wait(FAR struct icmpv6_notify_s *notify, unsigned int timeout); +int icmpv6_wait(FAR struct net_driver_s *dev, + FAR struct icmpv6_notify_s *notify, unsigned int timeout); #else -# define icmpv6_wait(n,t) (0) +# define icmpv6_wait(d,n,t) (0) #endif /**************************************************************************** @@ -538,9 +539,10 @@ int icmpv6_rwait_cancel(FAR struct icmpv6_rnotify_s *notify); ****************************************************************************/ #ifdef CONFIG_NET_ICMPv6_AUTOCONF -int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, unsigned int timeout); +int icmpv6_rwait(FAR struct net_driver_s *dev, + FAR struct icmpv6_rnotify_s *notify, unsigned int timeout); #else -# define icmpv6_rwait(n,t) (0) +# define icmpv6_rwait(d,n,t) (0) #endif /**************************************************************************** diff --git a/net/icmpv6/icmpv6_autoconfig.c b/net/icmpv6/icmpv6_autoconfig.c index c8603b57802fe..1121807f01cd9 100644 --- a/net/icmpv6/icmpv6_autoconfig.c +++ b/net/icmpv6/icmpv6_autoconfig.c @@ -227,19 +227,15 @@ static int icmpv6_send_message(FAR struct net_driver_s *dev, bool advertise) netdev_txnotify_dev(dev, ICMPv6_POLL); /* Wait for the send to complete or an error to occur - * net_sem_wait will also terminate if a signal is received. + * nxsem_wait will also terminate if a signal is received. */ - netdev_unlock(dev); - do { - net_sem_wait(&state.snd_sem); + conn_dev_sem_timedwait(&state.snd_sem, true, UINT_MAX, NULL, dev); } while (!state.snd_sent); - netdev_lock(dev); - ret = state.snd_result; devif_dev_callback_free(dev, state.snd_cb); @@ -395,7 +391,7 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev) /* Wait to receive the Router Advertisement message */ - ret = icmpv6_rwait(¬ify, CONFIG_ICMPv6_AUTOCONF_DELAYMSEC); + ret = icmpv6_rwait(dev, ¬ify, CONFIG_ICMPv6_AUTOCONF_DELAYMSEC); if (ret != -ETIMEDOUT) { /* ETIMEDOUT is the only expected failure. We will retry on that diff --git a/net/icmpv6/icmpv6_neighbor.c b/net/icmpv6/icmpv6_neighbor.c index 0756ac1cbcff5..13679ddc77c05 100644 --- a/net/icmpv6/icmpv6_neighbor.c +++ b/net/icmpv6/icmpv6_neighbor.c @@ -44,6 +44,7 @@ #include "inet/inet.h" #include "neighbor/neighbor.h" #include "route/route.h" +#include "utils/utils.h" #include "icmpv6/icmpv6.h" #ifdef CONFIG_NET_ICMPv6_NEIGHBOR @@ -339,14 +340,12 @@ int icmpv6_neighbor(FAR struct net_driver_s *dev, netdev_txnotify_dev(dev, ICMPv6_POLL); /* Wait for the send to complete or an error to occur. - * net_sem_wait will also terminate if a signal is received. + * nxsem_wait will also terminate if a signal is received. */ - netdev_unlock(dev); - do { - net_sem_wait(&state.snd_sem); + conn_dev_sem_timedwait(&state.snd_sem, true, UINT_MAX, NULL, dev); } while (!state.snd_sent); @@ -354,9 +353,7 @@ int icmpv6_neighbor(FAR struct net_driver_s *dev, * received. */ - ret = icmpv6_wait(¬ify, CONFIG_ICMPv6_NEIGHBOR_DELAYMSEC); - - netdev_lock(dev); + ret = icmpv6_wait(dev, ¬ify, CONFIG_ICMPv6_NEIGHBOR_DELAYMSEC); /* icmpv6_wait will return OK if and only if the matching Neighbor * Advertisement is received. Otherwise, it will return -ETIMEDOUT. diff --git a/net/icmpv6/icmpv6_notify.c b/net/icmpv6/icmpv6_notify.c index 7361b4a30b5be..3faf3dda94bc1 100644 --- a/net/icmpv6/icmpv6_notify.c +++ b/net/icmpv6/icmpv6_notify.c @@ -36,6 +36,7 @@ #include #include +#include "utils/utils.h" #include "icmpv6/icmpv6.h" #ifdef CONFIG_NET_ICMPv6_NEIGHBOR @@ -165,13 +166,14 @@ int icmpv6_wait_cancel(FAR struct icmpv6_notify_s *notify) * ****************************************************************************/ -int icmpv6_wait(FAR struct icmpv6_notify_s *notify, unsigned int timeout) +int icmpv6_wait(FAR struct net_driver_s *dev, + FAR struct icmpv6_notify_s *notify, unsigned int timeout) { int ret; /* And wait for the Neighbor Advertisement (or a timeout). */ - ret = net_sem_timedwait(¬ify->nt_sem, timeout); + ret = conn_dev_sem_timedwait(¬ify->nt_sem, true, timeout, NULL, dev); if (ret >= 0) { ret = notify->nt_result; diff --git a/net/icmpv6/icmpv6_recvmsg.c b/net/icmpv6/icmpv6_recvmsg.c index ff5a20ad390b6..e86e93ecc1363 100644 --- a/net/icmpv6/icmpv6_recvmsg.c +++ b/net/icmpv6/icmpv6_recvmsg.c @@ -384,14 +384,15 @@ ssize_t icmpv6_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, state.recv_cb->event = recvfrom_eventhandler; /* Wait for either the response to be received or for timeout to - * occur. (1) net_sem_timedwait will also terminate if a signal is - * received, (2) interrupts may be disabled! They will be - * re-enabled while the task sleeps and automatically re-enabled + * occur. (1) conn_dev_sem_timedwait will also terminate if a + * signal is received, (2) interrupts may be disabled! They will + * be re-enabled while the task sleeps and automatically re-enabled * when the task restarts. */ - ret = net_sem_timedwait(&state.recv_sem, - _SO_TIMEOUT(conn->sconn.s_rcvtimeo)); + ret = conn_dev_sem_timedwait(&state.recv_sem, true, + _SO_TIMEOUT(conn->sconn.s_rcvtimeo), + &conn->sconn, dev); if (ret < 0) { state.recv_result = ret; diff --git a/net/icmpv6/icmpv6_rnotify.c b/net/icmpv6/icmpv6_rnotify.c index 2b8751c1060d2..424cb893f48ab 100644 --- a/net/icmpv6/icmpv6_rnotify.c +++ b/net/icmpv6/icmpv6_rnotify.c @@ -258,7 +258,8 @@ int icmpv6_rwait_cancel(FAR struct icmpv6_rnotify_s *notify) * ****************************************************************************/ -int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, unsigned int timeout) +int icmpv6_rwait(FAR struct net_driver_s *dev, + FAR struct icmpv6_rnotify_s *notify, unsigned int timeout) { int ret; @@ -266,7 +267,7 @@ int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, unsigned int timeout) /* And wait for the Neighbor Advertisement (or a timeout). */ - ret = net_sem_timedwait(¬ify->rn_sem, timeout); + ret = conn_dev_sem_timedwait(¬ify->rn_sem, true, timeout, NULL, dev); if (ret >= 0) { ret = notify->rn_result; diff --git a/net/icmpv6/icmpv6_sendmsg.c b/net/icmpv6/icmpv6_sendmsg.c index 03a3b3e83c9c9..60e678f220f5e 100644 --- a/net/icmpv6/icmpv6_sendmsg.c +++ b/net/icmpv6/icmpv6_sendmsg.c @@ -402,13 +402,12 @@ ssize_t icmpv6_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, netdev_txnotify_dev(dev, ICMPv6_POLL); /* Wait for either the send to complete or for timeout to occur. - * net_sem_timedwait will also terminate if a signal is received. + * conn_dev_sem_timedwait will also terminate if a signal is received. */ - conn_dev_unlock(&conn->sconn, dev); - ret = net_sem_timedwait(&state.snd_sem, - _SO_TIMEOUT(conn->sconn.s_sndtimeo)); - conn_dev_lock(&conn->sconn, dev); + ret = conn_dev_sem_timedwait(&state.snd_sem, true, + _SO_TIMEOUT(conn->sconn.s_sndtimeo), + &conn->sconn, dev); if (ret < 0) { if (ret == -ETIMEDOUT) diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h index a5869dfa32699..2864ba7989c3f 100644 --- a/net/ieee802154/ieee802154.h +++ b/net/ieee802154/ieee802154.h @@ -32,6 +32,7 @@ #include #include +#include #include #ifdef CONFIG_NET_IEEE802154 @@ -133,6 +134,40 @@ extern "C" EXTERN const struct sock_intf_s g_ieee802154_sockif; +/* The IEEE 802.15.4 connections rmutex */ + +extern rmutex_t g_ieee802154_connections_lock; + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ieee802154_conn_list_lock + * + * Description: + * Lock the IEEE 802.15.4 connection list. + * + ****************************************************************************/ + +static inline_function void ieee802154_conn_list_lock(void) +{ + nxrmutex_lock(&g_ieee802154_connections_lock); +} + +/**************************************************************************** + * Name: ieee802154_conn_list_unlock + * + * Description: + * Unlock the IEEE 802.15.4 connection list. + * + ****************************************************************************/ + +static inline_function void ieee802154_conn_list_unlock(void) +{ + nxrmutex_unlock(&g_ieee802154_connections_lock); +} + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/net/ieee802154/ieee802154_callback.c b/net/ieee802154/ieee802154_callback.c index 5d79d834130c1..a90bcab6129b7 100644 --- a/net/ieee802154/ieee802154_callback.c +++ b/net/ieee802154/ieee802154_callback.c @@ -33,6 +33,7 @@ #include #include "devif/devif.h" +#include "utils/utils.h" #include "ieee802154/ieee802154.h" #ifdef CONFIG_NET_IEEE802154 @@ -67,7 +68,9 @@ uint32_t ieee802154_callback(FAR struct radio_driver_s *radio, { /* Perform the callback */ + conn_lock(&conn->sconn); flags = devif_conn_event(&radio->r_dev, flags, conn->sconn.list); + conn_unlock(&conn->sconn); } return flags; diff --git a/net/ieee802154/ieee802154_conn.c b/net/ieee802154/ieee802154_conn.c index ce89c02c6b2f9..5d5049a578a0d 100644 --- a/net/ieee802154/ieee802154_conn.c +++ b/net/ieee802154/ieee802154_conn.c @@ -54,6 +54,14 @@ # define CONFIG_NET_IEEE802154_MAX_CONNS 0 #endif +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* The IEEE 802.15.4 connections rmutex */ + +rmutex_t g_ieee802154_connections_lock = NXRMUTEX_INITIALIZER; + /**************************************************************************** * Private Data ****************************************************************************/ @@ -91,7 +99,7 @@ FAR struct ieee802154_conn_s *ieee802154_conn_alloc(void) /* The free list is protected by the network lock. */ - net_lock(); + ieee802154_conn_list_lock(); conn = NET_BUFPOOL_TRYALLOC(g_ieee802154_connections); if (conn) @@ -99,7 +107,7 @@ FAR struct ieee802154_conn_s *ieee802154_conn_alloc(void) dq_addlast(&conn->sconn.node, &g_active_ieee802154_connections); } - net_unlock(); + ieee802154_conn_list_unlock(); return conn; } @@ -123,7 +131,7 @@ void ieee802154_conn_free(FAR struct ieee802154_conn_s *conn) /* Remove the connection from the active list */ - net_lock(); + ieee802154_conn_list_lock(); dq_rem(&conn->sconn.node, &g_active_ieee802154_connections); /* Check if there any any frames attached to the container */ @@ -151,7 +159,7 @@ void ieee802154_conn_free(FAR struct ieee802154_conn_s *conn) NET_BUFPOOL_FREE(g_ieee802154_connections, conn); - net_unlock(); + ieee802154_conn_list_unlock(); } /**************************************************************************** diff --git a/net/ieee802154/ieee802154_container.c b/net/ieee802154/ieee802154_container.c index 14f32ee2adbe0..ddf9e81c70bb5 100644 --- a/net/ieee802154/ieee802154_container.c +++ b/net/ieee802154/ieee802154_container.c @@ -133,17 +133,17 @@ FAR struct ieee802154_container_s *ieee802154_container_allocate(void) /* Try the free list first */ - net_lock(); + ieee802154_conn_list_lock(); if (g_free_container != NULL) { container = g_free_container; g_free_container = container->ic_flink; pool = IEEE802154_POOL_PREALLOCATED; - net_unlock(); + ieee802154_conn_list_unlock(); } else { - net_unlock(); + ieee802154_conn_list_unlock(); container = (FAR struct ieee802154_container_s *) kmm_malloc((sizeof (struct ieee802154_container_s))); pool = IEEE802154_POOL_DYNAMIC; @@ -188,12 +188,12 @@ void ieee802154_container_free(FAR struct ieee802154_container_s *container) * in the free list. */ - net_lock(); + ieee802154_conn_list_lock(); if (container->ic_pool == IEEE802154_POOL_PREALLOCATED) { container->ic_flink = g_free_container; g_free_container = container; - net_unlock(); + ieee802154_conn_list_unlock(); } else { @@ -201,7 +201,7 @@ void ieee802154_container_free(FAR struct ieee802154_container_s *container) /* Otherwise, deallocate it. */ - net_unlock(); + ieee802154_conn_list_unlock(); kmm_free(container); } } diff --git a/net/ieee802154/ieee802154_recvmsg.c b/net/ieee802154/ieee802154_recvmsg.c index 1720390502b7f..53b0cecb8875a 100644 --- a/net/ieee802154/ieee802154_recvmsg.c +++ b/net/ieee802154/ieee802154_recvmsg.c @@ -45,6 +45,7 @@ #include "netdev/netdev.h" #include "devif/devif.h" #include "socket/socket.h" +#include "utils/utils.h" #include "ieee802154/ieee802154.h" #ifdef CONFIG_NET_IEEE802154 @@ -341,7 +342,6 @@ ssize_t ieee802154_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, * locked because we don't want anything to happen until we are ready. */ - net_lock(); memset(&state, 0, sizeof(struct ieee802154_recvfrom_s)); state.ir_buflen = len; @@ -358,6 +358,8 @@ ssize_t ieee802154_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, goto errout_with_lock; } + conn_dev_lock(&conn->sconn, &radio->r_dev); + /* Before we wait for data, let's check if there are already frame(s) * waiting in the RX queue. */ @@ -367,7 +369,7 @@ ssize_t ieee802154_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, { /* Good newe! We have a frame and we are done. */ - net_unlock(); + conn_dev_unlock(&conn->sconn, &radio->r_dev); return ret; } @@ -383,12 +385,14 @@ ssize_t ieee802154_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, state.ir_cb->event = ieee802154_recvfrom_eventhandler; /* Wait for either the receive to complete or for an error/timeout to - * occur. NOTES: (1) net_sem_wait will also terminate if a signal - * is received, (2) the network is locked! It will be un-locked while - * the task sleeps and automatically re-locked when the task restarts. + * occur. NOTES: (1) conn_dev_sem_timedwait will also terminate if a + * signal is received, (2) the network is locked! It will be un-locked + * while the task sleeps and automatically re-locked when the task + * restarts. */ - net_sem_wait(&state.ir_sem); + conn_dev_sem_timedwait(&state.ir_sem, true, UINT_MAX, + &conn->sconn, &radio->r_dev); /* Make sure that no further events are processed */ @@ -403,7 +407,7 @@ ssize_t ieee802154_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, nxsem_destroy(&state.ir_sem); errout_with_lock: - net_unlock(); + conn_dev_unlock(&conn->sconn, &radio->r_dev); return ret; } diff --git a/net/ieee802154/ieee802154_sendmsg.c b/net/ieee802154/ieee802154_sendmsg.c index a54e8b65da3d7..7da627aea146a 100644 --- a/net/ieee802154/ieee802154_sendmsg.c +++ b/net/ieee802154/ieee802154_sendmsg.c @@ -469,7 +469,7 @@ static ssize_t ieee802154_sendto(FAR struct socket *psock, * ready. */ - net_lock(); + conn_dev_lock(&conn->sconn, &radio->r_dev); memset(&state, 0, sizeof(struct ieee802154_sendto_s)); nxsem_init(&state.is_sem, 0, 0); /* Doesn't really fail */ @@ -501,10 +501,12 @@ static ssize_t ieee802154_sendto(FAR struct socket *psock, netdev_txnotify_dev(&radio->r_dev, IEEE802154_POLL); /* Wait for the send to complete or an error to occur. - * net_sem_wait will also terminate if a signal is received. + * conn_dev_sem_timedwait will also terminate if a signal is + * received. */ - ret = net_sem_wait(&state.is_sem); + ret = conn_dev_sem_timedwait(&state.is_sem, true, UINT_MAX, + &conn->sconn, &radio->r_dev); /* Make sure that no further events are processed */ @@ -513,7 +515,7 @@ static ssize_t ieee802154_sendto(FAR struct socket *psock, } nxsem_destroy(&state.is_sem); - net_unlock(); + conn_dev_unlock(&conn->sconn, &radio->r_dev); /* Check for a errors, Errors are signaled by negative errno values * for the send length @@ -524,9 +526,9 @@ static ssize_t ieee802154_sendto(FAR struct socket *psock, return state.is_sent; } - /* If net_sem_wait failed, then we were probably reawakened by a signal. - * In this case, net_sem_wait will have returned negated errno - * appropriately. + /* If conn_dev_sem_timedwait failed, then we were probably reawakened by a + * signal. In this case, conn_dev_sem_timedwait will have returned negated + * errno appropriately. */ if (ret < 0) diff --git a/net/igmp/igmp_msg.c b/net/igmp/igmp_msg.c index 7d57033e52756..d6a138b415ab8 100644 --- a/net/igmp/igmp_msg.c +++ b/net/igmp/igmp_msg.c @@ -145,7 +145,7 @@ int igmp_waitmsg(FAR struct igmp_group_s *group, uint8_t msgid) { /* Wait for the semaphore to be posted */ - ret = net_sem_wait_uninterruptible(&group->sem); + ret = nxsem_wait_uninterruptible(&group->sem); if (ret < 0) { break; diff --git a/net/ipfrag/ipfrag.c b/net/ipfrag/ipfrag.c index efc1f58989bf5..621f78f884d7a 100644 --- a/net/ipfrag/ipfrag.c +++ b/net/ipfrag/ipfrag.c @@ -232,7 +232,7 @@ static void ip_fragin_timerwork(FAR void *arg) { FAR struct net_driver_s *dev = node->dev; - net_lock(); + netdev_lock(dev); netdev_iob_replace(dev, node->frags->frag); node->frags->frag = NULL; @@ -266,7 +266,7 @@ static void ip_fragin_timerwork(FAR void *arg) netdev_txnotify_dev(dev, IPFRAG_POLL); } - net_unlock(); + netdev_unlock(dev); } #endif diff --git a/net/mld/mld_msg.c b/net/mld/mld_msg.c index 4cb6a6b1d4aa7..13b9445179840 100644 --- a/net/mld/mld_msg.c +++ b/net/mld/mld_msg.c @@ -120,7 +120,7 @@ int mld_waitmsg(FAR struct mld_group_s *group, uint8_t msgtype) { /* Wait for the semaphore to be posted */ - ret = net_sem_wait_uninterruptible(&group->sem); + ret = nxsem_wait_uninterruptible(&group->sem); if (ret < 0) { break; diff --git a/net/netlink/netlink_conn.c b/net/netlink/netlink_conn.c index 9295297ee1d3f..22b6f45f973fc 100644 --- a/net/netlink/netlink_conn.c +++ b/net/netlink/netlink_conn.c @@ -475,14 +475,11 @@ int netlink_get_response(FAR struct netlink_conn_s *conn, } else { - unsigned int count; - /* Wait for a response to be queued */ tls_cleanup_push(tls_get_info(), netlink_notifier_teardown, conn); - nxrmutex_breaklock(&g_netlink_lock, &count); - ret = net_sem_wait(&waitsem); - nxrmutex_restorelock(&g_netlink_lock, count); + ret = net_sem_timedwait2(&waitsem, true, UINT_MAX, &g_netlink_lock, + NULL); tls_cleanup_pop(tls_get_info(), 0); } diff --git a/net/pkt/pkt_recvmsg.c b/net/pkt/pkt_recvmsg.c index cd30728b1ea71..57cf3471de1ab 100644 --- a/net/pkt/pkt_recvmsg.c +++ b/net/pkt/pkt_recvmsg.c @@ -312,7 +312,8 @@ static void pkt_recvfrom_initialize(FAR struct pkt_conn_s *conn, * Evaluate the result of the recv operations * * Input Parameters: - * result The result of the net_sem_wait operation (may indicate EINTR) + * result The result of the conn_dev_sem_timedwait operation + * (may indicate EINTR) * pstate A pointer to the state structure to be initialized * * Returned Value: @@ -338,9 +339,9 @@ static ssize_t pkt_recvfrom_result(int result, return pstate->pr_result; } - /* If net_sem_wait failed, then we were probably reawakened by a signal. - * In this case, net_sem_wait will have returned negated errno - * appropriately. + /* If conn_dev_sem_timedwait failed, then we were probably reawakened by a + * signal. In this case, conn_dev_sem_timedwait will have returned negated + * errno appropriately. */ if (result < 0) @@ -559,15 +560,14 @@ ssize_t pkt_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, state.pr_cb->event = pkt_recvfrom_eventhandler; /* Wait for either the receive to complete or for an error/timeout - * to occur. NOTES: (1) net_sem_wait will also terminate if a - * signal is received, (2) the network is locked! It will be + * to occur. NOTES: (1) conn_dev_sem_timedwait will also terminate + * if a signal is received, (2) the network is locked! It will be * un-locked while the task sleeps and automatically re-locked when * the task restarts. */ - conn_dev_unlock(&conn->sconn, dev); - ret = net_sem_wait(&state.pr_sem); - conn_dev_lock(&conn->sconn, dev); + ret = conn_dev_sem_timedwait(&state.pr_sem, true, UINT_MAX, + &conn->sconn, dev); /* Make sure that no further events are processed */ diff --git a/net/pkt/pkt_sendmsg_buffered.c b/net/pkt/pkt_sendmsg_buffered.c index 2ebbdc0150747..e511a0a11c2f8 100644 --- a/net/pkt/pkt_sendmsg_buffered.c +++ b/net/pkt/pkt_sendmsg_buffered.c @@ -254,8 +254,9 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR const struct msghdr *msg, goto errout_with_lock; } - ret = net_sem_timedwait_uninterruptible(&conn->sndsem, - _SO_TIMEOUT(conn->sconn.s_sndtimeo)); + ret = conn_dev_sem_timedwait(&conn->sndsem, false, + _SO_TIMEOUT(conn->sconn.s_sndtimeo), + &conn->sconn, dev); if (ret < 0) { goto errout_with_lock; diff --git a/net/pkt/pkt_sendmsg_unbuffered.c b/net/pkt/pkt_sendmsg_unbuffered.c index db954e0d746c6..039a4a99410d1 100644 --- a/net/pkt/pkt_sendmsg_unbuffered.c +++ b/net/pkt/pkt_sendmsg_unbuffered.c @@ -242,12 +242,12 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, netdev_txnotify_dev(dev, PKT_POLL); /* Wait for the send to complete or an error to occur. - * net_sem_wait will also terminate if a signal is received. + * conn_dev_sem_timedwait will also terminate if a signal is + * received. */ - conn_dev_unlock(&conn->sconn, dev); - ret = net_sem_wait(&state.snd_sem); - conn_dev_lock(&conn->sconn, dev); + ret = conn_dev_sem_timedwait(&state.snd_sem, true, UINT_MAX, + &conn->sconn, dev); /* Make sure that no further events are processed */ @@ -267,9 +267,9 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, return state.snd_sent; } - /* If net_sem_wait failed, then we were probably reawakened by a signal. - * In this case, net_sem_wait will have returned negated errno - * appropriately. + /* If conn_dev_sem_timedwait failed, then we were probably reawakened by a + * signal. In this case, conn_dev_sem_timedwait will have returned negated + * errno appropriately. */ if (ret < 0) diff --git a/net/pkt/pkt_sockif.c b/net/pkt/pkt_sockif.c index e880141a1dbab..02c6fb505bba5 100644 --- a/net/pkt/pkt_sockif.c +++ b/net/pkt/pkt_sockif.c @@ -377,10 +377,9 @@ static int pkt_close(FAR struct socket *psock) while (iob_get_queue_entry_count(&conn->write_q) != 0) { - conn_dev_unlock(&conn->sconn, dev); - ret = net_sem_timedwait_uninterruptible(&conn->sndsem, - _SO_TIMEOUT(conn->sconn.s_sndtimeo)); - conn_dev_lock(&conn->sconn, dev); + ret = conn_dev_sem_timedwait(&conn->sndsem, false, + _SO_TIMEOUT(conn->sconn.s_sndtimeo), + &conn->sconn, dev); if (ret < 0) { break; diff --git a/net/sixlowpan/sixlowpan_internal.h b/net/sixlowpan/sixlowpan_internal.h index 5c169b23204b6..dd053bf1a4a23 100644 --- a/net/sixlowpan/sixlowpan_internal.h +++ b/net/sixlowpan/sixlowpan_internal.h @@ -250,6 +250,7 @@ struct devif_callback_s; /* Forward reference */ struct ipv6_hdr_s; /* Forward reference */ struct netdev_varaddr_s; /* Forward reference */ struct iob_s; /* Forward reference */ +struct udp_conn_s; /* Forward reference */ /**************************************************************************** * Name: sixlowpan_send @@ -284,12 +285,9 @@ struct iob_s; /* Forward reference */ * ****************************************************************************/ -int sixlowpan_send(FAR struct net_driver_s *dev, - FAR struct devif_callback_s **list, - FAR struct devif_callback_s **list_tail, +int sixlowpan_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn, FAR const struct ipv6_hdr_s *ipv6hdr, FAR const void *buf, - size_t len, FAR const struct netdev_varaddr_s *destmac, - unsigned int timeout); + size_t len, FAR const struct netdev_varaddr_s *destmac); /**************************************************************************** * Name: sixlowpan_meta_data diff --git a/net/sixlowpan/sixlowpan_send.c b/net/sixlowpan/sixlowpan_send.c index 0f9e3a2b4c090..0c50a92b90741 100644 --- a/net/sixlowpan/sixlowpan_send.c +++ b/net/sixlowpan/sixlowpan_send.c @@ -36,6 +36,9 @@ #include "netdev/netdev.h" #include "devif/devif.h" +#include "udp/udp.h" +#include "utils/utils.h" +#include "socket/socket.h" #include "sixlowpan/sixlowpan_internal.h" @@ -202,16 +205,14 @@ static uint32_t send_eventhandler(FAR struct net_driver_s *dev, * ****************************************************************************/ -int sixlowpan_send(FAR struct net_driver_s *dev, - FAR struct devif_callback_s **list, - FAR struct devif_callback_s **list_tail, +int sixlowpan_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn, FAR const struct ipv6_hdr_s *ipv6hdr, FAR const void *buf, - size_t len, FAR const struct netdev_varaddr_s *destmac, - unsigned int timeout) + size_t len, FAR const struct netdev_varaddr_s *destmac) { struct sixlowpan_send_s sinfo; - ninfo("len=%lu timeout=%u\n", (unsigned long)len, timeout); + ninfo("len=%lu timeout=%u\n", (unsigned long)len, + (unsigned int)_SO_TIMEOUT(conn->sconn.s_sndtimeo)); /* Initialize the send state structure */ @@ -223,7 +224,7 @@ int sixlowpan_send(FAR struct net_driver_s *dev, sinfo.s_buf = buf; sinfo.s_len = len; - net_lock(); + conn_dev_lock(&conn->sconn, dev); if (len > 0) { /* Allocate resources to receive a callback. @@ -232,7 +233,8 @@ int sixlowpan_send(FAR struct net_driver_s *dev, * device related events, no connect-related events. */ - sinfo.s_cb = devif_callback_alloc(dev, list, list_tail); + sinfo.s_cb = devif_callback_alloc(dev, &conn->sconn.list, + &conn->sconn.list_tail); if (sinfo.s_cb != NULL) { int ret; @@ -248,12 +250,15 @@ int sixlowpan_send(FAR struct net_driver_s *dev, netdev_txnotify_dev(dev, UDP_POLL); /* Wait for the send to complete or an error to occur. - * net_sem_timedwait will also terminate if a signal is received. + * conn_dev_sem_timedwait will also terminate if a signal is + * received. */ ninfo("Wait for send complete\n"); - ret = net_sem_timedwait(&sinfo.s_waitsem, timeout); + ret = conn_dev_sem_timedwait(&sinfo.s_waitsem, true, + _SO_TIMEOUT(conn->sconn.s_sndtimeo), + &conn->sconn, dev); if (ret < 0) { if (ret == -ETIMEDOUT) @@ -267,12 +272,13 @@ int sixlowpan_send(FAR struct net_driver_s *dev, /* Make sure that no further events are processed */ - devif_conn_callback_free(dev, sinfo.s_cb, list, list_tail); + devif_conn_callback_free(dev, sinfo.s_cb, &conn->sconn.list, + &conn->sconn.list_tail); } } nxsem_destroy(&sinfo.s_waitsem); - net_unlock(); + conn_dev_unlock(&conn->sconn, dev); return (sinfo.s_result < 0 ? sinfo.s_result : len); } diff --git a/net/sixlowpan/sixlowpan_tcpsend.c b/net/sixlowpan/sixlowpan_tcpsend.c index 043a239b6eb67..6e8151cf1508d 100644 --- a/net/sixlowpan/sixlowpan_tcpsend.c +++ b/net/sixlowpan/sixlowpan_tcpsend.c @@ -597,7 +597,7 @@ static int sixlowpan_send_packet(FAR struct socket *psock, memset(&sinfo, 0, sizeof(struct sixlowpan_send_s)); - net_lock(); + conn_dev_lock(&conn->sconn, dev); if (len > 0) { /* Allocate resources to receive a callback. @@ -643,7 +643,8 @@ static int sixlowpan_send_packet(FAR struct socket *psock, netdev_txnotify_dev(dev, TCP_POLL); /* Wait for the send to complete or an error to occur. - * net_sem_timedwait will also terminate if a signal is received. + * conn_dev_sem_timedwait will also terminate if a signal is + * received. */ ninfo("Wait for send complete\n"); @@ -652,7 +653,8 @@ static int sixlowpan_send_packet(FAR struct socket *psock, { uint32_t acked = sinfo.s_acked; - ret = net_sem_timedwait(&sinfo.s_waitsem, timeout); + ret = conn_dev_sem_timedwait(&sinfo.s_waitsem, true, timeout, + &conn->sconn, dev); if (ret != -ETIMEDOUT || acked == sinfo.s_acked) { if (ret == -ETIMEDOUT) @@ -676,7 +678,7 @@ static int sixlowpan_send_packet(FAR struct socket *psock, } nxsem_destroy(&sinfo.s_waitsem); - net_unlock(); + conn_dev_unlock(&conn->sconn, dev); return (sinfo.s_result < 0 ? sinfo.s_result : len); } diff --git a/net/sixlowpan/sixlowpan_udpsend.c b/net/sixlowpan/sixlowpan_udpsend.c index 70ae8c5400d09..077f19b96832d 100644 --- a/net/sixlowpan/sixlowpan_udpsend.c +++ b/net/sixlowpan/sixlowpan_udpsend.c @@ -295,12 +295,8 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, * packet. */ - ret = sixlowpan_send(dev, - &conn->sconn.list, - &conn->sconn.list_tail, - (FAR const struct ipv6_hdr_s *)&ipv6udp, - buf, buflen, &destmac, - _SO_TIMEOUT(conn->sconn.s_sndtimeo)); + ret = sixlowpan_send(dev, conn, (FAR const struct ipv6_hdr_s *)&ipv6udp, + buf, buflen, &destmac); if (ret < 0) { nerr("ERROR: sixlowpan_send() failed: %d\n", ret); diff --git a/net/tcp/tcp_accept.c b/net/tcp/tcp_accept.c index a2fb6135b35dd..38e31ec0106b0 100644 --- a/net/tcp/tcp_accept.c +++ b/net/tcp/tcp_accept.c @@ -272,12 +272,11 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr, conn->accept = accept_eventhandler; /* Wait for the send to complete or an error to occur: NOTES: - * net_sem_wait will also terminate if a signal is received. + * conn_dev_sem_timedwait will also terminate if a signal is received. */ - conn_unlock(&conn->sconn); - ret = net_sem_wait(&state.acpt_sem); - conn_lock(&conn->sconn); + ret = conn_dev_sem_timedwait(&state.acpt_sem, true, UINT_MAX, + &conn->sconn, NULL); /* Make sure that no further events are processed */ @@ -296,9 +295,9 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr, ret = -state.acpt_result; } - /* If net_sem_wait failed, then we were probably reawakened by a - * signal. In this case, net_sem_wait will have returned negated - * errno appropriately. + /* If conn_dev_sem_timedwait failed, then we were probably reawakened + * by a signal. In this case, conn_dev_sem_timedwait will have + * returned negated errno appropriately. */ if (ret < 0) diff --git a/net/tcp/tcp_connect.c b/net/tcp/tcp_connect.c index abc2e12711e18..f3858c69990fd 100644 --- a/net/tcp/tcp_connect.c +++ b/net/tcp/tcp_connect.c @@ -383,22 +383,23 @@ int psock_tcp_connect(FAR struct socket *psock, /* Wait for either the connect to complete or for an * error/timeout to occur. - * NOTES: net_sem_wait will also terminate if a + * NOTES: conn_dev_sem_timedwait will also terminate if a * signal is received. */ - conn_dev_unlock(&conn->sconn, conn->dev); tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info); - ret = net_sem_wait(&state.tc_sem); + ret = conn_dev_sem_timedwait(&state.tc_sem, true, UINT_MAX, + &conn->sconn, conn->dev); tls_cleanup_pop(tls_get_info(), 0); - conn_dev_lock(&conn->sconn, conn->dev); /* Uninitialize the state structure */ nxsem_destroy(&state.tc_sem); - /* If net_sem_wait failed, negated errno was returned. */ + /* If conn_dev_sem_timedwait failed, negated errno was + * returned. + */ if (ret >= 0) { diff --git a/net/tcp/tcp_recvfrom.c b/net/tcp/tcp_recvfrom.c index 736fc12c13162..bfa3b03847f62 100644 --- a/net/tcp/tcp_recvfrom.c +++ b/net/tcp/tcp_recvfrom.c @@ -576,7 +576,7 @@ static void tcp_recvfrom_initialize(FAR struct tcp_conn_s *conn, * Evaluate the result of the recv operations * * Input Parameters: - * result The result of the net_sem_timedwait operation + * result The result of the conn_dev_sem_timedwait operation * (may indicate EINTR) * pstate A pointer to the state structure to be initialized * @@ -801,18 +801,17 @@ static ssize_t tcp_recvfrom_one(FAR struct tcp_conn_s *conn, FAR void *buf, info.tc_conn = conn; info.tc_cb = &state.ir_cb; info.tc_sem = &state.ir_sem; - conn_dev_unlock(&conn->sconn, conn->dev); tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info); /* Wait for either the receive to complete or for an - * error/timeout to occur. net_sem_timedwait will also + * error/timeout to occur. conn_dev_sem_timedwait will also * terminate if a signal is received. */ - ret = net_sem_timedwait(&state.ir_sem, - _SO_TIMEOUT(conn->sconn.s_rcvtimeo)); + ret = conn_dev_sem_timedwait(&state.ir_sem, true, + _SO_TIMEOUT(conn->sconn.s_rcvtimeo), + &conn->sconn, conn->dev); tls_cleanup_pop(tls_get_info(), 0); - conn_dev_lock(&conn->sconn, conn->dev); if (ret == -ETIMEDOUT) { ret = -EAGAIN; @@ -837,11 +836,7 @@ static ssize_t tcp_recvfrom_one(FAR struct tcp_conn_s *conn, FAR void *buf, if (tcp_should_send_recvwindow(conn)) { - conn_unlock(&conn->sconn); - netdev_lock(conn->dev); netdev_txnotify_dev(conn->dev, TCP_POLL); - netdev_unlock(conn->dev); - conn_lock(&conn->sconn); } tcp_notify_recvcpu(conn); diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index 5ab17b54c91b3..35b510e77db11 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -1475,13 +1475,12 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf, info.tc_conn = conn; info.tc_cb = &conn->sndcb; info.tc_sem = &conn->snd_sem; - conn_dev_unlock(&conn->sconn, conn->dev); tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info); - ret = net_sem_timedwait_uninterruptible(&conn->snd_sem, - tcp_send_gettimeout(start, timeout)); + ret = conn_dev_sem_timedwait(&conn->snd_sem, false, + tcp_send_gettimeout(start, timeout), + &conn->sconn, conn->dev); tls_cleanup_pop(tls_get_info(), 0); - conn_dev_lock(&conn->sconn, conn->dev); if (ret < 0) { if (ret == -ETIMEDOUT) diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index 77a62ef30ad96..d7217f24573e7 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -607,7 +607,8 @@ ssize_t psock_tcp_send(FAR struct socket *psock, tcp_send_txnotify(psock, conn); /* Wait for the send to complete or an error to occur: NOTES: - * net_sem_wait will also terminate if a signal is received. + * conn_dev_sem_timedwait will also terminate if a signal is + * received. */ for (; ; ) @@ -621,13 +622,12 @@ ssize_t psock_tcp_send(FAR struct socket *psock, info.tc_conn = conn; info.tc_cb = &state.snd_cb; info.tc_sem = &state.snd_sem; - conn_dev_unlock(&conn->sconn, conn->dev); tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info); - ret = net_sem_timedwait(&state.snd_sem, - _SO_TIMEOUT(conn->sconn.s_sndtimeo)); + ret = conn_dev_sem_timedwait(&state.snd_sem, true, + _SO_TIMEOUT(conn->sconn.s_sndtimeo), + &conn->sconn, conn->dev); tls_cleanup_pop(tls_get_info(), 0); - conn_dev_lock(&conn->sconn, conn->dev); if (ret != -ETIMEDOUT || acked == state.snd_acked) { if (ret == -ETIMEDOUT) @@ -658,8 +658,8 @@ ssize_t psock_tcp_send(FAR struct socket *psock, goto errout; } - /* If net_sem_timedwait failed, then we were probably reawakened by a - * signal. In this case, net_sem_timedwait will have returned negated + /* If conn_dev_sem_timedwait failed, then we were probably reawakened by a + * signal. In this case, conn_dev_sem_timedwait will have returned negated * errno appropriately. */ diff --git a/net/tcp/tcp_sendfile.c b/net/tcp/tcp_sendfile.c index 0aabc9c88d1f5..455e92eb6be17 100644 --- a/net/tcp/tcp_sendfile.c +++ b/net/tcp/tcp_sendfile.c @@ -525,8 +525,9 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile, { uint32_t acked = state.snd_acked; - ret = net_sem_timedwait_uninterruptible( - &state.snd_sem, _SO_TIMEOUT(conn->sconn.s_sndtimeo)); + ret = conn_dev_sem_timedwait(&state.snd_sem, false, + _SO_TIMEOUT(conn->sconn.s_sndtimeo), + &conn->sconn, conn->dev); if (ret != -ETIMEDOUT || acked == state.snd_acked) { if (ret == -ETIMEDOUT) diff --git a/net/tcp/tcp_txdrain.c b/net/tcp/tcp_txdrain.c index 2ae4760d876c8..95a1f375db64b 100644 --- a/net/tcp/tcp_txdrain.c +++ b/net/tcp/tcp_txdrain.c @@ -145,9 +145,8 @@ int tcp_txdrain(FAR struct socket *psock, unsigned int timeout) * wait for it to drain or be be disconnected. */ - conn_dev_unlock(&conn->sconn, conn->dev); - ret = net_sem_timedwait_uninterruptible(&waitsem, timeout); - conn_dev_lock(&conn->sconn, conn->dev); + ret = conn_dev_sem_timedwait(&waitsem, false, timeout, + &conn->sconn, conn->dev); /* Tear down the disconnect notifier */ diff --git a/net/udp/udp_recvfrom.c b/net/udp/udp_recvfrom.c index 38fbfda7829aa..fabfc2f6cfca4 100644 --- a/net/udp/udp_recvfrom.c +++ b/net/udp/udp_recvfrom.c @@ -562,7 +562,7 @@ static void udp_recvfrom_initialize(FAR struct udp_conn_s *conn, * Evaluate the result of the recv operations * * Input Parameters: - * result The result of the net_sem_timedwait operation + * result The result of the conn_dev_sem_timedwait operation * (may indicate EINTR) * pstate A pointer to the state structure to be initialized * @@ -588,8 +588,8 @@ static ssize_t udp_recvfrom_result(int result, struct udp_recvfrom_s *pstate) return pstate->ir_result; } - /* If net_sem_timedwait failed, then we were probably reawakened by a - * signal. In this case, net_sem_timedwait will have returned negated + /* If conn_dev_sem_timedwait failed, then we were probably reawakened by a + * signal. In this case, conn_dev_sem_timedwait will have returned negated * errno appropriately. */ @@ -765,14 +765,13 @@ ssize_t psock_udp_recvfrom(FAR struct socket *psock, FAR struct msghdr *msg, tls_cleanup_push(tls_get_info(), udp_callback_cleanup, &info); /* Wait for either the receive to complete or for an error/timeout - * to occur. net_sem_timedwait will also terminate if a signal is - * received. + * to occur. conn_dev_sem_timedwait will also terminate if a + * signal is received. */ - conn_dev_unlock(&conn->sconn, dev); - ret = net_sem_timedwait(&state.ir_sem, - _SO_TIMEOUT(conn->sconn.s_rcvtimeo)); - conn_dev_lock(&conn->sconn, dev); + ret = conn_dev_sem_timedwait(&state.ir_sem, true, + _SO_TIMEOUT(conn->sconn.s_rcvtimeo), + &conn->sconn, dev); tls_cleanup_pop(tls_get_info(), 0); if (ret == -ETIMEDOUT) { diff --git a/net/udp/udp_sendto_buffered.c b/net/udp/udp_sendto_buffered.c index 683879577e6cb..d78dd2bf041a7 100644 --- a/net/udp/udp_sendto_buffered.c +++ b/net/udp/udp_sendto_buffered.c @@ -717,14 +717,15 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, conn_lock(&conn->sconn); while (udp_wrbuffer_inqueue_size(conn) + len > conn->sndbufs) { - conn_unlock(&conn->sconn); if (nonblock) { + conn_unlock(&conn->sconn); return -EAGAIN; } - ret = net_sem_timedwait_uninterruptible(&conn->sndsem, - udp_send_gettimeout(start, timeout)); + ret = conn_dev_sem_timedwait(&conn->sndsem, false, + udp_send_gettimeout(start, timeout), + &conn->sconn, NULL); if (ret < 0) { if (ret == -ETIMEDOUT) @@ -732,10 +733,9 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, ret = -EAGAIN; } + conn_unlock(&conn->sconn); return ret; } - - conn_lock(&conn->sconn); } conn_unlock(&conn->sconn); diff --git a/net/udp/udp_sendto_unbuffered.c b/net/udp/udp_sendto_unbuffered.c index 5eecb9f7402b5..cb95624062af2 100644 --- a/net/udp/udp_sendto_unbuffered.c +++ b/net/udp/udp_sendto_unbuffered.c @@ -480,13 +480,13 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, netdev_txnotify_dev(state.st_dev, UDP_POLL); /* Wait for either the receive to complete or for an error/timeout to - * occur. NOTES: net_sem_timedwait will also terminate if a signal + * occur. NOTES: conn_dev_sem_timedwait will also terminate if a signal * is received. */ - conn_dev_unlock(&conn->sconn, state.st_dev); - ret = net_sem_timedwait(&state.st_sem, - _SO_TIMEOUT(conn->sconn.s_sndtimeo)); + ret = conn_dev_sem_timedwait(&state.st_sem, true, + _SO_TIMEOUT(conn->sconn.s_sndtimeo), + &conn->sconn, state.st_dev); if (ret >= 0) { /* The result of the sendto operation is the number of bytes @@ -496,8 +496,6 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, ret = state.st_sndlen; } - conn_dev_lock(&conn->sconn, state.st_dev); - /* Make sure that no further events are processed */ udp_callback_free(state.st_dev, conn, state.st_cb); diff --git a/net/udp/udp_txdrain.c b/net/udp/udp_txdrain.c index f5013eaa64a6d..3c344a2bf56f9 100644 --- a/net/udp/udp_txdrain.c +++ b/net/udp/udp_txdrain.c @@ -85,9 +85,8 @@ int udp_txdrain(FAR struct socket *psock, unsigned int timeout) if (!sq_empty(&conn->write_q)) { conn->txdrain_sem = &waitsem; - conn_unlock(&conn->sconn); - ret = net_sem_timedwait_uninterruptible(&waitsem, timeout); - conn_lock(&conn->sconn); + ret = conn_dev_sem_timedwait(&waitsem, false, timeout, + &conn->sconn, NULL); conn->txdrain_sem = NULL; } diff --git a/net/utils/net_lock.c b/net/utils/net_lock.c index 60fe754ee8858..913bedd648560 100644 --- a/net/utils/net_lock.c +++ b/net/utils/net_lock.c @@ -395,43 +395,3 @@ FAR struct iob_s *net_ioballoc(bool throttled) return net_iobtimedalloc(throttled, UINT_MAX); } #endif - -/**************************************************************************** - * Name: conn_lock, conn_unlock, conn_dev_lock, conn_dev_unlock - * - * Description: - * Lock and unlock the connection and device. - * - ****************************************************************************/ - -void conn_lock(FAR struct socket_conn_s *sconn) -{ - nxrmutex_lock(&sconn->s_lock); -} - -void conn_unlock(FAR struct socket_conn_s *sconn) -{ - nxrmutex_unlock(&sconn->s_lock); -} - -void conn_dev_lock(FAR struct socket_conn_s *sconn, - FAR struct net_driver_s *dev) -{ - if (dev != NULL) - { - netdev_lock(dev); - } - - nxrmutex_lock(&sconn->s_lock); -} - -void conn_dev_unlock(FAR struct socket_conn_s *sconn, - FAR struct net_driver_s *dev) -{ - nxrmutex_unlock(&sconn->s_lock); - - if (dev != NULL) - { - netdev_unlock(dev); - } -} diff --git a/net/utils/utils.h b/net/utils/utils.h index 0eacf0a59b75d..03fe8d15d2c17 100644 --- a/net/utils/utils.h +++ b/net/utils/utils.h @@ -32,6 +32,7 @@ #include +#include #include #include #include @@ -152,6 +153,69 @@ extern "C" #define EXTERN extern #endif +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: conn_lock, conn_unlock, conn_dev_lock, conn_dev_unlock + * + * Description: + * Lock and unlock the connection and device. + * + ****************************************************************************/ + +static inline_function void conn_lock(FAR struct socket_conn_s *sconn) +{ + nxrmutex_lock(&sconn->s_lock); +} + +static inline_function void conn_unlock(FAR struct socket_conn_s *sconn) +{ + nxrmutex_unlock(&sconn->s_lock); +} + +static inline_function void conn_dev_lock(FAR struct socket_conn_s *sconn, + FAR struct net_driver_s *dev) +{ + if (dev != NULL) + { + netdev_lock(dev); + } + + nxrmutex_lock(&sconn->s_lock); +} + +static inline_function void conn_dev_unlock(FAR struct socket_conn_s *sconn, + FAR struct net_driver_s *dev) +{ + nxrmutex_unlock(&sconn->s_lock); + + if (dev != NULL) + { + netdev_unlock(dev); + } +} + +/**************************************************************************** + * Name: conn_dev_sem_timedwait + * + * Description: + * Wait on the connection semaphore, unlocking the device and connection + * locks while waiting. + * + ****************************************************************************/ + +static inline_function int +conn_dev_sem_timedwait(FAR sem_t *sem, bool interruptible, + unsigned int timeout, FAR struct socket_conn_s *sconn, + FAR struct net_driver_s *dev) +{ + return net_sem_timedwait2(sem, interruptible, timeout, + sconn ? &sconn->s_lock : NULL, + dev ? &dev->d_lock : NULL); +} + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -606,23 +670,6 @@ uint16_t icmpv6_chksum(FAR struct net_driver_s *dev, unsigned int iplen); FAR void *cmsg_append(FAR struct msghdr *msg, int level, int type, FAR void *value, int value_len); -/**************************************************************************** - * Name: conn_lock, conn_unlock, conn_dev_lock, conn_dev_unlock - * - * Description: - * Lock and unlock the connection and device. - * - ****************************************************************************/ - -void conn_lock(FAR struct socket_conn_s *sconn); -void conn_unlock(FAR struct socket_conn_s *sconn); - -void conn_dev_lock(FAR struct socket_conn_s *sconn, - FAR struct net_driver_s *dev); - -void conn_dev_unlock(FAR struct socket_conn_s *sconn, - FAR struct net_driver_s *dev); - #undef EXTERN #ifdef __cplusplus }