You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/10/02 13:13:59 UTC
(nuttx-apps) branch master updated: nsh:support wait command to wait task exit.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
The following commit(s) were added to refs/heads/master by this push:
new c916f163f nsh:support wait command to wait task exit.
c916f163f is described below
commit c916f163f28810a13c18d29230eecf0ff02e3c5c
Author: anjiahao <an...@xiaomi.com>
AuthorDate: Wed Dec 27 14:57:30 2023 +0800
nsh:support wait command to wait task exit.
usage like:
nsh> sleep 10 &
[5:100]
nsh>set pid1=$!
nsh>sleep 15 &
[6:100]
nsh>set pid2=$!
nsh>wait $pid1 $pid2
'wait' command will block nsh from running until pid1 and pid2 finish.
This is useful for parallel requirements to perform certain tasks
Signed-off-by: anjiahao <an...@xiaomi.com>
---
nshlib/CMakeLists.txt | 4 ++
nshlib/Kconfig | 5 ++
nshlib/Makefile | 4 ++
nshlib/nsh.h | 5 ++
nshlib/nsh_command.c | 5 ++
nshlib/nsh_parse.c | 12 ++--
nshlib/nsh_wait.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 179 insertions(+), 6 deletions(-)
diff --git a/nshlib/CMakeLists.txt b/nshlib/CMakeLists.txt
index ae3b8dcd8..b7d3fc50d 100644
--- a/nshlib/CMakeLists.txt
+++ b/nshlib/CMakeLists.txt
@@ -98,6 +98,10 @@ if(CONFIG_NSH_LIBRARY)
list(APPEND CSRCS nsh_test.c)
endif()
+ if(NOT CONFIG_NSH_DISABLE_WAIT)
+ list(APPEND CSRCS nsh_wait.c)
+ endif()
+
if(CONFIG_USBDEV)
list(APPEND CSRCS nsh_usbconsole.c)
endif()
diff --git a/nshlib/Kconfig b/nshlib/Kconfig
index b6899b452..72e117c0a 100644
--- a/nshlib/Kconfig
+++ b/nshlib/Kconfig
@@ -699,6 +699,11 @@ config NSH_DISABLE_IRQ_AFFINITY
default DEFAULT_SMALL
depends on BOARDCTL_IRQ_AFFINITY
+config NSH_DISABLE_WAIT
+ bool "Disable wait"
+ default DEFAULT_SMALL
+ depends on SCHED_WAITPID
+
endmenu
if MMCSD
diff --git a/nshlib/Makefile b/nshlib/Makefile
index fb7aed89c..808d63af5 100644
--- a/nshlib/Makefile
+++ b/nshlib/Makefile
@@ -82,6 +82,10 @@ ifneq ($(CONFIG_NSH_DISABLESCRIPT),y)
CSRCS += nsh_test.c
endif
+ifneq ($(CONFIG_NSH_DISABLE_WAIT),y)
+CSRCS += nsh_wait.c
+endif
+
ifeq ($(CONFIG_USBDEV),y)
CSRCS += nsh_usbconsole.c
endif
diff --git a/nshlib/nsh.h b/nshlib/nsh.h
index af6cdb058..f6fb38f9a 100644
--- a/nshlib/nsh.h
+++ b/nshlib/nsh.h
@@ -1231,6 +1231,11 @@ int cmd_alias(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
int cmd_unalias(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
#endif
+#if !defined(CONFIG_NSH_DISABLE_WAIT) && defined(CONFIG_SCHED_WAITPID) && \
+ !defined(CONFIG_DISABLE_PTHREAD)
+int cmd_wait(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
+#endif
+
/****************************************************************************
* Name: nsh_extmatch_count
*
diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c
index 6efbbee69..0e3eb593b 100644
--- a/nshlib/nsh_command.c
+++ b/nshlib/nsh_command.c
@@ -666,6 +666,11 @@ static const struct cmdmap_s g_cmdmap[] =
#ifndef CONFIG_NSH_DISABLE_XD
CMD_MAP("xd", cmd_xd, 3, 3, "<hex-address> <byte-count>"),
+#endif
+#if !defined(CONFIG_NSH_DISABLE_WAIT) && defined(CONFIG_SCHED_WAITPID) && \
+ !defined(CONFIG_DISABLE_PTHREAD)
+ CMD_MAP("wait", cmd_wait, 1, CONFIG_NSH_MAXARGUMENTS,
+ "pid1 [pid2 [pid3] ...]"),
#endif
CMD_MAP(NULL, NULL, 1, 1, NULL)
};
diff --git a/nshlib/nsh_parse.c b/nshlib/nsh_parse.c
index 2119d4b47..d0973ec55 100644
--- a/nshlib/nsh_parse.c
+++ b/nshlib/nsh_parse.c
@@ -504,6 +504,12 @@ static pthread_addr_t nsh_child(pthread_addr_t arg)
_info("BG %s complete\n", carg->argv[0]);
nsh_releaseargs(carg);
+
+ /* Detach from the pthread since we are not going to join with it.
+ * Otherwise, we would have a memory leak.
+ */
+
+ pthread_detach(pthread_self());
return (pthread_addr_t)((uintptr_t)ret);
}
#endif
@@ -844,12 +850,6 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl,
goto errout;
}
- /* Detach from the pthread since we are not going to join with it.
- * Otherwise, we would have a memory leak.
- */
-
- pthread_detach(thread);
-
nsh_output(vtbl, "%s [%d:%d]\n", argv[0], thread,
param.sched_priority);
}
diff --git a/nshlib/nsh_wait.c b/nshlib/nsh_wait.c
new file mode 100644
index 000000000..c025799ad
--- /dev/null
+++ b/nshlib/nsh_wait.c
@@ -0,0 +1,150 @@
+/****************************************************************************
+ * apps/nshlib/nsh_wait.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/sched.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <pthread.h>
+
+#include "nsh.h"
+#include "nsh_console.h"
+
+#if !defined(CONFIG_NSH_DISABLE_WAIT) && defined(CONFIG_SCHED_WAITPID) && \
+ !defined(CONFIG_DISABLE_PTHREAD)
+
+static const char g_groupid[] = "Group:";
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cmd_wait
+ *
+ * Description:
+ * Handle 'cmd_wait' command from terminal.
+ * wait pid1 [pid2 [pid3] ..] - wait for a pid to exit.
+ *
+ * Input Parameters:
+ * vtbl - The NSH console.
+ * argc - Amount of argument strings in command.
+ * argv - The argument strings.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int cmd_wait(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
+{
+ FAR char *nextline;
+ FAR char *line;
+ char buf[128];
+ char path[32];
+ int status = 0;
+ int ret = OK;
+ pid_t self;
+ pid_t tid;
+ int fd;
+ int i;
+
+ if (argc == 1)
+ {
+ return OK;
+ }
+
+ self = getpid();
+ for (i = 1; i < argc; i++)
+ {
+ tid = atoi(argv[i]);
+ if (tid == 0)
+ {
+ continue;
+ }
+
+ snprintf(path, sizeof(path), "/proc/%d/status", tid);
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ {
+ nsh_error(vtbl, g_fmtcmdfailed, argv[0], "wait", NSH_ERRNO);
+ continue;
+ }
+
+ ret = read(fd, buf, sizeof(buf) - 1);
+ if (ret < 0)
+ {
+ nsh_error(vtbl, g_fmtcmdfailed, argv[0], "wait", NSH_ERRNO);
+ close(fd);
+ continue;
+ }
+
+ close(fd);
+ nextline = buf;
+ do
+ {
+ line = nextline;
+ for (nextline++;
+ *nextline != '\0' && *nextline != '\n';
+ nextline++);
+
+ if (*nextline == '\n')
+ {
+ *nextline++ = '\0';
+ }
+ else
+ {
+ nextline = NULL;
+ }
+
+ if (strncmp(line, g_groupid, sizeof(g_groupid) - 1) == 0)
+ {
+ if (atoi(line + sizeof(g_groupid)) == self)
+ {
+ ret = pthread_join(tid, (FAR pthread_addr_t *)&status);
+ }
+ else
+ {
+ ret = waitpid(tid, &status, 0);
+ }
+
+ if (ret < 0)
+ {
+ nsh_error(vtbl, g_fmtcmdfailed,
+ argv[0], "wait", NSH_ERRNO);
+ }
+
+ break;
+ }
+ }
+ while (nextline != NULL);
+ }
+
+ return ret < 0 ? ret : status;
+}
+
+#endif /* CONFIG_NSH_DISABLE_WAIT */