drivers/timers/rtc.c: Protect the timer state with a semaphore.

This commit is contained in:
Xiang Xiao 2019-01-27 10:08:18 -06:00 committed by Gregory Nutt
parent a497aebcfa
commit 1c75aa76f0

View File

@ -67,6 +67,7 @@
struct timer_upperhalf_s
{
sem_t exclsem; /* Supports mutual exclusion */
uint8_t crefs; /* The number of times the device has been opened */
uint8_t signo; /* The signal number to use in the notification */
pid_t pid; /* The ID of the task/thread to receive the signal */
@ -164,6 +165,14 @@ static int timer_open(FAR struct file *filep)
tmrinfo("crefs: %d\n", upper->crefs);
/* Get exclusive access to the device structures */
ret = nxsem_wait(&upper->exclsem);
if (ret < 0)
{
goto errout;
}
/* Increment the count of references to the device. If this the first
* time that the driver has been opened for this device, then initialize
* the device.
@ -175,7 +184,7 @@ static int timer_open(FAR struct file *filep)
/* More than 255 opens; uint8_t overflows to zero */
ret = -EMFILE;
goto errout;
goto errout_with_sem;
}
/* Save the new open count */
@ -183,6 +192,9 @@ static int timer_open(FAR struct file *filep)
upper->crefs = tmp;
ret = OK;
errout_with_sem:
nxsem_post(&upper->exclsem);
errout:
return ret;
}
@ -199,9 +211,18 @@ static int timer_close(FAR struct file *filep)
{
FAR struct inode *inode = filep->f_inode;
FAR struct timer_upperhalf_s *upper = inode->i_private;
int ret;
tmrinfo("crefs: %d\n", upper->crefs);
/* Get exclusive access to the device structures */
ret = nxsem_wait(&upper->exclsem);
if (ret < 0)
{
return ret;
}
/* Decrement the references to the driver. If the reference count will
* decrement to 0, then uninitialize the driver.
*/
@ -211,6 +232,7 @@ static int timer_close(FAR struct file *filep)
upper->crefs--;
}
nxsem_post(&upper->exclsem);
return OK;
}
@ -265,6 +287,14 @@ static int timer_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
lower = upper->lower;
DEBUGASSERT(lower != NULL);
/* Get exclusive access to the device structures */
ret = nxsem_wait(&upper->exclsem);
if (ret < 0)
{
return ret;
}
/* Handle built-in ioctl commands */
switch (cmd)
@ -433,6 +463,7 @@ static int timer_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
break;
}
nxsem_post(&upper->exclsem);
return ret;
}
@ -490,6 +521,7 @@ FAR void *timer_register(FAR const char *path,
*/
upper->lower = lower;
nxsem_init(&upper->exclsem, 0, 1);
/* Copy the registration path */
@ -515,6 +547,7 @@ errout_with_path:
kmm_free(upper->path);
errout_with_upper:
nxsem_destroy(&upper->exclsem);
kmm_free(upper);
errout:
@ -560,6 +593,7 @@ void timer_unregister(FAR void *handle)
/* Then free all of the driver resources */
nxsem_destroy(&upper->exclsem);
kmm_free(upper->path);
kmm_free(upper);
}