diff options
-rw-r--r-- | nuttx/ChangeLog | 1 | ||||
-rw-r--r-- | nuttx/Documentation/NuttX.html | 1 | ||||
-rw-r--r-- | nuttx/sched/timer_create.c | 25 | ||||
-rw-r--r-- | nuttx/sched/timer_delete.c | 27 | ||||
-rw-r--r-- | nuttx/sched/timer_internal.h | 11 | ||||
-rw-r--r-- | nuttx/sched/timer_settime.c | 36 |
6 files changed, 77 insertions, 24 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index ddf3e9e13..f3742881d 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -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. diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html index 43e26d663..c6b94fa59 100644 --- a/nuttx/Documentation/NuttX.html +++ b/nuttx/Documentation/NuttX.html @@ -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> diff --git a/nuttx/sched/timer_create.c b/nuttx/sched/timer_create.c index 645007c9f..a9e19dc2a 100644 --- a/nuttx/sched/timer_create.c +++ b/nuttx/sched/timer_create.c @@ -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); diff --git a/nuttx/sched/timer_delete.c b/nuttx/sched/timer_delete.c index 386807575..e6afc57bf 100644 --- a/nuttx/sched/timer_delete.c +++ b/nuttx/sched/timer_delete.c @@ -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; } + + /* If the watchdog structure is busy now, then just mark it for deletion later */ + + 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) + */ - /* 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); + (void)wd_delete(timer->pt_wdog); - /* Release the timer structure */ + /* Release the timer structure */ - timer_free(timer); + timer_free(timer); + } return OK; } diff --git a/nuttx/sched/timer_internal.h b/nuttx/sched/timer_internal.h index 604adbc8e..e4403499c 100644 --- a/nuttx/sched/timer_internal.h +++ b/nuttx/sched/timer_internal.h @@ -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 diff --git a/nuttx/sched/timer_settime.c b/nuttx/sched/timer_settime.c index 27f7d2af1..ab130210e 100644 --- a/nuttx/sched/timer_settime.c +++ b/nuttx/sched/timer_settime.c @@ -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; + + /* Check if the signal handler attempted to delete the timer */ + + if ((u.timer->pt_flags & PT_FLAGS_DELETED) != 0) + { + /* Yes.. delete the timer now that we are no longer busy */ - /* If this is a repetitive timer, the restart the watchdog */ + timer_delete(u.timer); + } + else + { + /* If this is a repetitive timer, the restart the watchdog */ - timer_restart(u.timer, itimer); + 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 } |