Boost logo

Boost :

Subject: Re: [boost] [boost.process] 0.6 Alpha
From: Klemens Morgenstern (klemens.morgenstern_at_[hidden])
Date: 2016-06-08 05:19:45

Am 08.06.2016 um 10:33 schrieb Rob Stewart:
> On June 8, 2016 3:05:37 AM EDT, Klemens Morgenstern <klemens.morgenstern_at_[hidden]> wrote:
>> Am 08.06.2016 um 04:06 schrieb Rob Stewart:
>>>> Consider this:
>>>> ipstream is;
>>>> child c("prog", std_in < is);
>>>> is << generate_input() << endl;
>>>> Not if generate_input throws, I need to terminate the child,
>> elsewise I
>>>> get a deadlock (since "prog" waits for input). If you do not want
>> this,
>>>> you can detach it or join it. In that it is similar to std::thread,
>>>> though it doesn't terminate the current process. Now using a timeout
>>>> would be possible, but I really don't like to set an arbitrary value
>>>> here.
>>> I see your point. You could provide a default timeout for that case
>> and include a function permitting the user to override that default.
>> Sry, but no. I don't see the point of timeouts, especially default
>> ones.
>> In this case it is quite clear, that there's no point in continuing, so
>> why put in timeout?
> Your approach gives the child no chance to shut down gracefully. It cannot close database connections, remove temporary files, clean up content in shared memory, whatever.

A timeout doesn't make sense if you have no standard way to signal the
child to exit. If you implement your version of that, you can use
chlid::wait_for and then terminate. The child class is meant to be
joined before destructing; the terminate on destruction is for exceptions.

>>> Sending signals on posix systems may not terminate
>> a process either. That's why you fall back on SIGKILL. On Windows, you
>> try the WM_CLOSE approach and fall back on TerminateProcess().
>> Difference is: every posix program can catch SIGTERM, not every windows
>> program will get WM_CLOSE - console applications will never receive
>> that. It depends on the compile options.
> Some console apps can be written to process such messages, but most won't, of course. What's more, if an app doesn't handle the message, you're no worse off than when you just call TerminateProcess().
>> Now for this to be part of the process core library (i.e. included in
>> boost/process.hpp) it would need to work like this both platforms:
>> //father
>> child c(...);
>> c.request_exit();
>> //child
>> this_process::on_exit_request(std::function<bool()> func);
>> That's not possible, so it won't be in the library. It might be added
>> to
>> the platform-extensions though, i.e. you could have something like the
>> following functions if you include boost/process/posix.hpp or
>> boost/process/windows.hpp (needs to be distinguished by #ifdef)
>> posix::send_terminate(child &);
>> windows::send_wm_close(child&);
>> windows::send_console_kill(child&);
>> I have no problem having a platform-specific function there, but if I
>> have a function in the multi-platform part of boost.process it has to
>> behave the same everywhere.
> I see that you only want to send the nice termination signal if the child can install a handler in a common way. I was missing that side of the equation. The Windows issue is whether it's possible to determine, at compile time or runtime, whether an association has a GUI message loop or not. If so, you'd have to install a message loop handler for WM_CLOSE, and if not, you'd have to use SetConsoleCtrlHandler() to install a callback.

That, AND it ought to be the default on the system for exit requests.

> I don't know much about Windows message handler loops, but you could install a message hook if there isn't a better way to integrate into the app's own message loop.

It doesn't work really, especially since SetConsoleCtrlHandler does only
allow two values (Ctrl+C & Ctrl+Break), which are both not clearly
termination requests, but more of a terminate command I think. Also to
do that, I would need to put all those child processes on a new process
group, which would mean, that Ctrl+C will NOT be transmitted to them.
That's also a dealbreaker.

>>>> Joël Lamotte
>>>> recommended a similar solution and will send me some examples, so a
>>>> child::request_exit() function might be added.
>>> The remote thread technique sounds interesting.
>>>> Now if that happens, I
>>>> still will not change the behaviour in child, but you might be able
>> to
>>>> do this then:
>>>> soft_exit se (child("thingy"), milliseconds(100));
>>> Why not c.terminate(milliseconds(100)) and c.kill()?
>> Yeah would be possible, too. Though as written above, there won't be a
>> terminate-request member-function of child. But what you could do is
>> this.
>> some_magic_terminate_request(c); //your SIGTERM impl.
>> if (!c.wait_for(milliseconds(100))
>> c.terminate();
> I'm confused why you think some_magic_terminate_request() should be a free function, while terminate() is a member function.

Because I would be fine to have it as an extension in the posix- or
windows-namespace, but not in the core-library. Hence it won't be a
method of child.

> ___
> Rob
> (Sent from my portable computation engine)
> _______________________________________________
> Unsubscribe & other changes:

Boost list run by bdawes at, gregod at, cpdaniel at, john at