[sdk/kdesrc-build] /: Support SIGHUP for graceful script exit.
Michael Pyne
null at kde.org
Thu Jul 14 05:13:53 BST 2022
Git commit e5a9295bccf07ed0ca9d9729b7ca72ec193f5a2d by Michael Pyne.
Committed on 14/07/2022 at 04:11.
Pushed by mpyne into branch 'master'.
Support SIGHUP for graceful script exit.
This helps if a user started a long build without --stop-on-failure and
needs it to stop without risking interrupting kdesrc-build during an
install step.
Fixes #96.
M +97 -1 doc/index.docbook
M +10 -1 doc/man-kdesrc-build.1.docbook
M +59 -2 modules/ksb/TaskManager.pm
https://invent.kde.org/sdk/kdesrc-build/commit/e5a9295bccf07ed0ca9d9729b7ca72ec193f5a2d
diff --git a/doc/index.docbook b/doc/index.docbook
index 894fc38..f086c8c 100644
--- a/doc/index.docbook
+++ b/doc/index.docbook
@@ -2,7 +2,7 @@
<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN" "dtd/kdedbx45.dtd" [
<!--
Documentation for kdesrc-build.
- Copyright (c) 2005-2008, 2010-2020 Michael Pyne <mpyne at kde.org>
+ Copyright (c) 2005-2008, 2010-2022 Michael Pyne <mpyne at kde.org>
Copyright (c) 2005 Carlos Leonhard Woelz <carloswoelz at imap-mail.com>
Copyright (c) 2009 Burkhard Lück <lueck at hube-lueck.de>
@@ -4326,6 +4326,102 @@ as well.
</sect2>
+<sect2 id="stopping-the-build-early">
+<title>Stopping the build early</title>
+
+<sect3 id="the-build-continues">
+<title>The build normally continues even if failures occur</title>
+
+<para>&kdesrc-build; normally will update, build and install all modules
+in the specified list of modules to build, even if a module fails to build.
+This is usually a convenience to allow you to update software packages even
+if a simple mistake is made in one of the source repositories during
+development that causes the build to break.
+</para>
+
+<para>
+However you may wish for &kdesrc-build; to stop what it is doing once a
+module fails to build and install. This can help save you time that will be
+wasted trying to make progress when modules remaining in the build list will
+not be able to successfully build either, especially if you have not ever
+successfully built the modules in the list.
+</para>
+
+</sect3>
+
+<sect3 id="stop-on-failure-stops-early">
+<title>Stopping early with --stop-on-failure</title>
+
+<para>
+The primary method to do this is to use the
+<link linkend="cmdline-stop-on-failure">--stop-on-failure</link>
+command line option when you run &kdesrc-build;.
+</para>
+
+<para>This option can also be set in the
+<link linkend="conf-stop-on-failure">configuration file</link> to make
+it the normal mode of operation.
+</para>
+
+<para>It is also possible to tell &kdesrc-build; at runtime to stop building
+<emphasis>after</emphasis> completing the current module it is working on.
+This is as opposed to interrupting &kdesrc-build; using a command like
+<keycombo action="simul">&Ctrl;<keycap>C</keycap></keycombo>, which interrupts
+&kdesrc-build; immediately, losing the progress of the current module.
+</para>
+
+<important><para>Interrupting &kdesrc-build; during a module install when
+the <link linkend="conf-use-clean-install">use-clean-install</link> option
+is enabled will mean that the interrupted module will be unavailable until
+&kdesrc-build; is able to successfully build the module!</para>
+
+<para>If you need to interrupt &kdesrc-build; without permitting a graceful shutdown
+in this situation, at least try to avoid doing this while &kdesrc-build; is
+installing a module.</para>
+</important>
+
+</sect3>
+
+<sect3 id="stopping-early-without-stop-on-failure">
+<title>Stopping &kdesrc-build; early without --stop-on-failure</title>
+
+<para>As mentioned above, it is possible to cause &kdesrc-build; to gracefully
+shutdown early once it has completed the module it is currently working on.
+To do this, you need to send the POSIX <literal>HUP</literal> signal to &kdesrc-build;
+</para>
+
+<para>You can do this with a command such as <command>pkill</command> (on &Linux; systems) as follows:</para>
+
+<programlisting>
+<prompt>$ </prompt><userinput><command>pkill <option>-HUP</option> kdesrc-build</command></userinput>
+</programlisting>
+
+<para>If done successfully, you will see a message in the &kdesrc-build; output similar
+to:</para>
+
+<programlisting>
+[ build ] recv SIGHUP, will end after this module
+</programlisting>
+
+<note>
+<para>&kdesrc-build; may show this message multiple times depending on the
+number of individual &kdesrc-build; processes that are active. This is
+normal and not an indication of an error.</para>
+</note>
+
+<para>
+Once &kdesrc-build; has acknowledged the signal, it will stop processing
+after the current module is built and installed. If &kdesrc-build; is still
+updating source code when the request is received, &kdesrc-build; will stop
+after the module source code update is complete. Once both the update and build
+processes have stopped early, &kdesrc-build; will print its partial results
+and exit.
+</para>
+
+</sect3>
+
+</sect2>
+
<sect2 id="building-successfully">
<title>How &kdesrc-build; tries to ensure a successful build</title>
diff --git a/doc/man-kdesrc-build.1.docbook b/doc/man-kdesrc-build.1.docbook
index 82f5786..098755d 100644
--- a/doc/man-kdesrc-build.1.docbook
+++ b/doc/man-kdesrc-build.1.docbook
@@ -6,7 +6,7 @@
<!--
Man page for kdesrc-build.
- Copyright (c) 2011, 2014-2020 Michael Pyne <mpyne at kde.org>
+ Copyright (c) 2011, 2014-2020, 2022 Michael Pyne <mpyne at kde.org>
Permission is granted to copy, distribute and/or modify this document under
the terms of the GNU Free Documentation License, Version 1.2 or any later
@@ -1157,6 +1157,15 @@ others
</variablelist>
</refsect1>
+<refsect1>
+<title>SIGNALS</title>
+
+<para>&kdesrc-build; supports <literal>SIGHUP</literal>, which if received
+will cause &kdesrc-build; to exit after the current modules for the
+build thread (and update thread, if still active) have completed.</para>
+
+</refsect1>
+
<refsect1>
<title>FILES</title>
diff --git a/modules/ksb/TaskManager.pm b/modules/ksb/TaskManager.pm
index 976147c..6194275 100644
--- a/modules/ksb/TaskManager.pm
+++ b/modules/ksb/TaskManager.pm
@@ -34,6 +34,8 @@ use Mojo::URL;
use IO::Select;
use POSIX qw(EINTR WNOHANG);
+my $DO_STOP = 0;
+
sub new ($class, $app)
{
assert_isa($app, 'ksb::Application');
@@ -72,6 +74,13 @@ sub runAllTasks ($self)
} else {
whisper ("Using no IPC mechanism\n");
+ # If the user sends SIGHUP during the build, we should allow the
+ # current module to complete and then exit early.
+ local $SIG{HUP} = sub {
+ say "[noasync] recv SIGHUP, will end after this module";
+ $DO_STOP = 1;
+ };
+
note ("\n b[<<< Update Process >>>]\n");
$result = _handle_updates ($ipc, $ctx);
@@ -131,6 +140,11 @@ sub _handle_updates ($ipc, $ctx)
my $hadError = 0;
foreach my $module (@update_list) {
+ if ($DO_STOP) {
+ note (" y[b[* * *] Early exit requested, aborting updates.");
+ last;
+ }
+
$ipc->setLoggedModule($module->name());
# Note that this must be in this order to avoid accidentally not
@@ -251,6 +265,11 @@ EOF
$statusViewer->numberModulesTotal($num_modules);
while (my $module = shift @modules) {
+ if ($DO_STOP) {
+ note (" y[b[* * *] Early exit requested, aborting updates.");
+ last;
+ }
+
my $moduleName = $module->name();
my $moduleSet = $module->moduleSet()->name();
my $modOutput = $moduleName;
@@ -378,20 +397,40 @@ sub _handle_async_build ($ipc, $ctx)
my $result = 0;
my $monitorPid = fork;
+ my $updaterPid;
if ($monitorPid == 0) {
# child
my $updaterToMonitorIPC = ksb::IPC::Pipe->new();
- my $updaterPid = fork;
+ $updaterPid = fork;
$SIG{INT} = sub { POSIX::_exit(EINTR); };
if ($updaterPid) {
+ # If the user sends SIGHUP during the build, we should allow the
+ # current module to complete and then exit early.
+ local $SIG{HUP} = sub {
+ say "[updater] recv SIGHUP, will end after this module";
+
+ $DO_STOP = 1;
+ };
+
$0 = 'kdesrc-build-updater';
$updaterToMonitorIPC->setSender();
ksb::Debug::setIPC($updaterToMonitorIPC);
POSIX::_exit (_handle_updates ($updaterToMonitorIPC, $ctx));
} else {
+ # If the user sends SIGHUP during the build, we should allow the
+ # current module to complete and then exit early.
+ local $SIG{HUP} = sub {
+ say "[monitor] recv SIGHUP, will end after this module";
+
+ # If we haven't recv'd yet, forward to monitor in case user didn't
+ # send to process group
+ kill 'HUP', $updaterPid unless $DO_STOP;
+ $DO_STOP = 1;
+ };
+
$0 = 'kdesrc-build-monitor';
$ipc->setSender();
$updaterToMonitorIPC->setReceiver();
@@ -399,10 +438,28 @@ sub _handle_async_build ($ipc, $ctx)
$ipc->setLoggedModule('#monitor#'); # This /should/ never be used...
ksb::Debug::setIPC($ipc);
- POSIX::_exit (_handle_monitoring ($ipc, $updaterToMonitorIPC));
+ my $exitcode = _handle_monitoring ($ipc, $updaterToMonitorIPC);
+ if (waitpid ($updaterPid, WNOHANG) == 0) {
+ error (" r[b[***] updater thread is finished but hasn't exited?!?");
+ }
+
+ POSIX::_exit ($exitcode);
}
} else {
# Still the parent, let's do the build.
+
+ # If the user sends SIGHUP during the build, we should allow the current
+ # module to complete and then exit early.
+ local $SIG{HUP} = sub {
+ say "[ build ] recv SIGHUP, will end after this module";
+
+ # If we haven't recv'd yet, forward to monitor in case user didn't
+ # send to process group
+ kill 'HUP', $monitorPid unless $DO_STOP;
+ $DO_STOP = 1;
+ };
+
+ $0 = 'kdesrc-build[build]';
$ipc->setReceiver();
$result = _handle_build ($ipc, $ctx);
}
More information about the kde-doc-english
mailing list