summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 f875a5edc9..4cddd92ddd 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 1950c881be..56a98a2f62 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 5e4b902b5e..e60b6689a8 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 09407bfb08..78f79b3829 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 1444d88052..066c9a4ef1 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 7d5fe16bf5..4cfca9dbcd 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 b9b9346b55..27696e0fae 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 39a526edaf..b8a1bb519a 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 3a116f4c14..da1be1c2ab 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 0000000000..9824ec7353
--- /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 160b0fb423..3990cd3c6b 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 31715051a1..4cd2b3ba7a 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 9567f48a9f..7dc07e79f1 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
}