summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-01-31 23:39:12 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-01-31 23:39:12 +0000
commitd9e1bd9b855de8783076cddae7e17177d071a8b5 (patch)
tree4ec59e18f087faba4945cf1bb1d7855d44e82080
parentc0191ed21b7cb6f978fbde31d7e106a8c801ee03 (diff)
downloadnuttx-d9e1bd9b855de8783076cddae7e17177d071a8b5.tar.gz
nuttx-d9e1bd9b855de8783076cddae7e17177d071a8b5.tar.bz2
nuttx-d9e1bd9b855de8783076cddae7e17177d071a8b5.zip
Add on_exit(); Re-order some logic in the task shutdown sequence. Sometimes some complex logic needs to execute when closing file descriptors and this needs to happen early while the task is still healthy
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4354 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--apps/include/netutils/telnetd.h9
-rw-r--r--apps/netutils/telnetd/telnetd_driver.c19
-rw-r--r--nuttx/ChangeLog6
-rw-r--r--nuttx/Documentation/NuttxUserGuide.html2
-rw-r--r--nuttx/fs/fs_files.c29
-rw-r--r--nuttx/include/nuttx/sched.h16
-rw-r--r--nuttx/include/stdlib.h11
-rw-r--r--nuttx/sched/Makefile14
-rw-r--r--nuttx/sched/atexit.c12
-rw-r--r--nuttx/sched/on_exit.c127
-rw-r--r--nuttx/sched/sched_releasefiles.c37
-rw-r--r--nuttx/sched/task_delete.c17
-rw-r--r--nuttx/sched/task_exithook.c50
13 files changed, 266 insertions, 83 deletions
diff --git a/apps/include/netutils/telnetd.h b/apps/include/netutils/telnetd.h
index f875a5edc..4cddd92dd 100644
--- a/apps/include/netutils/telnetd.h
+++ b/apps/include/netutils/telnetd.h
@@ -47,9 +47,6 @@
****************************************************************************/
/* CONFIG_TELNETD_CONSOLE - Use the first telnet session as the default
* console.
- * CONFIG_TELNETD_NPOLLWAITERS - If the poll method is enabled, then this
- * value will defined the maximum number of threads that can be waiting
- * for events. Default: 1
* CONFIG_TELNETD_RXBUFFER_SIZE - The size of the telnet receive buffer.
* Default: 256 bytes.
* CONFIG_TELNETD_TXBUFFER_SIZE - The size of the telnet transmit buffer.
@@ -57,12 +54,6 @@
* CONFIG_TELNETD_DUMPBUFFER - dumping of all input/output buffers.
*/
-#ifndef CONFIG_TELNETD_NPOLLWAITERS
-# define CONFIG_TELNETD_NPOLLWAITERS 1
-#endif
-
-/* Configurable settings */
-
#ifndef CONFIG_TELNETD_RXBUFFER_SIZE
# define CONFIG_TELNETD_RXBUFFER_SIZE 256
#endif
diff --git a/apps/netutils/telnetd/telnetd_driver.c b/apps/netutils/telnetd/telnetd_driver.c
index 1950c881b..56a98a2f6 100644
--- a/apps/netutils/telnetd/telnetd_driver.c
+++ b/apps/netutils/telnetd/telnetd_driver.c
@@ -122,13 +122,14 @@ static inline void telnetd_dumpbuffer(FAR const char *msg,
#else
# define telnetd_dumpbuffer(msg,buffer,nbytes)
#endif
-static void telnetd_getchar(struct telnetd_dev_s *priv, uint8_t ch,
+static void telnetd_getchar(FAR struct telnetd_dev_s *priv, uint8_t ch,
FAR char *dest, int *nread);
-static ssize_t telnetd_receive(struct telnetd_dev_s *priv, FAR const char *src,
- size_t srclen, FAR char *dest, size_t destlen);
-static bool telnetd_putchar(struct telnetd_dev_s *priv, uint8_t ch,
+static ssize_t telnetd_receive(FAR struct telnetd_dev_s *priv,
+ FAR const char *src, size_t srclen, FAR char *dest,
+ size_t destlen);
+static bool telnetd_putchar(FAR struct telnetd_dev_s *priv, uint8_t ch,
int *nwritten);
-static void telnetd_sendopt(struct telnetd_dev_s *priv, uint8_t option,
+static void telnetd_sendopt(FAR struct telnetd_dev_s *priv, uint8_t option,
uint8_t value);
/* Character driver methods */
@@ -190,7 +191,7 @@ static inline void telnetd_dumpbuffer(FAR const char *msg,
*
****************************************************************************/
-static void telnetd_getchar(struct telnetd_dev_s *priv, uint8_t ch,
+static void telnetd_getchar(FAR struct telnetd_dev_s *priv, uint8_t ch,
FAR char *dest, int *nread)
{
register int index;
@@ -215,7 +216,7 @@ static void telnetd_getchar(struct telnetd_dev_s *priv, uint8_t ch,
*
****************************************************************************/
-static ssize_t telnetd_receive(struct telnetd_dev_s *priv, FAR const char *src,
+static ssize_t telnetd_receive(FAR struct telnetd_dev_s *priv, FAR const char *src,
size_t srclen, FAR char *dest, size_t destlen)
{
int nread;
@@ -336,7 +337,7 @@ static ssize_t telnetd_receive(struct telnetd_dev_s *priv, FAR const char *src,
*
****************************************************************************/
-static bool telnetd_putchar(struct telnetd_dev_s *priv, uint8_t ch,
+static bool telnetd_putchar(FAR struct telnetd_dev_s *priv, uint8_t ch,
int *nread)
{
register int index;
@@ -379,7 +380,7 @@ static bool telnetd_putchar(struct telnetd_dev_s *priv, uint8_t ch,
*
****************************************************************************/
-static void telnetd_sendopt(struct telnetd_dev_s *priv, uint8_t option,
+static void telnetd_sendopt(FAR struct telnetd_dev_s *priv, uint8_t option,
uint8_t value)
{
uint8_t optbuf[4];
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 5e4b902b5..e60b6689a 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -2416,3 +2416,9 @@
This upsets C++ if usb.h is included. 'class' -> 'classid' in this header
file and all places that referenced 'class'
* drivers/usbdev/usbmsc.c: Fixed some backward conditional compilation.
+ * sched/on_exit.c: Add support for the on_exit() function.,
+ * sched/exit.c, task_exithook.c, task_delete.c, sched_releasetcb.c: Move
+ the logic that closes file descriptors sooner in the task shutdown sequence.
+ When drivers are closed, they may need to do things that require a fully
+ up-and-running task. Some things cannot be done later when the task is
+ crippled.
diff --git a/nuttx/Documentation/NuttxUserGuide.html b/nuttx/Documentation/NuttxUserGuide.html
index 09407bfb0..78f79b382 100644
--- a/nuttx/Documentation/NuttxUserGuide.html
+++ b/nuttx/Documentation/NuttxUserGuide.html
@@ -478,7 +478,7 @@ VxWorks provides the following similar interface:
<b>Description:</b> This function causes the calling task to cease
to exist -- its stack and TCB will be deallocated. exit differs from
_exit in that it flushes streams, closes file descriptors and will
-execute any function registered with atexit().
+execute any function registered with <code>atexit()</code> or <code>on_exit()</code>.
<p>
<b>Input Parameters:</b>
<ul>
diff --git a/nuttx/fs/fs_files.c b/nuttx/fs/fs_files.c
index 1444d8805..066c9a4ef 100644
--- a/nuttx/fs/fs_files.c
+++ b/nuttx/fs/fs_files.c
@@ -1,8 +1,8 @@
/****************************************************************************
* fs/fs_files.c
*
- * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -74,6 +74,7 @@
/****************************************************************************
* Name: _files_semtake
****************************************************************************/
+
static void _files_semtake(FAR struct filelist *list)
{
/* Take the semaphore (perhaps waiting) */
@@ -91,6 +92,7 @@ static void _files_semtake(FAR struct filelist *list)
/****************************************************************************
* Name: _files_semgive
****************************************************************************/
+
#define _files_semgive(list) sem_post(&list->fl_sem)
/****************************************************************************
@@ -103,6 +105,7 @@ static void _files_semtake(FAR struct filelist *list)
* Caller holds the list semaphore because the file descriptor will be freed.
*
****************************************************************************/
+
static int _files_close(FAR struct file *filep)
{
struct inode *inode = filep->f_inode;
@@ -145,6 +148,7 @@ static int _files_close(FAR struct file *filep)
* This is called from the FS initialization logic to configure the files.
*
****************************************************************************/
+
void files_initialize(void)
{
}
@@ -155,6 +159,7 @@ void files_initialize(void)
* Description: Allocate a list of files for a new task
*
****************************************************************************/
+
FAR struct filelist *files_alloclist(void)
{
FAR struct filelist *list;
@@ -178,6 +183,7 @@ FAR struct filelist *files_alloclist(void)
* Description: Increase the reference count on a file list
*
****************************************************************************/
+
int files_addreflist(FAR struct filelist *list)
{
if (list)
@@ -257,6 +263,7 @@ int files_releaselist(FAR struct filelist *list)
* Assign an inode to a specific files structure. This is the heart of dup2.
*
****************************************************************************/
+
int files_dup(FAR struct file *filep1, FAR struct file *filep2)
{
FAR struct filelist *list;
@@ -402,12 +409,13 @@ int files_allocate(FAR struct inode *inode, int oflags, off_t pos, int minfd)
* Caller holds the list semaphore because the file descriptor will be freed.
*
****************************************************************************/
+
int files_close(int filedes)
{
- FAR struct filelist *list;
- int ret;
+ FAR struct filelist *list;
+ int ret;
- /* Get the thread-specific file list */
+ /* Get the thread-specific file list */
list = sched_getfiles();
if (!list)
@@ -422,12 +430,12 @@ int files_close(int filedes)
return -EBADF;
}
- /* Perform the protected close operation */
+ /* Perform the protected close operation */
- _files_semtake(list);
- ret = _files_close(&list->fl_files[filedes]);
- _files_semgive(list);
- return ret;
+ _files_semtake(list);
+ ret = _files_close(&list->fl_files[filedes]);
+ _files_semgive(list);
+ return ret;
}
/****************************************************************************
@@ -438,6 +446,7 @@ int files_close(int filedes)
* conditions.
*
****************************************************************************/
+
void files_release(int filedes)
{
FAR struct filelist *list;
diff --git a/nuttx/include/nuttx/sched.h b/nuttx/include/nuttx/sched.h
index 7d5fe16bf..4cfca9dbc 100644
--- a/nuttx/include/nuttx/sched.h
+++ b/nuttx/include/nuttx/sched.h
@@ -133,12 +133,16 @@ union entry_u
};
typedef union entry_u entry_t;
-/* This is the type of the function that is executed with exit() is called
- * (if registered via atexit()).
+/* These is the types of the functions that are executed with exit() is called
+ * (if registered via atexit() on on_exit()).
*/
#ifdef CONFIG_SCHED_ATEXIT
-typedef void (*exitfunc_t)(void);
+typedef void (*atexitfunc_t)(void);
+#endif
+
+#ifdef CONFIG_SCHED_ONEXIT
+typedef void (*onexitfunc_t)(int, FAR void *)
#endif
/* POSIX Message queue */
@@ -185,7 +189,11 @@ struct _TCB
start_t start; /* Thread start function */
entry_t entry; /* Entry Point into the thread */
#ifdef CONFIG_SCHED_ATEXIT
- exitfunc_t exitfunc; /* Called if exit is called. */
+ atexitfunc_t atexitfunc; /* Called if exit is called. */
+#endif
+#ifdef CONFIG_SCHED_ONEXIT
+ onexitfunc_t onexitfunc; /* Called if exit is called. */
+ FAR void *onexitarg; /* The argument passed to the function */
#endif
#ifdef CONFIG_SCHED_WAITPID /* Experimental */
sem_t exitsem; /* Support for waitpid */
diff --git a/nuttx/include/stdlib.h b/nuttx/include/stdlib.h
index b9b9346b5..27696e0fa 100644
--- a/nuttx/include/stdlib.h
+++ b/nuttx/include/stdlib.h
@@ -1,8 +1,8 @@
/****************************************************************************
* include/stdlib.h
*
- * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -132,7 +132,12 @@ EXTERN int unsetenv(const char *name);
EXTERN void exit(int status) noreturn_function;
EXTERN void abort(void) noreturn_function;
-EXTERN int atexit(void (*func)(void));
+#ifdef CONFIG_SCHED_ATEXIT
+EXTERN int atexit(CODE void (*func)(void));
+#endif
+#ifdef CONFIG_SCHED_ONEXIT
+EXTERN int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg);
+#endif
/* String to binary conversions */
diff --git a/nuttx/sched/Makefile b/nuttx/sched/Makefile
index 39a526eda..b8a1bb519 100644
--- a/nuttx/sched/Makefile
+++ b/nuttx/sched/Makefile
@@ -1,8 +1,8 @@
############################################################################
# sched/Makefile
#
-# Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+# Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -45,7 +45,7 @@ MISC_SRCS = os_start.c os_bringup.c errno_getptr.c errno_get.c errno_set.c \
TSK_SRCS = task_create.c task_init.c task_setup.c task_activate.c \
task_start.c task_delete.c task_deletecurrent.c task_exithook.c \
- task_restart.c exit.c atexit.c getpid.c sched_addreadytorun.c \
+ task_restart.c exit.c getpid.c sched_addreadytorun.c \
sched_removereadytorun.c sched_addprioritized.c sched_mergepending.c \
sched_addblocked.c sched_removeblocked.c sched_free.c sched_gettcb.c \
sched_verifytcb.c sched_releasetcb.c
@@ -55,6 +55,14 @@ SCHED_SRCS = sched_setparam.c sched_setpriority.c sched_getparam.c \
sched_yield.c sched_rrgetinterval.c sched_foreach.c \
sched_lock.c sched_unlock.c sched_lockcount.c sched_self.c
+ifeq ($(CONFIG_SCHED_ATEXIT),y)
+SCHED_SRCS += atexit.c
+endif
+
+ifeq ($(CONFIG_SCHED_ONEXIT),y)
+SCHED_SRCS += on_exit.c
+endif
+
ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
SCHED_SRCS += sched_reprioritize.c
endif
diff --git a/nuttx/sched/atexit.c b/nuttx/sched/atexit.c
index 3a116f4c1..da1be1c2a 100644
--- a/nuttx/sched/atexit.c
+++ b/nuttx/sched/atexit.c
@@ -1,8 +1,8 @@
/************************************************************************
* sched/atexit.c
*
- * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ * Copyright (C) 2007, 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -52,7 +52,7 @@
#ifdef CONFIG_SCHED_ATEXIT
/************************************************************************
- * Definitions
+ * Pre-processor Definitions
************************************************************************/
/************************************************************************
@@ -72,7 +72,7 @@
************************************************************************/
/************************************************************************
- * Private Functionss
+ * Private Functions
************************************************************************/
/************************************************************************
@@ -101,9 +101,9 @@ int atexit(void (*func)(void))
/* The following must be atomic */
sched_lock();
- if (func && !tcb->exitfunc)
+ if (func && !tcb->atexitfunc)
{
- tcb->exitfunc = func;
+ tcb->atexitfunc = func;
ret = OK;
}
diff --git a/nuttx/sched/on_exit.c b/nuttx/sched/on_exit.c
new file mode 100644
index 000000000..9824ec735
--- /dev/null
+++ b/nuttx/sched/on_exit.c
@@ -0,0 +1,127 @@
+/************************************************************************
+ * sched/on_exit.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/fs.h>
+
+#include "os_internal.h"
+
+#ifdef CONFIG_SCHED_ONEXIT
+
+/************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Function: atexit
+ *
+ * Description:
+ * Registers a function to be called at program exit.
+ * The on_exit() function registers the given function to be called
+ * at normal process termination, whether via exit or via return from
+ * the program's main(). The function is passed the status argument
+ * given to the last call to exit and the arg argument from on_exit().
+ *
+ * Limitiations in the current implementation:
+ *
+ * 1. Only a single on_exit function can be registered.
+ * 2. on_exit functions are not inherited when a new task is
+ * created.
+ *
+ * Parameters:
+ * func
+ *
+ * Return Value:
+ * Zero on success. Non-zero on failure.
+ *
+ ************************************************************************/
+
+int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg)
+{
+ _TCB *tcb = (_TCB*)g_readytorun.head;
+ int ret = ERROR;
+
+ /* The following must be atomic */
+
+ sched_lock();
+ if (func && !tcb->onexitfunc)
+ {
+ tcb->onexitfunc = func;
+ tdb->onexitarg = arg;
+ ret = OK;
+ }
+
+ sched_unlock();
+ return ret;
+}
+
+#endif /* CONFIG_SCHED_ATEXIT */
+
+
diff --git a/nuttx/sched/sched_releasefiles.c b/nuttx/sched/sched_releasefiles.c
index 160b0fb42..3990cd3c6 100644
--- a/nuttx/sched/sched_releasefiles.c
+++ b/nuttx/sched/sched_releasefiles.c
@@ -1,8 +1,8 @@
/****************************************************************************
* sched/sched_releasefiles.c
*
- * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ * Copyright (C) 2007, 2008, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -58,7 +58,10 @@
* Function: sched_releasefiles
*
* Description:
- * Release file resources attached to a TCB.
+ * Release file resources attached to a TCB. This file may be called
+ * multiple times as a task exists. It will be called as early as possible
+ * to support proper closing of complex drivers that may need to wait
+ * on external events.
*
* Parameters:
* tcb - tcb of the new task.
@@ -75,25 +78,33 @@ int sched_releasefiles(_TCB *tcb)
if (tcb)
{
#if CONFIG_NFILE_DESCRIPTORS > 0
- /* Free the file descriptor list */
+ /* Free the file descriptor list */
- files_releaselist(tcb->filelist);
- tcb->filelist = NULL;
+ if (tcb->filelist)
+ {
+ files_releaselist(tcb->filelist);
+ tcb->filelist = NULL;
+ }
#if CONFIG_NFILE_STREAMS > 0
- /* Free the stream list */
+ /* Free the stream list */
- lib_releaselist(tcb->streams);
- tcb->streams = NULL;
+ if (tcb->streams)
+ {
+ lib_releaselist(tcb->streams);
+ tcb->streams = NULL;
+ }
#endif /* CONFIG_NFILE_STREAMS */
#endif /* CONFIG_NFILE_DESCRIPTORS */
#if CONFIG_NSOCKET_DESCRIPTORS > 0
- /* Free the file descriptor list */
-
- net_releaselist(tcb->sockets);
- tcb->sockets = NULL;
+ /* Free the file descriptor list */
+ if (tcb->sockets)
+ {
+ net_releaselist(tcb->sockets);
+ tcb->sockets = NULL;
+ }
#endif /* CONFIG_NSOCKET_DESCRIPTORS */
}
return OK;
diff --git a/nuttx/sched/task_delete.c b/nuttx/sched/task_delete.c
index 31715051a..4cd2b3ba7 100644
--- a/nuttx/sched/task_delete.c
+++ b/nuttx/sched/task_delete.c
@@ -140,6 +140,16 @@ int task_delete(pid_t pid)
PANIC(OSERR_BADDELETESTATE);
}
+ /* Perform common task termination logic (flushing streams, calling
+ * functions registered by at_exit/on_exit, etc.). We need to do
+ * this as early as possible so that higher level clean-up logic
+ * can run in a healthy tasking environment.
+ *
+ * I suppose EXIT_SUCCESS is an appropriate return value???
+ */
+
+ task_exithook(dtcb, EXIT_SUCCESS);
+
/* Remove the task from the OS's tasks lists. */
saved_state = irqsave();
@@ -151,13 +161,6 @@ int task_delete(pid_t pid)
sched_unlock();
- /* Perform common task termination logic (flushing streams, calling
- * functions registered by at_exit/on_exit, etc.). I suppose EXIT_SUCCESS
- * is an appropriate return value???
- */
-
- task_exithook(dtcb, EXIT_SUCCESS);
-
/* Deallocate its TCB */
sched_releasetcb(dtcb);
diff --git a/nuttx/sched/task_exithook.c b/nuttx/sched/task_exithook.c
index 9567f48a9..7dc07e79f 100644
--- a/nuttx/sched/task_exithook.c
+++ b/nuttx/sched/task_exithook.c
@@ -1,8 +1,8 @@
/****************************************************************************
* sched/task_exithook.c
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -106,18 +106,23 @@ void task_exithook(FAR _TCB *tcb, int status)
sched_note_stop(tcb);
- /* Flush all streams (File descriptors will be closed when
- * the TCB is deallocated).
+ /* If an exit function was registered, call it now before we do any un-
+ * initialized. NOTE: In the case of task_delete(), the exit function
+ * will *not* be called on the thread execution of the task being deleted!
*/
-#if CONFIG_NFILE_STREAMS > 0
- (void)lib_flushall(tcb->streams);
+#ifdef CONFIG_SCHED_ATEXIT
+ if (tcb->atexitfunc)
+ {
+ (*tcb->atexitfunc)();
+ }
#endif
- /* Deallocate anything left in the TCB's queues */
-
-#ifndef CONFIG_DISABLE_SIGNALS
- sig_cleanup(tcb); /* Deallocate Signal lists */
+#ifdef CONFIG_SCHED_ONEXIT
+ if (tcb->onexitfunc)
+ {
+ (*tcb->onexitfunc)(status, tcb->onexitarg);
+ }
#endif
/* Wakeup any tasks waiting for this task to exit */
@@ -142,16 +147,25 @@ void task_exithook(FAR _TCB *tcb, int status)
sem_post(&tcb->exitsem);
}
#endif
+ /* Flush all streams (File descriptors will be closed when
+ * the TCB is deallocated).
+ */
- /* If an exit function was registered, call it now. NOTE: In the case
- * of task_delete(), the exit function will *not* be called on the thread
- * execution of the task being deleted!
+#if CONFIG_NFILE_STREAMS > 0
+ (void)lib_flushall(tcb->streams);
+#endif
+
+ /* Free all file-related resources now. This gets called again
+ * just be be certain when the TCB is delallocated. However, we
+ * really need to close files as soon as possible while we still
+ * have a functioning task.
*/
-#ifdef CONFIG_SCHED_ATEXIT
- if (tcb->exitfunc)
- {
- (*tcb->exitfunc)();
- }
+ (void)sched_releasefiles(tcb);
+
+ /* Deallocate anything left in the TCB's queues */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+ sig_cleanup(tcb); /* Deallocate Signal lists */
#endif
}