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