Networking: Clean up and consolidate some clunky stuff by adding new net_timedwait() function

This commit is contained in:
Gregory Nutt 2015-02-09 07:50:10 -06:00
parent e218f620ac
commit 559f1ef825
8 changed files with 82 additions and 55 deletions

View file

@ -221,11 +221,36 @@ void net_unlock(net_lock_t flags);
# define net_unlock(f) irqrestore(f)
#endif
/****************************************************************************
* Function: net_timedwait
*
* Description:
* Atomically wait for sem (or a timeout( while temporarily releasing
* the lock on the network.
*
* Input Parameters:
* sem - A reference to the semaphore to be taken.
* abstime - The absolute time to wait until a timeout is declared.
*
* Returned value:
* The returned value is the same as sem_timedwait(): Zero (OK) is
* returned on success; -1 (ERROR) is returned on a failure with the
* errno value set appropriately.
*
****************************************************************************/
#ifdef CONFIG_NET_NOINTS
struct timespec;
int net_timedwait(sem_t *sem, FAR const struct timespec *abstime);
#else
# define net_timedwait(s,t) sem_timedwait(s,t)
#endif
/****************************************************************************
* Function: net_lockedwait
*
* Description:
* Atomically wait for sem while temporarily releasing g_netlock.
* Atomically wait for sem while temporarily releasing lock on the network.
*
* Input Parameters:
* sem - A reference to the semaphore to be taken.

View file

@ -46,6 +46,7 @@
#include <netinet/in.h>
#include <nuttx/net/net.h>
#include <arch/irq.h>
#include "arp/arp.h"
@ -167,7 +168,7 @@ int arp_wait_cancel(FAR struct arp_notify_s *notify)
*
* Assumptions:
* This function is called from ARP send must execute with the network
* un-locked (interrupts may be disabled to keep the things stable).
* locked.
*
****************************************************************************/
@ -192,11 +193,11 @@ int arp_wait(FAR struct arp_notify_s *notify, FAR struct timespec *timeout)
abstime.tv_nsec -= 1000000000;
}
/* REVISIT: If sem_timedwait() is awakened with signal, we will return
/* REVISIT: If net_timedwait() is awakened with signal, we will return
* the wrong error code.
*/
(void)sem_timedwait(&notify->nt_sem, &abstime);
(void)net_timedwait(&notify->nt_sem, &abstime);
ret = notify->nt_result;
/* Remove our wait structure from the list (we may no longer be at the

View file

@ -190,9 +190,6 @@ int arp_send(in_addr_t ipaddr)
struct arp_notify_s notify;
struct timespec delay;
struct arp_send_s state;
#ifdef CONFIG_NET_NOINTS
irqstate_t flags;
#endif
net_lock_t save;
int ret;
@ -367,15 +364,7 @@ int arp_send(in_addr_t ipaddr)
delay.tv_sec = CONFIG_ARP_SEND_DELAYSEC;
delay.tv_nsec = CONFIG_ARP_SEND_DELAYNSEC;
#ifdef CONFIG_NET_NOINTS
flags = irqsave(); /* Keep things stable */
net_unlock(save); /* Unlock the network with interrupts disabled */
#endif
ret = arp_wait(&notify, &delay);
#ifdef CONFIG_NET_NOINTS
save = net_lock(); /* Re-lock the network with interrupts disabled */
irqrestore(flags);
#endif
/* arp_wait will return OK if and only if the matching ARP response
* is received. Otherwise, it will return -ETIMEDOUT.

View file

@ -278,9 +278,6 @@ static int icmpv6_wait_radvertise(FAR struct net_driver_s *dev,
net_lock_t *save)
{
struct timespec delay;
#ifdef CONFIG_NET_NOINTS
irqstate_t flags;
#endif
int ret;
/* Wait for response to the Router Advertisement to be received. The
@ -291,15 +288,7 @@ static int icmpv6_wait_radvertise(FAR struct net_driver_s *dev,
delay.tv_sec = CONFIG_ICMPv6_AUTOCONF_DELAYSEC;
delay.tv_nsec = CONFIG_ICMPv6_AUTOCONF_DELAYNSEC;
#ifdef CONFIG_NET_NOINTS
flags = irqsave(); /* Keep things stable */
net_unlock(*save); /* Unlock the network with interrupts disabled */
#endif
ret = icmpv6_rwait(notify, &delay);
#ifdef CONFIG_NET_NOINTS
*save = net_lock(); /* Re-lock the network with interrupts disabled */
irqrestore(flags);
#endif
/* icmpv6_wait will return OK if and only if the matching Router
* Advertisement is received. Otherwise, it will return -ETIMEDOUT.

View file

@ -206,9 +206,6 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr)
struct timespec delay;
struct icmpv6_neighbor_s state;
FAR const uint16_t *lookup;
#ifdef CONFIG_NET_NOINTS
irqstate_t flags;
#endif
net_lock_t save;
int ret;
@ -381,15 +378,7 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr)
delay.tv_sec = CONFIG_ICMPv6_NEIGHBOR_DELAYSEC;
delay.tv_nsec = CONFIG_ICMPv6_NEIGHBOR_DELAYNSEC;
#ifdef CONFIG_NET_NOINTS
flags = irqsave(); /* Keep things stable */
net_unlock(save); /* Unlock the network with interrupts disabled */
#endif
ret = icmpv6_wait(&notify, &delay);
#ifdef CONFIG_NET_NOINTS
save = net_lock(); /* Re-lock the network with interrupts disabled */
irqrestore(flags);
#endif
/* icmpv6_wait will return OK if and only if the matching Neighbor
* Advertisement is received. Otherwise, it will return -ETIMEDOUT.

View file

@ -47,6 +47,7 @@
#include <netinet/in.h>
#include <nuttx/net/net.h>
#include <arch/irq.h>
#include "icmpv6/icmpv6.h"
@ -170,8 +171,7 @@ int icmpv6_wait_cancel(FAR struct icmpv6_notify_s *notify)
*
* Assumptions:
* This function is called from icmpv6_neighbor() and must execute with
* the network un-locked (interrupts may be disabled to keep the things
* stable).
* the network locked.
*
****************************************************************************/
@ -197,11 +197,11 @@ int icmpv6_wait(FAR struct icmpv6_notify_s *notify,
abstime.tv_nsec -= 1000000000;
}
/* REVISIT: If sem_timedwait() is awakened with signal, we will return
/* REVISIT: If net_timedwait() is awakened with signal, we will return
* the wrong error code.
*/
(void)sem_timedwait(&notify->nt_sem, &abstime);
(void)net_timedwait(&notify->nt_sem, &abstime);
ret = notify->nt_result;
/* Remove our wait structure from the list (we may no longer be at the

View file

@ -47,6 +47,7 @@
#include <netinet/in.h>
#include <nuttx/net/net.h>
#include <nuttx/net/netdev.h>
#include <arch/irq.h>
@ -264,8 +265,7 @@ int icmpv6_rwait_cancel(FAR struct icmpv6_rnotify_s *notify)
*
* Assumptions:
* This function is called from icmpv6_autoconfig() and must execute with
* the network un-locked (interrupts may be disabled to keep the things
* stable).
* the network locked.
*
****************************************************************************/
@ -293,11 +293,11 @@ int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify,
abstime.tv_nsec -= 1000000000;
}
/* REVISIT: If sem_timedwait() is awakened with signal, we will return
/* REVISIT: If net_timedwait() is awakened with signal, we will return
* the wrong error code.
*/
(void)sem_timedwait(&notify->rn_sem, &abstime);
(void)net_timedwait(&notify->rn_sem, &abstime);
ret = notify->rn_result;
/* Remove our wait structure from the list (we may no longer be at the

View file

@ -173,22 +173,24 @@ void net_unlock(net_lock_t flags)
}
/****************************************************************************
* Function: net_lockedwait
* Function: net_timedwait
*
* Description:
* Atomically wait for sem while temporarily releasing g_netlock.
* Atomically wait for sem (or a timeout( while temporarily releasing
* the lock on the network.
*
* Input Parameters:
* sem - A reference to the semaphore to be taken.
* sem - A reference to the semaphore to be taken.
* abstime - The absolute time to wait until a timeout is declared.
*
* Returned value:
* The returned value is the same as sem_wait(): Zero (OK) is returned
* on success; -1 (ERROR) is returned on a failure with the errno value
* set appropriately.
* The returned value is the same as sem_wait() or sem_timedwait(): Zero
* (OK) is returned on success; -1 (ERROR) is returned on a failure with
* the errno value set appropriately.
*
****************************************************************************/
int net_lockedwait(sem_t *sem)
int net_timedwait(sem_t *sem, FAR const struct timespec *abstime)
{
pid_t me = getpid();
unsigned int count;
@ -206,9 +208,20 @@ int net_lockedwait(sem_t *sem)
g_count = 0;
sem_post(&g_netlock);
/* Now take the semaphore */
/* Now take the semaphore, waiting if so requested. */
ret = sem_wait(sem);
if (abstime)
{
/* Wait until we get the lock or until the timeout expires */
ret = sem_timedwait(sem, abstime);
}
else
{
/* Wait as long as necessary to get the lot */
ret = sem_wait(sem);
}
/* Recover the network lock at the proper count */
@ -224,6 +237,27 @@ int net_lockedwait(sem_t *sem)
sched_unlock();
irqrestore(flags);
return ret;
}
}
/****************************************************************************
* Function: net_lockedwait
*
* Description:
* Atomically wait for sem while temporarily releasing g_netlock.
*
* Input Parameters:
* sem - A reference to the semaphore to be taken.
*
* Returned value:
* The returned value is the same as sem_wait(): Zero (OK) is returned
* on success; -1 (ERROR) is returned on a failure with the errno value
* set appropriately.
*
****************************************************************************/
int net_lockedwait(sem_t *sem)
{
return net_timedwait(sem, NULL);
}
#endif /* CONFIG_NET */