Boost logo

Boost :

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


Am 08.06.2016 um 04:06 schrieb Rob Stewart:
> On June 7, 2016 4:59:59 AM EDT, Klemens Morgenstern <klemens.morgenstern_at_[hidden]> wrote:
>> Am 07.06.2016 um 10:37 schrieb Rob Stewart:
>>> On June 6, 2016 6:49:44 AM EDT, "Klaim - Joël Lamotte"
>> <mjklaim_at_[hidden]> wrote:
>>>> On 6 June 2016 at 12:00, Klemens Morgenstern <klemens.morgenstern_at_[hidden]>
>>>> wrote:
>>>>
>>>>> It's TerminateProcess on windows and "kill -9" on posix.
>>
>>> That's too harsh as a default. Default signal handling in Posix
>>> systems means that sending SIGTERM first would signal a graceful exit.
>>> That doesn't mean the process will exit successfully or that it won't
>>> ignore the signal, so after waiting for a limited time (user specified
>>> with a default), you would send SIGKILL.
>>>
>>> (You could actually send SIGTERM, SIGINT, and SIGQUIT, one after the
>>> other to increase the chance that the process recognizes the need to
>> exit.)
>>>
>>> On Windows, you can send WM_CLOSE. The process may respond within the
>> allotted time and it may not (it certainly won't if it's an ordinary
>> console app). TerminateProcess() is the final step if the process
>> handle isn't signaled within the timeout period.
>>>
>>> Thus, terminating a process behaves similarly on both platforms: try
>>> a nice signal, wait, then terminate it forcefully if need be.
>> I actually thought the same thing, but it is an issue of security.
>> 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?

>
>> Regarding the WM_CLOSE version: I currently don't think that is a
>> really
>> portable solution, since you signal the HWND not the Process, which
>> means that console programs will cause problems here.
>
> I mentioned that. 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.
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.

>
>> 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();

> ___
> Rob
>
> (Sent from my portable computation engine)
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk