diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 760d0488dca..634e1c6a237 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -516,6 +516,31 @@ int net_sem_timedwait_uninterruptible(FAR sem_t *sem, unsigned int timeout); int net_sem_wait_uninterruptible(FAR sem_t *sem); +/**************************************************************************** + * Name: net_sem_timedwait2 + * + * Description: + * Atomically wait for sem (or a timeout) while temporarily releasing + * the lock on the conn and device. + * + * Input Parameters: + * sem - A reference to the semaphore to be taken. + * interruptible - An indication of whether the wait is interruptible + * timeout - The relative time to wait until a timeout is declared. + * mutex1 - The lock to be released during waiting and restored + * later, can be NULL. + * mutex2 - Same as mutex1, but released after mutex1. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int net_sem_timedwait2(FAR sem_t *sem, bool interruptible, + unsigned int timeout, FAR rmutex_t *mutex1, + FAR rmutex_t *mutex2); + #ifdef CONFIG_MM_IOB /**************************************************************************** diff --git a/net/utils/net_lock.c b/net/utils/net_lock.c index 0f9e0f8f9b0..3393762c4e6 100644 --- a/net/utils/net_lock.c +++ b/net/utils/net_lock.c @@ -55,25 +55,36 @@ static rmutex_t g_netlock = NXRMUTEX_INITIALIZER; /**************************************************************************** - * Private Functions + * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: _net_timedwait + * Name: net_sem_timedwait2 ****************************************************************************/ -static int -_net_timedwait(FAR sem_t *sem, bool interruptible, unsigned int timeout) +int net_sem_timedwait2(FAR sem_t *sem, bool interruptible, + unsigned int timeout, FAR rmutex_t *mutex1, + FAR rmutex_t *mutex2) { - unsigned int count; - int blresult; + unsigned int count1 = 0; + unsigned int count2 = 0; + int blresult1 = -ENOENT; + int blresult2 = -ENOENT; int ret; /* Release the network lock, remembering my count. net_breaklock will * return a negated value if the caller does not hold the network lock. */ - blresult = net_breaklock(&count); + if (mutex1 != NULL) + { + blresult1 = nxrmutex_breaklock(mutex1, &count1); + } + + if (mutex2 != NULL) + { + blresult2 = nxrmutex_breaklock(mutex2, &count2); + } /* Now take the semaphore, waiting if so requested. */ @@ -106,18 +117,19 @@ _net_timedwait(FAR sem_t *sem, bool interruptible, unsigned int timeout) /* Recover the network lock at the proper count (if we held it before) */ - if (blresult >= 0) + if (blresult2 >= 0) { - net_restorelock(count); + nxrmutex_restorelock(mutex2, count2); + } + + if (blresult1 >= 0) + { + nxrmutex_restorelock(mutex1, count1); } return ret; } -/**************************************************************************** - * Public Functions - ****************************************************************************/ - /**************************************************************************** * Name: net_lock * @@ -235,7 +247,7 @@ int net_restorelock(unsigned int count) int net_sem_timedwait(FAR sem_t *sem, unsigned int timeout) { - return _net_timedwait(sem, true, timeout); + return net_sem_timedwait2(sem, true, timeout, &g_netlock, NULL); } /**************************************************************************** @@ -364,7 +376,7 @@ int net_mutex_lock(FAR mutex_t *mutex) int net_sem_timedwait_uninterruptible(FAR sem_t *sem, unsigned int timeout) { - return _net_timedwait(sem, false, timeout); + return net_sem_timedwait2(sem, false, timeout, &g_netlock, NULL); } /****************************************************************************