Fix problem when timer deleted by timer handler
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@762 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
b5d6002463
commit
a9b64a7469
@ -365,3 +365,4 @@
|
||||
* Fix several FAT filesystem problems reported by kwonsk (Changes not yet
|
||||
verified).
|
||||
* Host simulator no longer uses Linux system calls directly; Now works with Cygwin.
|
||||
* Fix an error that occurs when a POSIX timer is deleted by the timer signal handler.
|
||||
|
@ -1015,6 +1015,7 @@ nuttx-0.3.11 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
* Fix several FAT filesystem problems reported by kwonsk (Changes not yet
|
||||
verified).
|
||||
* Host simulator no longer uses Linux system calls directly; Now works with Cygwin.
|
||||
* Fix an error that occurs when a POSIX timer is deleted by the timer signal handler.
|
||||
|
||||
pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
|
@ -74,7 +74,8 @@
|
||||
static struct posix_timer_s *timer_allocate(void)
|
||||
{
|
||||
struct posix_timer_s *ret;
|
||||
irqstate_t flags;
|
||||
irqstate_t flags;
|
||||
ubyte pt_flags;
|
||||
|
||||
/* Try to get a preallocated timer from the free list */
|
||||
|
||||
@ -84,23 +85,31 @@ static struct posix_timer_s *timer_allocate(void)
|
||||
irqrestore(flags);
|
||||
|
||||
/* Did we get one? */
|
||||
|
||||
if (!ret)
|
||||
|
||||
if (ret)
|
||||
{
|
||||
pt_flags = PT_FLAGS_PREALLOCATED;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Allocate a new timer from the heap */
|
||||
|
||||
ret = (struct posix_timer_s*)malloc(sizeof(struct posix_timer_s));
|
||||
if (ret)
|
||||
{
|
||||
ret->pt_flags = 0;
|
||||
}
|
||||
ret = (struct posix_timer_s*)malloc(sizeof(struct posix_timer_s));
|
||||
pt_flags = 0;
|
||||
}
|
||||
|
||||
/* If we have a timer, then put it into the allocated timer list */
|
||||
|
||||
if (ret)
|
||||
{
|
||||
/* Initialize the timer structure */
|
||||
|
||||
memset(ret, 0, sizeof(struct posix_timer_s));
|
||||
ret->pt_flags = pt_flags;
|
||||
|
||||
/* And add it to the end of the list of allocated timers */
|
||||
|
||||
flags = irqsave();
|
||||
sq_addlast((sq_entry_t*)ret, (sq_queue_t*)&g_alloctimers);
|
||||
irqrestore(flags);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/********************************************************************************
|
||||
* timer_delete.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -14,7 +14,7 @@
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@ -137,16 +137,25 @@ int timer_delete(timer_t timerid)
|
||||
*get_errno_ptr() = EINVAL;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Free the underlying watchdog instance (the timer will be canceled by the
|
||||
* watchdog logic before it is actually deleted)
|
||||
*/
|
||||
|
||||
(void)wd_delete(timer->pt_wdog);
|
||||
|
||||
/* Release the timer structure */
|
||||
/* If the watchdog structure is busy now, then just mark it for deletion later */
|
||||
|
||||
timer_free(timer);
|
||||
if ((timer->pt_flags & PT_FLAGS_BUSY) != 0)
|
||||
{
|
||||
timer->pt_flags |= PT_FLAGS_DELETED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Free the underlying watchdog instance (the timer will be canceled by the
|
||||
* watchdog logic before it is actually deleted)
|
||||
*/
|
||||
|
||||
(void)wd_delete(timer->pt_wdog);
|
||||
|
||||
/* Release the timer structure */
|
||||
|
||||
timer_free(timer);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/********************************************************************************
|
||||
* timer_internal.h
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -14,7 +14,7 @@
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@ -49,7 +49,12 @@
|
||||
* Definitions
|
||||
********************************************************************************/
|
||||
|
||||
#define PT_FLAGS_PREALLOCATED 0x01
|
||||
#define PT_FLAGS_PREALLOCATED 0x01 /* Timer comes from a pool of preallocated timers */
|
||||
#define PT_FLAGS_BUSY 0x02 /* Timer cannot be deleted now */
|
||||
#define PT_FLAGS_DELETED 0x04 /* Busy timer marked for deletion */
|
||||
|
||||
#define PT_FLAGS_STATIC PT_FLAGS_PREALLOCATED
|
||||
#define PT_FLAGS_DYNAMIC (~PT_FLAGS_STATIC)
|
||||
|
||||
/********************************************************************************
|
||||
* Public Types
|
||||
|
@ -39,7 +39,9 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "clock_internal.h"
|
||||
#include "sig_internal.h"
|
||||
@ -181,21 +183,47 @@ static void timer_timeout(int argc, uint32 itimer)
|
||||
|
||||
/* Send the specified signal to the specified task. */
|
||||
|
||||
u.timer->pt_flags |= PT_FLAGS_BUSY;
|
||||
timer_sigqueue(u.timer);
|
||||
u.timer->pt_flags &= ~PT_FLAGS_BUSY;
|
||||
|
||||
/* If this is a repetitive timer, the restart the watchdog */
|
||||
/* Check if the signal handler attempted to delete the timer */
|
||||
|
||||
timer_restart(u.timer, itimer);
|
||||
if ((u.timer->pt_flags & PT_FLAGS_DELETED) != 0)
|
||||
{
|
||||
/* Yes.. delete the timer now that we are no longer busy */
|
||||
|
||||
timer_delete(u.timer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If this is a repetitive timer, the restart the watchdog */
|
||||
|
||||
timer_restart(u.timer, itimer);
|
||||
}
|
||||
#else
|
||||
FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)itimer;
|
||||
|
||||
/* Send the specified signal to the specified task. */
|
||||
|
||||
timer->pt_flags |= PT_FLAGS_BUSY;
|
||||
timer_sigqueue(timer);
|
||||
timer->pt_flags &= ~PT_FLAGS_BUSY;
|
||||
|
||||
/* If this is a repetitive timer, the restart the watchdog */
|
||||
/* Check if the signal handler attempted to delete the timer */
|
||||
|
||||
timer_restart(timer, itimer);
|
||||
if ((timer->pt_flags & PT_FLAGS_DELETED) != 0)
|
||||
{
|
||||
/* Yes.. delete the timer now that we are no longer busy */
|
||||
|
||||
timer_delete(timer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If this is a repetitive timer, the restart the watchdog */
|
||||
|
||||
timer_restart(timer, itimer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user