drivers/timers/rtc.c: Protect the RTC state with a semaphore.
This commit is contained in:
parent
dfee842074
commit
a497aebcfa
@ -40,6 +40,7 @@
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -67,6 +68,7 @@ struct rtc_alarminfo_s
|
||||
struct rtc_upperhalf_s
|
||||
{
|
||||
FAR struct rtc_lowerhalf_s *lower; /* Contained lower half driver */
|
||||
sem_t exclsem; /* Supports mutual exclusion */
|
||||
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
uint8_t crefs; /* Number of open references */
|
||||
@ -171,6 +173,7 @@ static void rtc_destroy(FAR struct rtc_upperhalf_s *upper)
|
||||
|
||||
/* And free our container */
|
||||
|
||||
nxsem_destroy(&upper->exclsem);
|
||||
kmm_free(upper);
|
||||
}
|
||||
#endif
|
||||
@ -248,6 +251,7 @@ static int rtc_open(FAR struct file *filep)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct rtc_upperhalf_s *upper;
|
||||
int ret;
|
||||
|
||||
/* Get the reference to our internal state structure from the inode
|
||||
* structure.
|
||||
@ -258,10 +262,19 @@ static int rtc_open(FAR struct file *filep)
|
||||
DEBUGASSERT(inode && inode->i_private);
|
||||
upper = inode->i_private;
|
||||
|
||||
/* Get exclusive access to the device structures */
|
||||
|
||||
ret = nxsem_wait(&upper->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Increment the count of open references on the RTC driver */
|
||||
|
||||
upper->crefs++;
|
||||
DEBUGASSERT(upper->crefs > 0);
|
||||
nxsem_post(&upper->exclsem);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
@ -275,6 +288,7 @@ static int rtc_close(FAR struct file *filep)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct rtc_upperhalf_s *upper;
|
||||
int ret;
|
||||
|
||||
/* Get the reference to our internal state structure from the inode
|
||||
* structure.
|
||||
@ -285,10 +299,19 @@ static int rtc_close(FAR struct file *filep)
|
||||
DEBUGASSERT(inode && inode->i_private);
|
||||
upper = inode->i_private;
|
||||
|
||||
/* Get exclusive access to the device structures */
|
||||
|
||||
ret = nxsem_wait(&upper->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Decrement the count of open references on the RTC driver */
|
||||
|
||||
DEBUGASSERT(upper->crefs > 0);
|
||||
upper->crefs--;
|
||||
nxsem_post(&upper->exclsem);
|
||||
|
||||
/* If the count has decremented to zero and the driver has been unlinked,
|
||||
* then commit Hara-Kiri now.
|
||||
@ -343,6 +366,14 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
upper = inode->i_private;
|
||||
DEBUGASSERT(upper->lower && upper->lower->ops);
|
||||
|
||||
/* Get exclusive access to the device structures */
|
||||
|
||||
ret = nxsem_wait(&upper->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* We simply forward all ioctl() commands to the lower half. The upper
|
||||
* half is nothing more than a thin driver shell over the lower level
|
||||
* RTC implementation.
|
||||
@ -726,6 +757,7 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
break;
|
||||
}
|
||||
|
||||
nxsem_post(&upper->exclsem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -737,6 +769,7 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
static int rtc_unlink(FAR struct inode *inode)
|
||||
{
|
||||
FAR struct rtc_upperhalf_s *upper;
|
||||
int ret;
|
||||
|
||||
/* Get the reference to our internal state structure from the inode
|
||||
* structure.
|
||||
@ -745,9 +778,18 @@ static int rtc_unlink(FAR struct inode *inode)
|
||||
DEBUGASSERT(inode && inode->i_private);
|
||||
upper = inode->i_private;
|
||||
|
||||
/* Get exclusive access to the device structures */
|
||||
|
||||
ret = nxsem_wait(&upper->exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Indicate that the driver has been unlinked */
|
||||
|
||||
upper->unlinked = true;
|
||||
nxsem_post(&upper->exclsem);
|
||||
|
||||
/* If there are no further open references to the driver, then commit
|
||||
* Hara-Kiri now.
|
||||
@ -804,6 +846,7 @@ int rtc_initialize(int minor, FAR struct rtc_lowerhalf_s *lower)
|
||||
/* Initialize the upper half container */
|
||||
|
||||
upper->lower = lower; /* Contain lower half driver */
|
||||
nxsem_init(&upper->exclsem, 0, 1);
|
||||
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
upper->crefs = 0; /* No open references */
|
||||
@ -821,6 +864,7 @@ int rtc_initialize(int minor, FAR struct rtc_lowerhalf_s *lower)
|
||||
ret = register_driver(devpath, &rtc_fops, 0666, upper);
|
||||
if (ret < 0)
|
||||
{
|
||||
nxsem_destroy(&upper->exclsem);
|
||||
kmm_free(upper);
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user