2009/8/17 Thomas Martitz thomas.martitz@student.htw-berlin.de:
Lex Trotman schrieb:
2009/8/16 Thomas Martitz thomas.martitz@student.htw-berlin.de:
Lex Trotman schrieb:
Hi Thomas,
Good to hear that there are no major problems.
I can see that you may want to kill a long build that you started by accident or when you realise you forgot to do something first. I've done that more than once ;-)
In Geany execute changes to stop while running, but build doesn't.
The difference is because they are run in different ways, execute runs in a terminal (either external or VTE) but build commands are run directly so that no terminal window pops up and so that the output can be captured for parsing for errors. Due to problems on windows, builds have to be run synchronously on windows, ie the whole of Geany freezes while the build runs (why? I don't understand exactly, maybe Enrico can explain it). That means that cancelling a windows build can't be done from Geany anyway.
Whilst Linux builds are still asynchronous only one is allowed at a time so that output isn't mixed up in the error parser. So all build commands are set insensitive until completion. To have one menu item still enabled and to have it change to stop is going to be quite a bit of fiddling unless it is always a fixed menu item or a toolbar button.
Seeing that the Run commands don't gray out too, I think adding a cancel button which doesn't gray out is going to be doable without a lot of fiddling.
But as a general action I would be worried about killing a build anyway.
Geany only knows about the parent process, the top level make, not any children that make forked to process subdirectories, or because -j was used, and they won't get killed (they migrate to be children of init). The overall impact is not well defined, but killing a top level make may leave most of the build still running. Now setting the build menu items sensitive and so enabling another build is risky.
And the results of builders other than make is even less well defined.
The Rockbox build system (see [1]) has a way to kill builds (even those which are started with -jX) using this snippet of perl code. Note that kill here is a perl function, which does IIUC killing the childs for us (it kills the process groups if the signal parameter is negative). I don't know if it helps us though. Could one try call the perl function from within geany with a crude hack/magic?
Um no, that would require Geany to have a dependency on Perl, and I doubt that such a requirement would be acceptable to the general Geany community.
I havn't written perl for a while but this seems to depend on the global builds variable, whats that got in it and where was it set??
sub killchild { my ($id) = @_;
return if (not defined $builds{$id});
my $pipe = $builds{$id}{pipe}; $read_set->remove($pipe);
$busy -= $builds{$id}{cores};
my $pid = $builds{$id}{pid}; kill -9, $pid; tprint "Killed build $id\n"; waitpid $pid, 0;
my $dir = "$cwd/build-$pid"; if (-d $dir) { tprint "Removing $dir\n"; rmtree $dir; }
delete $builds{$id}; }
I actually got interested in adding the configurability to Geany build system when an organisation I was consulting to was using Geany but running builds on a server farm with several versions of Linux, AIX, HP-UX, Solaris and several windows versions. And different pieces of software from many different sources used many different build systems, hence the need for configurability.
Of course such remote jobs won't be touched by any signals.
According to the reference you provided on Rockbox it does remote builds by copying data from SVN and then copying the results back. So a remote build can be cancelled by its special server on the remote system (I guess thats where the perl snippet came from) and thrown away and no corruption is possible, but our system used shared sources for all machines and locks to control multiple build interactions. Killing things could leave locks about and block builds until someone removed them manually. Worse some pieces of software could corrupt the build tree if cancelled (sure they were lousy build scripts, but we used software from lots of places and didn't want to touch such things unless absolutely required)
Killing is done in the client (the snippet came from rbclient.rb). The server just sends a message CANCEL, the client in turn calls killchild.
Ok, which is client and which is server is not well defined :-)
Requiring perl is indeed suboptimal, but on the other hands it's really part of the default installation in 99% of all distros, and just about the same percentage of projects require perl already. But I understand that this is unwanted :)
While such a system is unusual, it made me very aware that the area of child processes in Unix (ignoring windows) is very flexible and not always fully standardised ( eg Linux pre 2.6 is not exactly POSIX). Remember even if it doesn't run something remote, a build could easily spawn background processes that can't be killed from the parent because they are not part of the same process group, so if the perl function only kills the group it still won't get them.
And your killall only works because you know that you are the only make running on your machine, it would be considered impolite if you were to kill someone else's make by accident :-)
I know, hence I'm searching for something better. See, I'm running a rockbox build client. Natually, I will kill those makes too if it was running at this very moment.
Its an area where caution is required to avoid real problems. If you have a solution that works for you, great!! Configure it for yourself, but it can't be offered as a general solution unless safe (oh, and useful ;-)
I actually played around a bit, and got a bit farther.
In my quick hack, I use kill(0, SIGTERM) to kill everything that has geanys pid as parent. To not kill geany itself too, I changed the signal handler to something which does nothing (and reverting to SIG_DFL afterwards). That works well, although I don't know which other process geany creates. Also, I think this is really a bad hack :( (isn't it?
Well, yes it is, thats too drastic, you don't know what else is running. If you use something like this elsewhere you just set the handler to SIG_IGN, thats what its for.
As an aside don't try blocking the signal, Geany (actually GTK+) uses multiple threads and you will only be blocking the main thread. So I guess thats advice for all GTK programs.
What I'm wondering is why doing "kill(build_info.pid, SIGINT)" doesn't work. Isn't that the same as doing CTRL+C when doing make in a terminal manually?
But it only kills the parent build process, unfortunately all the issues about children still apply.
Remember your ctrl-c from the terminal doesn't kill background processes because they are in another process group.
Your make script might not run other processes, but there is nothing preventing a script from running background processes or anything. We do *not* know what the users build executes and what a mess it might leave if terminated.
Thats why I say it should not be programmed into Geany, it makes too many assumptions.
As I said before, if it works for you in a particular situation configure it as a command, but just because it works for you does *not* mean it is safe in general. Having a command which is a script (even a perl one ;-) examine the process tree and find the "make" children of the instance of Geany that is a parent of the script itself (you may have to read that slowly, I did to ensure I got it right) would be the best way to go to avoid clobbering any other makes that are running and anything running from any other instances of Geany.
But programming one way of killing a build into Geany that may not work or may do damage is a bad idea.
I think we need to consider this a bit more first to find a safe general solution.
In the interim why don't you configure an extra execute command to run the "killall -9 make". It can then run asynchronously whilst the build is running.
Because my run (and build) command list is full ;)
I keep running out too :-D
With the build-system branch the hidden preference number_exec_menu_items can be set to increase the number of execute commands, see the build-system version of geany.html preferences file format section.
The geany.html is currently broken here due to svn merge (which took surprisingly long, some 30min) :D But I did not know that, thanks!
Was that merging trunk with your working copy? I will be merging trunk into build-system soon as 0.18 is released so let me know of any big problems. geany.html doesn't matter because it can be re-generated but if there are other problems its would be good to be warned. Build.c always has to be manually merged though.
Cheers Lex
Filetype and non-filetype numbers can also be increased so you can add make commands too (you can't decrease them). Close and re-open Geany before they take effect.
Cheers Lex
Geany-devel mailing list Geany-devel@uvena.de http://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel