[gimp] app: add gimp_spawn_async()
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add gimp_spawn_async()
- Date: Mon, 5 Mar 2018 06:56:06 +0000 (UTC)
commit 0f2df18ddee944f5c27a283151d31e9be451d841
Author: Ell <ell_se yahoo com>
Date: Mon Mar 5 01:32:53 2018 -0500
app: add gimp_spawn_async()
gimp_spawn_async() is similar to, but more limited than,
g_spawn_sync(). Unlike the latter, gimp_spawn_async() uses
vfork(), instead of fork(), when possible.
On Linux, a process that uses large amounts of memory (as GIMP may)
can hang during a fork() if overcommitting is enabled, and there's
not enough memroy. Using vfork() avoids that, since it doesn't
duplicate the parent's address space.
app/core/Makefile.am | 2 +
app/core/gimp-spawn.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++++
app/core/gimp-spawn.h | 32 +++++++
configure.ac | 5 +
po/POTFILES.in | 1 +
5 files changed, 262 insertions(+), 0 deletions(-)
---
diff --git a/app/core/Makefile.am b/app/core/Makefile.am
index c3be33a..a751ffb 100644
--- a/app/core/Makefile.am
+++ b/app/core/Makefile.am
@@ -54,6 +54,8 @@ libappcore_a_sources = \
gimp-palettes.h \
gimp-parasites.c \
gimp-parasites.h \
+ gimp-spawn.c \
+ gimp-spawn.h \
gimp-tags.c \
gimp-tags.h \
gimp-templates.c \
diff --git a/app/core/gimp-spawn.c b/app/core/gimp-spawn.c
new file mode 100644
index 0000000..26fec13
--- /dev/null
+++ b/app/core/gimp-spawn.c
@@ -0,0 +1,222 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimp-spawn.c
+ * Copyright (C) 2018 Ell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#ifdef HAVE_VFORK
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+#endif
+
+#include <glib-object.h>
+
+#include "core-types.h"
+
+#include "gimp-spawn.h"
+
+#include "gimp-intl.h"
+
+
+/* copied from glib */
+static gint
+exec_err_to_g_error (gint en)
+{
+ switch (en)
+ {
+#ifdef EACCES
+ case EACCES:
+ return G_SPAWN_ERROR_ACCES;
+ break;
+#endif
+
+#ifdef EPERM
+ case EPERM:
+ return G_SPAWN_ERROR_PERM;
+ break;
+#endif
+
+#ifdef E2BIG
+ case E2BIG:
+ return G_SPAWN_ERROR_TOO_BIG;
+ break;
+#endif
+
+#ifdef ENOEXEC
+ case ENOEXEC:
+ return G_SPAWN_ERROR_NOEXEC;
+ break;
+#endif
+
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG:
+ return G_SPAWN_ERROR_NAMETOOLONG;
+ break;
+#endif
+
+#ifdef ENOENT
+ case ENOENT:
+ return G_SPAWN_ERROR_NOENT;
+ break;
+#endif
+
+#ifdef ENOMEM
+ case ENOMEM:
+ return G_SPAWN_ERROR_NOMEM;
+ break;
+#endif
+
+#ifdef ENOTDIR
+ case ENOTDIR:
+ return G_SPAWN_ERROR_NOTDIR;
+ break;
+#endif
+
+#ifdef ELOOP
+ case ELOOP:
+ return G_SPAWN_ERROR_LOOP;
+ break;
+#endif
+
+#ifdef ETXTBUSY
+ case ETXTBUSY:
+ return G_SPAWN_ERROR_TXTBUSY;
+ break;
+#endif
+
+#ifdef EIO
+ case EIO:
+ return G_SPAWN_ERROR_IO;
+ break;
+#endif
+
+#ifdef ENFILE
+ case ENFILE:
+ return G_SPAWN_ERROR_NFILE;
+ break;
+#endif
+
+#ifdef EMFILE
+ case EMFILE:
+ return G_SPAWN_ERROR_MFILE;
+ break;
+#endif
+
+#ifdef EINVAL
+ case EINVAL:
+ return G_SPAWN_ERROR_INVAL;
+ break;
+#endif
+
+#ifdef EISDIR
+ case EISDIR:
+ return G_SPAWN_ERROR_ISDIR;
+ break;
+#endif
+
+#ifdef ELIBBAD
+ case ELIBBAD:
+ return G_SPAWN_ERROR_LIBBAD;
+ break;
+#endif
+
+ default:
+ return G_SPAWN_ERROR_FAILED;
+ break;
+ }
+}
+
+gboolean
+gimp_spawn_async (gchar **argv,
+ gchar **envp,
+ GSpawnFlags flags,
+ GPid *child_pid,
+ GError **error)
+{
+#ifdef HAVE_VFORK
+ if (flags == (G_SPAWN_LEAVE_DESCRIPTORS_OPEN |
+ G_SPAWN_DO_NOT_REAP_CHILD |
+ G_SPAWN_CHILD_INHERITS_STDIN))
+ {
+ pid_t pid;
+
+ pid = vfork ();
+
+ if (pid < 0)
+ {
+ gint errsv = errno;
+
+ g_set_error (error,
+ G_SPAWN_ERROR,
+ G_SPAWN_ERROR_FORK,
+ _("Failed to fork (%s)"),
+ g_strerror (errsv));
+
+ return FALSE;
+ }
+ else if (pid == 0)
+ {
+ if (envp)
+ execve (argv[0], argv, envp);
+ else
+ execv (argv[0], argv);
+
+ _exit (errno);
+ }
+ else
+ {
+ int status = -1;
+ pid_t result;
+
+ result = waitpid (pid, &status, WNOHANG);
+
+ if (result)
+ {
+ if (result < 0)
+ {
+ g_warning ("waitpid() should not fail in "
+ "gimp_spawn_async()");
+ }
+
+ if (WIFEXITED (status))
+ status = WEXITSTATUS (status);
+ else
+ status = -1;
+
+ g_set_error (error,
+ G_SPAWN_ERROR,
+ exec_err_to_g_error (status),
+ _("Failed to execute child process ā%sā (%s)"),
+ argv[0],
+ g_strerror (status));
+
+ return FALSE;
+ }
+
+ if (child_pid) *child_pid = pid;
+
+ return TRUE;
+ }
+ }
+#endif /* HAVE_VFORK */
+
+ return g_spawn_async (NULL, argv, envp, flags, NULL, NULL, child_pid, error);
+}
diff --git a/app/core/gimp-spawn.h b/app/core/gimp-spawn.h
new file mode 100644
index 0000000..432296e
--- /dev/null
+++ b/app/core/gimp-spawn.h
@@ -0,0 +1,32 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimp-spawn.h
+ * Copyright (C) 2018 Ell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_SPAWN_H__
+#define __GIMP_SPAWN_H__
+
+
+gboolean gimp_spawn_async (gchar **argv,
+ gchar **envp,
+ GSpawnFlags flags,
+ GPid *child_pid,
+ GError **error);
+
+
+#endif /* __GIMP_SPAWN_H__ */
diff --git a/configure.ac b/configure.ac
index 14c2e20..c9d65bf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -960,6 +960,11 @@ AC_CHECK_FUNC(rint, AC_DEFINE(HAVE_RINT, 1,
AC_DEFINE(HAVE_RINT)])])
+# check for vfork
+AC_CHECK_FUNCS(vfork, ,)
+AC_SUBST(HAVE_VFORK)
+
+
##############################
# Check for attributes we need
##############################
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9099597..d20a69e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -110,6 +110,7 @@ app/core/gimp-gui.c
app/core/gimp-internal-data.c
app/core/gimp-modules.c
app/core/gimp-palettes.c
+app/core/gimp-spawn.c
app/core/gimp-tags.c
app/core/gimp-units.c
app/core/gimp-user-install.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]