[Geany-devel] ANN: Configurable Build Menu Alpha in SVN

Lex Trotman elextr at xxxxx
Sun Aug 16 15:48:32 UTC 2009


2009/8/17 Thomas Martitz <thomas.martitz at student.htw-berlin.de>:
> Lex Trotman schrieb:
>>
>> 2009/8/16 Thomas Martitz <thomas.martitz at 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 at uvena.de
> http://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel
>



More information about the Devel mailing list