summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2013-06-07 13:13:12 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2013-06-07 13:13:12 -0400
commit5d691c1a2a13cb5ce131abdc8acfb65e5d9bae77 (patch)
tree03a7d275a7d3199fbb585acb2188e62745344ecd /gtk2_ardour
parent79cb2875fef3771623f01ecf1e3c0c494f683855 (diff)
fix handling of returning value of ::waitpid() so that we clean up harvid correctly
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/system_exec.cc31
1 files changed, 26 insertions, 5 deletions
diff --git a/gtk2_ardour/system_exec.cc b/gtk2_ardour/system_exec.cc
index ca059dada5..c63d1d183b 100644
--- a/gtk2_ardour/system_exec.cc
+++ b/gtk2_ardour/system_exec.cc
@@ -414,6 +414,10 @@ void
SystemExec::terminate ()
{
::pthread_mutex_lock(&write_lock);
+
+ /* close stdin in an attempt to get the child to exit cleanly.
+ */
+
close_stdin();
if (pid) {
@@ -422,12 +426,21 @@ SystemExec::terminate ()
wait(WNOHANG);
}
+ /* if pid is non-zero, the child task is still executing (i.e. it did
+ * not exit in response to stdin being closed). try to kill it.
+ */
+
if (pid) {
::kill(pid, SIGTERM);
::usleep(50000);
sched_yield();
wait(WNOHANG);
}
+
+ /* if pid is non-zero, the child task is STILL executing after being
+ * sent SIGTERM. Act tough ... send SIGKILL
+ */
+
if (pid) {
::fprintf(stderr, "Process is still running! trying SIGKILL\n");
::kill(pid, SIGKILL);
@@ -443,15 +456,23 @@ int
SystemExec::wait (int options)
{
int status=0;
+ int ret;
+
if (pid==0) return -1;
- if (pid==::waitpid(pid, &status, options)) {
+
+ ret = waitpid (pid, &status, options);
+
+ if (ret == pid) {
if (WEXITSTATUS(status) || WIFSIGNALED(status)) {
pid=0;
}
} else {
- if (errno == ECHILD) {
- pid=0;
- }
+ if (ret != 0) {
+ if (errno == ECHILD) {
+ /* no currently running children, reset pid */
+ pid=0;
+ }
+ } /* else the process is still running */
}
return status;
}
@@ -615,7 +636,7 @@ SystemExec::output_interposer()
ssize_t r;
unsigned long l = 1;
- ioctl(rfd, FIONBIO, &l); // set non-blocking I/O
+ ioctl(rfd, FIONBIO, &l); // set non-blocking I/O
for (;fcntl(rfd, F_GETFL)!=-1;) {
r = read(rfd, buf, sizeof(buf));