diff options
-rw-r--r-- | apps/include/netutils/telnetd.h | 9 | ||||
-rw-r--r-- | apps/netutils/telnetd/telnetd_driver.c | 19 | ||||
-rw-r--r-- | nuttx/ChangeLog | 6 | ||||
-rw-r--r-- | nuttx/Documentation/NuttxUserGuide.html | 2 | ||||
-rw-r--r-- | nuttx/fs/fs_files.c | 29 | ||||
-rw-r--r-- | nuttx/include/nuttx/sched.h | 16 | ||||
-rw-r--r-- | nuttx/include/stdlib.h | 11 | ||||
-rw-r--r-- | nuttx/sched/Makefile | 14 | ||||
-rw-r--r-- | nuttx/sched/atexit.c | 12 | ||||
-rw-r--r-- | nuttx/sched/on_exit.c | 127 | ||||
-rw-r--r-- | nuttx/sched/sched_releasefiles.c | 37 | ||||
-rw-r--r-- | nuttx/sched/task_delete.c | 17 | ||||
-rw-r--r-- | nuttx/sched/task_exithook.c | 50 |
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 } |