9
0
Fork 0

Fix problem when timer deleted by timer handler

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@762 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2008-06-01 17:46:26 +00:00
parent 9ae4a1c91a
commit 471a765be4
6 changed files with 78 additions and 25 deletions

View File

@ -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.

View File

@ -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>

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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
}