diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-01-18 01:52:42 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-01-18 01:52:42 +0000 |
commit | 76753ad9cb67133892000f19de10f93de78bb525 (patch) | |
tree | 1eae1d92a03b0a2cbd1e83b45704a24d8662cf17 | |
parent | 2f653578c632ec95e94f67306af24c7d82700d28 (diff) | |
download | px4-firmware-76753ad9cb67133892000f19de10f93de78bb525.tar.gz px4-firmware-76753ad9cb67133892000f19de10f93de78bb525.tar.bz2 px4-firmware-76753ad9cb67133892000f19de10f93de78bb525.zip |
Add internal API task_reparent(), used in posix_spawn(). Move libc/spawn/lib_ps.c to sched/task_posixspawn.c; Move libc/spawn/spawn.h to include/nuttx/spawn.h
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5531 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r-- | apps/builtin/exec_builtin.c | 44 | ||||
-rw-r--r-- | apps/nshlib/nsh_builtin.c | 26 | ||||
-rw-r--r-- | apps/nshlib/nsh_fileapps.c | 21 | ||||
-rw-r--r-- | nuttx/ChangeLog | 7 | ||||
-rw-r--r-- | nuttx/binfmt/binfmt_exec.c | 1 | ||||
-rw-r--r-- | nuttx/include/nuttx/spawn.h (renamed from nuttx/libc/spawn/spawn.h) | 8 | ||||
-rw-r--r-- | nuttx/include/signal.h | 9 | ||||
-rw-r--r-- | nuttx/libc/spawn/Make.defs | 2 | ||||
-rw-r--r-- | nuttx/libc/spawn/lib_psfa_addaction.c | 2 | ||||
-rw-r--r-- | nuttx/libc/spawn/lib_psfa_addclose.c | 2 | ||||
-rw-r--r-- | nuttx/libc/spawn/lib_psfa_adddup2.c | 2 | ||||
-rw-r--r-- | nuttx/libc/spawn/lib_psfa_addopen.c | 2 | ||||
-rw-r--r-- | nuttx/libc/spawn/lib_psfa_destroy.c | 2 | ||||
-rw-r--r-- | nuttx/libc/spawn/lib_psfa_dump.c | 2 | ||||
-rw-r--r-- | nuttx/sched/Makefile | 6 | ||||
-rw-r--r-- | nuttx/sched/os_internal.h | 3 | ||||
-rw-r--r-- | nuttx/sched/task_posixspawn.c (renamed from nuttx/libc/spawn/lib_ps.c) | 82 | ||||
-rw-r--r-- | nuttx/sched/task_reparent.c | 145 | ||||
-rw-r--r-- | nuttx/syscall/syscall.csv | 2 |
19 files changed, 297 insertions, 71 deletions
diff --git a/apps/builtin/exec_builtin.c b/apps/builtin/exec_builtin.c index 803d1ef34..60e8b742d 100644 --- a/apps/builtin/exec_builtin.c +++ b/apps/builtin/exec_builtin.c @@ -124,7 +124,7 @@ static void bultin_semtake(FAR sem_t *sem) do { ret = sem_wait(sem); - ASSERT(ret == 0 || errno == EINTR); + ASSERT(ret == 0 || get_errno() == EINTR); } while (ret != 0); } @@ -152,7 +152,7 @@ static int builtin_taskcreate(int index, FAR const char **argv) if (b == NULL) { - errno = ENOENT; + set_errno(ENOENT); return ERROR; } @@ -228,7 +228,7 @@ static int builtin_proxy(int argc, char *argv[]) { /* Remember the errno value. ret is already set to ERROR */ - g_builtin_parms.errcode = errno; + g_builtin_parms.errcode = get_errno(); sdbg("ERROR: open of %s failed: %d\n", g_builtin_parms.redirfile, g_builtin_parms.errcode); } @@ -246,7 +246,7 @@ static int builtin_proxy(int argc, char *argv[]) ret = dup2(fd, 1); if (ret < 0) { - g_builtin_parms.errcode = errno; + g_builtin_parms.errcode = get_errno(); sdbg("ERROR: dup2 failed: %d\n", g_builtin_parms.errcode); } @@ -266,12 +266,18 @@ static int builtin_proxy(int argc, char *argv[]) ret = builtin_taskcreate(g_builtin_parms.index, g_builtin_parms.argv); if (ret < 0) { - g_builtin_parms.errcode = errno; + g_builtin_parms.errcode = get_errno(); sdbg("ERROR: builtin_taskcreate failed: %d\n", g_builtin_parms.errcode); } } + /* NOTE: There is a logical error here if CONFIG_SCHED_HAVE_PARENT is + * defined: The new task is the child of this proxy task, not the + * original caller. As a consequence, operations like waitpid() will + * fail on the caller's thread. + */ + /* Post the semaphore to inform the parent task that we have completed * what we need to do. */ @@ -340,11 +346,21 @@ static inline int builtin_startproxy(int index, FAR const char **argv, ret = sched_getparam(0, ¶m); if (ret < 0) { - errcode = errno; + errcode = get_errno(); sdbg("ERROR: sched_getparam failed: %d\n", errcode); - goto errout; + goto errout_with_sem; } + /* Disable pre-emption so that the proxy does not run until we waitpid + * is called. This is probably unnecessary since the builtin_proxy has + * the same priority as this thread; it should be schedule behind this + * task in the ready-to-run list. + */ + +#ifdef CONFIG_SCHED_WAITPID + sched_lock(); +#endif + /* Start the intermediary/proxy task at the same priority as the parent task. */ proxy = TASK_CREATE("builtin_proxy", param.sched_priority, @@ -352,9 +368,9 @@ static inline int builtin_startproxy(int index, FAR const char **argv, (FAR const char **)NULL); if (proxy < 0) { - errcode = errno; + errcode = get_errno(); sdbg("ERROR: Failed to start builtin_proxy: %d\n", errcode); - goto errout; + goto errout_with_lock; } /* Wait for the proxy to complete its job. We could use waitpid() @@ -365,7 +381,8 @@ static inline int builtin_startproxy(int index, FAR const char **argv, ret = waitpid(proxy, &status, 0); if (ret < 0) { - sdbg("ERROR: waitpid() failed: %d\n", errno); + sdbg("ERROR: waitpid() failed: %d\n", get_errno()); + goto errout_with_lock; } #else bultin_semtake(&g_builtin_execsem); @@ -377,7 +394,12 @@ static inline int builtin_startproxy(int index, FAR const char **argv, builtin_semgive(&g_builtin_parmsem); return g_builtin_parms.result; -errout: +errout_with_lock: +#ifdef CONFIG_SCHED_WAITPID + sched_unlock(); +#endif + +errout_with_sem: set_errno(errcode); builtin_semgive(&g_builtin_parmsem); return ERROR; diff --git a/apps/nshlib/nsh_builtin.c b/apps/nshlib/nsh_builtin.c index 343a0824b..0d5a0231c 100644 --- a/apps/nshlib/nsh_builtin.c +++ b/apps/nshlib/nsh_builtin.c @@ -131,12 +131,14 @@ int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, { /* The application was successfully started with pre-emption disabled. * In the simplest cases, the application will not have run because the - * the scheduler is locked. but in the case were I/O redirected, a - * proxy task ran and, as result, so may have the application. + * the scheduler is locked. But in the case where I/O was redirected, a + * proxy task ran and broke our lock. As result, the application may + * have aso ran if its priority was higher than than the priority of + * this thread. * - * If the application did not run and if the application was not - * backgrounded, then we need to wait here for the application to - * exit. This only works works with the following options: + * If the application did not run to completion and if the application + * was not backgrounded, then we need to wait here for the application + * to exit. This only works works with the following options: * * - CONFIG_NSH_DISABLEBG - Do not run commands in background * - CONFIG_SCHED_WAITPID - Required to run external commands in @@ -156,11 +158,17 @@ int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, { int rc = 0; - /* Wait for the application to exit. We did locked the scheduler + /* Wait for the application to exit. We did lock the scheduler * above, but that does not guarantee that the application did not - * run in the case where I/O was redirected. The scheduler will - * be unlocked while waitpid is waiting and if the application has - * not yet run, it will be able to to do so. + * already run to completion in the case where I/O was redirected. + * Here the scheduler will be unlocked while waitpid is waiting + * and if the application has not yet run, it will now be able to + * do so. + * + * Also, if CONFIG_SCHED_HAVE_PARENT is defined waitpid() might fail + * even if task is still active: If the I/O was re-directed by a + * proxy task, then the ask is a child of the proxy, and not this + * task. waitpid() fails with ECHILD in either case. */ ret = waitpid(ret, &rc, 0); diff --git a/apps/nshlib/nsh_fileapps.c b/apps/nshlib/nsh_fileapps.c index 92146a68d..9ff230f1a 100644 --- a/apps/nshlib/nsh_fileapps.c +++ b/apps/nshlib/nsh_fileapps.c @@ -168,12 +168,14 @@ int nsh_fileapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, { /* The application was successfully started with pre-emption disabled. * In the simplest cases, the application will not have run because the - * the scheduler is locked. but in the case were I/O redirected, a - * proxy task ran and, as result, so may have the application. + * the scheduler is locked. But in the case where I/O was redirected, a + * proxy task ran and broke our lock. As result, the application may + * have aso ran if its priority was higher than than the priority of + * this thread. * - * If the application did not run and if the application was not - * backgrounded, then we need to wait here for the application to - * exit. This only works works with the following options: + * If the application did not run to completion and if the application + * was not backgrounded, then we need to wait here for the application + * to exit. This only works works with the following options: * * - CONFIG_NSH_DISABLEBG - Do not run commands in background * - CONFIG_SCHED_WAITPID - Required to run external commands in @@ -193,11 +195,12 @@ int nsh_fileapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, { int rc = 0; - /* Wait for the application to exit. We did locked the scheduler + /* Wait for the application to exit. We did lock the scheduler * above, but that does not guarantee that the application did not - * run in the case where I/O was redirected. The scheduler will - * be unlocked while waitpid is waiting and if the application has - * not yet run, it will be able to to do so. + * already run to completion in the case where I/O was redirected. + * Here the scheduler will be unlocked while waitpid is waiting + * and if the application has not yet run, it will now be able to + * do so. */ ret = waitpid(pid, &rc, 0); diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 1b0c5338b..2a1561abe 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -3971,4 +3971,9 @@ automatically unload and clean-up after running a task that was loaded into memory. * binfmt/libbuiltin: Extensions from Mike Smith - + * sched/task_reparent.c: Add internal interface to change the + parent task. + * sched/task_posixspawn(): Move libc/spawn/lib_ps.c to + sched/task_posixspawn() now it requires internal, reparenting + interfaces + * include/nuttx/spawn(): Move libc/spawn.h to include/nuttx/spawn.h diff --git a/nuttx/binfmt/binfmt_exec.c b/nuttx/binfmt/binfmt_exec.c index 7f45fb841..4226b6cfc 100644 --- a/nuttx/binfmt/binfmt_exec.c +++ b/nuttx/binfmt/binfmt_exec.c @@ -97,7 +97,6 @@ int exec(FAR const char *filename, FAR const char **argv, { #ifdef CONFIG_SCHED_ONEXIT FAR struct binary_s *bin; - int errorcode; int pid; int ret; diff --git a/nuttx/libc/spawn/spawn.h b/nuttx/include/nuttx/spawn.h index 3f4e195cc..f84ae8355 100644 --- a/nuttx/libc/spawn/spawn.h +++ b/nuttx/include/nuttx/spawn.h @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/spawn/spawn.h + * include/nuttx/spawn.h * * Copyright (C) 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __LIBC_SPAWN_SPAWN_H -#define __LIBC_SPAWN_SPAWN_H +#ifndef __INCLUDE_NUTTX_SPAWN_H +#define __INCLUDE_NUTTX_SPAWN_H /**************************************************************************** * Included Files @@ -118,4 +118,4 @@ void add_file_action(FAR posix_spawn_file_actions_t *file_action, } #endif -#endif /* __LIBC_SPAWN_SPAWN_H */ +#endif /* __INCLUDE_NUTTX_SPAWN_H */ diff --git a/nuttx/include/signal.h b/nuttx/include/signal.h index 30726105b..7c6b4cd55 100644 --- a/nuttx/include/signal.h +++ b/nuttx/include/signal.h @@ -61,14 +61,17 @@ /* All signals are "real time" signals */ -#define SIGRTMIN 0 /* First real time signal */ -#define SIGRTMAX 31 /* Last real time signal */ +#define SIGRTMIN MIN_SIGNO /* First real time signal */ +#define SIGRTMAX MAX_SIGNO /* Last real time signal */ /* A few of the real time signals are used within the OS. They have * default values that can be overridden from the configuration file. The * rest are all user signals. * - * These are semi-standard signal definitions: + * The signal number zero is wasted for the most part. It is a valid + * signal number, but has special meaning at many interfaces (e.g., Kill()). + * + * These are the semi-standard signal definitions: */ #ifndef CONFIG_SIG_SIGUSR1 diff --git a/nuttx/libc/spawn/Make.defs b/nuttx/libc/spawn/Make.defs index 99ee781ce..8cb086fee 100644 --- a/nuttx/libc/spawn/Make.defs +++ b/nuttx/libc/spawn/Make.defs @@ -37,8 +37,6 @@ ifeq ($(CONFIG_LIBC_EXECFUNCS),y) -CSRCS += lib_ps.c - CSRCS += lib_psfa_addaction.c lib_psfa_addclose.c lib_psfa_adddup2.c CSRCS += lib_psfa_addopen.c lib_psfa_destroy.c lib_psfa_init.c diff --git a/nuttx/libc/spawn/lib_psfa_addaction.c b/nuttx/libc/spawn/lib_psfa_addaction.c index 3f297d7cf..8700efc2a 100644 --- a/nuttx/libc/spawn/lib_psfa_addaction.c +++ b/nuttx/libc/spawn/lib_psfa_addaction.c @@ -41,7 +41,7 @@ #include <spawn.h> -#include "spawn/spawn.h" +#include <nuttx/spawn.h> /**************************************************************************** * Global Functions diff --git a/nuttx/libc/spawn/lib_psfa_addclose.c b/nuttx/libc/spawn/lib_psfa_addclose.c index bf22a153a..1c72f0f82 100644 --- a/nuttx/libc/spawn/lib_psfa_addclose.c +++ b/nuttx/libc/spawn/lib_psfa_addclose.c @@ -44,7 +44,7 @@ #include <assert.h> #include <errno.h> -#include "spawn/spawn.h" +#include <nuttx/spawn.h> /**************************************************************************** * Global Functions diff --git a/nuttx/libc/spawn/lib_psfa_adddup2.c b/nuttx/libc/spawn/lib_psfa_adddup2.c index fc788a4e9..deb3cbdb3 100644 --- a/nuttx/libc/spawn/lib_psfa_adddup2.c +++ b/nuttx/libc/spawn/lib_psfa_adddup2.c @@ -44,7 +44,7 @@ #include <assert.h> #include <errno.h> -#include "spawn/spawn.h" +#include <nuttx/spawn.h> /**************************************************************************** * Global Functions diff --git a/nuttx/libc/spawn/lib_psfa_addopen.c b/nuttx/libc/spawn/lib_psfa_addopen.c index 385e1cfc3..66bbd813a 100644 --- a/nuttx/libc/spawn/lib_psfa_addopen.c +++ b/nuttx/libc/spawn/lib_psfa_addopen.c @@ -45,7 +45,7 @@ #include <assert.h> #include <errno.h> -#include "spawn/spawn.h" +#include <nuttx/spawn.h> /**************************************************************************** * Global Functions diff --git a/nuttx/libc/spawn/lib_psfa_destroy.c b/nuttx/libc/spawn/lib_psfa_destroy.c index 5d0a644d8..a21886645 100644 --- a/nuttx/libc/spawn/lib_psfa_destroy.c +++ b/nuttx/libc/spawn/lib_psfa_destroy.c @@ -43,7 +43,7 @@ #include <spawn.h> #include <assert.h> -#include "spawn/spawn.h" +#include <nuttx/spawn.h> /**************************************************************************** * Global Functions diff --git a/nuttx/libc/spawn/lib_psfa_dump.c b/nuttx/libc/spawn/lib_psfa_dump.c index d7bf1576d..0dbaeb023 100644 --- a/nuttx/libc/spawn/lib_psfa_dump.c +++ b/nuttx/libc/spawn/lib_psfa_dump.c @@ -43,7 +43,7 @@ #include <assert.h> #include <debug.h> -#include "spawn/spawn.h" +#include <nuttx/spawn.h> #ifdef CONFIG_DEBUG diff --git a/nuttx/sched/Makefile b/nuttx/sched/Makefile index 3d6b58bac..73c67239e 100644 --- a/nuttx/sched/Makefile +++ b/nuttx/sched/Makefile @@ -48,7 +48,7 @@ TSK_SRCS = prctl.c task_create.c task_init.c task_setup.c task_activate.c \ task_restart.c task_vfork.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 + sched_verifytcb.c sched_releasetcb.c task_posixspawn.c SCHED_SRCS = sched_setparam.c sched_setpriority.c sched_getparam.c \ sched_setscheduler.c sched_getscheduler.c \ @@ -67,6 +67,10 @@ ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) SCHED_SRCS += sched_reprioritize.c endif +ifeq ($(CONFIG_SCHED_HAVE_PARENT),y) +SCHED_SRCS += task_reparent.c +endif + ifeq ($(CONFIG_SCHED_WAITPID),y) SCHED_SRCS += sched_waitpid.c ifeq ($(CONFIG_SCHED_HAVE_PARENT),y) diff --git a/nuttx/sched/os_internal.h b/nuttx/sched/os_internal.h index 32d9fb4ac..f21d9654f 100644 --- a/nuttx/sched/os_internal.h +++ b/nuttx/sched/os_internal.h @@ -268,6 +268,9 @@ int task_schedsetup(FAR _TCB *tcb, int priority, start_t start, int task_argsetup(FAR _TCB *tcb, FAR const char *name, FAR const char *argv[]); void task_exithook(FAR _TCB *tcb, int status); int task_deletecurrent(void); +#ifdef CONFIG_SCHED_HAVE_PARENT +int task_reparent(pid_t oldpid, pid_t newpid, pid_t chpid); +#endif #ifndef CONFIG_CUSTOM_STACK int kernel_thread(FAR const char *name, int priority, int stack_size, main_t entry, FAR const char *argv[]); diff --git a/nuttx/libc/spawn/lib_ps.c b/nuttx/sched/task_posixspawn.c index 1bf7c2113..4201e759b 100644 --- a/nuttx/libc/spawn/lib_ps.c +++ b/nuttx/sched/task_posixspawn.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/string/lib_ps.c + * sched/task_posixspawn.c * * Copyright (C) 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> @@ -50,8 +50,9 @@ #include <debug.h> #include <nuttx/binfmt/binfmt.h> +#include <nuttx/spawn.h> -#include "spawn/spawn.h" +#include "os_internal.h" /**************************************************************************** * Private Types @@ -86,7 +87,7 @@ static struct spawn_parms_s g_ps_parms; ****************************************************************************/ /**************************************************************************** - * Name: ps_semtake and ps_semgive + * Name: spawn_semtake and spawn_semgive * * Description: * Give and take semaphores @@ -100,7 +101,7 @@ static struct spawn_parms_s g_ps_parms; * ****************************************************************************/ -static void ps_semtake(FAR sem_t *sem) +static void spawn_semtake(FAR sem_t *sem) { int ret; @@ -112,10 +113,10 @@ static void ps_semtake(FAR sem_t *sem) while (ret != 0); } -#define ps_semgive(sem) sem_post(sem) +#define spawn_semgive(sem) sem_post(sem) /**************************************************************************** - * Name: ps_exec + * Name: spawn_exec * * Description: * Execute the task from the file system. @@ -153,9 +154,9 @@ static void ps_semtake(FAR sem_t *sem) * ****************************************************************************/ -static int ps_exec(FAR pid_t *pidp, FAR const char *path, - FAR const posix_spawnattr_t *attr, - FAR char *const argv[]) +static int spawn_exec(FAR pid_t *pidp, FAR const char *path, + FAR const posix_spawnattr_t *attr, + FAR char *const argv[]) { struct sched_param param; FAR const struct symtab_s *symtab; @@ -420,7 +421,23 @@ static int spawn_proxy(int argc, char *argv[]) { /* Start the task */ - ret = ps_exec(g_ps_parms.pid, g_ps_parms.path, attr, g_ps_parms.argv); + ret = spawn_exec(g_ps_parms.pid, g_ps_parms.path, attr, + g_ps_parms.argv); + +#ifdef CONFIG_SCHED_HAVE_PARENT + if (ret == OK) + { + /* Change of the parent of the task we just spawned to our parent. + * What should we do in the event of a failure? + */ + + int tmp = task_reparent(0, 0, *g_ps_parms.pid); + if (tmp < 0) + { + sdbg("ERROR: task_reparent() failed: %d\n", tmp); + } + } +#endif } /* Post the semaphore to inform the parent task that we have completed @@ -429,9 +446,9 @@ static int spawn_proxy(int argc, char *argv[]) g_ps_parms.result = ret; #ifndef CONFIG_SCHED_WAITPID - ps_semgive(&g_ps_execsem); + spawn_semgive(&g_ps_execsem); #endif - return 0; + return OK; } /**************************************************************************** @@ -566,7 +583,7 @@ int posix_spawn(FAR pid_t *pid, FAR const char *path, if (file_actions == NULL || *file_actions == NULL) #endif { - return ps_exec(pid, path, attr, argv); + return spawn_exec(pid, path, attr, argv); } /* Otherwise, we will have to go through an intermediary/proxy task in order @@ -582,7 +599,7 @@ int posix_spawn(FAR pid_t *pid, FAR const char *path, /* Get exclusive access to the global parameter structure */ - ps_semtake(&g_ps_parmsem); + spawn_semtake(&g_ps_parmsem); /* Populate the parameter structure */ @@ -601,22 +618,33 @@ int posix_spawn(FAR pid_t *pid, FAR const char *path, int errcode = errno; sdbg("ERROR: sched_getparam failed: %d\n", errcode); - ps_semgive(&g_ps_parmsem); + spawn_semgive(&g_ps_parmsem); return errcode; } - /* Start the intermediary/proxy task at the same priority as the parent task. */ + /* Disable pre-emption so that the proxy does not run until we waitpid + * is called. This is probably unnecessary since the spawn_proxy has + * the same priority as this thread; it should be schedule behind this + * task in the ready-to-run list. + */ + +#ifdef CONFIG_SCHED_WAITPID + sched_lock(); +#endif + + /* Start the intermediary/proxy task at the same priority as the parent + * task. + */ proxy = TASK_CREATE("spawn_proxy", param.sched_priority, CONFIG_POSIX_SPAWN_STACKSIZE, (main_t)spawn_proxy, (FAR const char **)NULL); if (proxy < 0) { - int errcode = errno; + ret = get_errno(); + sdbg("ERROR: Failed to start spawn_proxy: %d\n", ret); - sdbg("ERROR: Failed to start spawn_proxy: %d\n", errcode); - ps_semgive(&g_ps_parmsem); - return errcode; + goto errout_with_lock; } /* Wait for the proxy to complete its job */ @@ -625,15 +653,21 @@ int posix_spawn(FAR pid_t *pid, FAR const char *path, ret = waitpid(proxy, &status, 0); if (ret < 0) { - sdbg("ERROR: waitpid() failed: %d\n", errno); + sdbg("ERROR: waitpid() failed: %d\n", errno); + goto errout_with_lock; } #else - ps_semtake(&g_ps_execsem); + spawn_semtake(&g_ps_execsem); #endif /* Get the result and relinquish our access to the parameter structure */ ret = g_ps_parms.result; - ps_semgive(&g_ps_parmsem); - return ret; + +errout_with_lock: +#ifdef CONFIG_SCHED_WAITPID + sched_unlock(); +#endif + spawn_semgive(&g_ps_parmsem); + return ret; } diff --git a/nuttx/sched/task_reparent.c b/nuttx/sched/task_reparent.c new file mode 100644 index 000000000..9daa0743b --- /dev/null +++ b/nuttx/sched/task_reparent.c @@ -0,0 +1,145 @@ +/***************************************************************************** + * sched/task_reparent.c + * + * Copyright (C) 2013 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 <errno.h> + +#include "os_internal.h" + +#ifdef CONFIG_SCHED_HAVE_PARENT + +/***************************************************************************** + * Private Functions + *****************************************************************************/ + +/***************************************************************************** + * Public Functions + *****************************************************************************/ + +/***************************************************************************** + * Name: task_reparent + * + * Description: + * Change the parent of a task. + * + * Parameters: + * oldpid - PID of the old parent task (0 if this task) + * newpid - PID ot the new parent task (0 for the parent of this task) + * chpid - PID of the child to be reparented. + * + * Return Value: + * 0 (OK) on success; A negated errno value on failure. + * + *****************************************************************************/ + +int task_reparent(pid_t oldpid, pid_t newpid, pid_t chpid) +{ + _TCB *oldtcb; + _TCB *newtcb; + _TCB *chtcb; + irqstate_t flags; + int ret; + + /* If oldpid is zero, then we are parent task. */ + + if (oldpid == 0) + { + oldpid = getpid(); + } + + /* Get the current parent task's TCB */ + + oldtcb = sched_gettcb(oldpid); + if (!oldtcb) + { + return -ESRCH; + } + + /* Disable interrupts so that nothing can change from this point */ + + flags = irqsave(); + + /* If newpid is zero, then new is the parent of oldpid. */ + + if (newpid == 0) + { + newpid = oldtcb->parent; + } + + /* Get the new parent task's TCB */ + + newtcb = sched_gettcb(newpid); + if (!newtcb) + { + ret = -ESRCH; + goto errout_with_ints; + } + + /* Get the child tasks TCB */ + + chtcb = sched_gettcb(chpid); + if (!chtcb) + { + ret = -ECHILD; + goto errout_with_ints; + } + + /* Verify that oldpid is the parent of chpid */ + + if (chtcb->parent != oldpid) + { + ret = -ECHILD; + goto errout_with_ints; + } + + /* Okay, reparent the child */ + + DEBUGASSERT(oldtcb->nchildren > 0); + chtcb->parent = newpid; + oldtcb->nchildren--; + newtcb->nchildren++; + ret = OK; + +errout_with_ints: + irqrestore(flags); + return ret; +} + +#endif /* CONFIG_SCHED_HAVE_PARENT */ diff --git a/nuttx/syscall/syscall.csv b/nuttx/syscall/syscall.csv index 4ccd53f9d..5bc52a71d 100644 --- a/nuttx/syscall/syscall.csv +++ b/nuttx/syscall/syscall.csv @@ -43,6 +43,8 @@ "prctl","sys/prctl.h", "CONFIG_TASK_NAME_SIZE > 0","int","int","..." "clock_systimer","nuttx/clock.h","!defined(CONFIG_DISABLE_CLOCK)","uint32_t" "poll","poll.h","!defined(CONFIG_DISABLE_POLL) && (CONFIG_NSOCKET_DESCRIPTORS > 0 || CONFIG_NFILE_DESCRIPTORS > 0)","int","FAR struct pollfd*","nfds_t","int" +"posix_spawnp", defined(CONFIG_BINFMT_EXEPATH), "int","FAR pid_t *","FAR const char *","FAR const posix_spawn_file_actions_t *","FAR const posix_spawnattr_t *","FAR char *const []","FAR char *const []" +"posix_spawn", !defined(CONFIG_BINFMT_EXEPATH), "int","FAR pid_t *","FAR const char *","FAR const posix_spawn_file_actions_t *","FAR const posix_spawnattr_t *","FAR char *const []","FAR char *const []" "pthread_barrier_destroy","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_barrier_t*" "pthread_barrier_init","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_barrier_t*","FAR const pthread_barrierattr_t*","unsigned int" "pthread_barrier_wait","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_barrier_t*" |