summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/ChangeLog1
-rw-r--r--nuttx/Documentation/NuttX.html1
-rw-r--r--nuttx/sched/timer_create.c25
-rw-r--r--nuttx/sched/timer_delete.c27
-rw-r--r--nuttx/sched/timer_internal.h11
-rw-r--r--nuttx/sched/timer_settime.c36
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
}