RFC: Integrating Boost.Process and Boost.Asio

I'm looking for ideas how to integrate Boost.Process and Boost.Asio. As of today it is possible to use asynchronous I/O with Boost.Process. However you have to pass around low-level file descriptors/HANDLEs like this: bp::child c = start_child(); bp::pistream &is = c.get_stdout(); #if defined(BOOST_POSIX_API) ba::posix::stream_descriptor in(io_service); #elif defined(BOOST_WINDOWS_API) ba::windows::stream_handle in(io_service); #endif in.assign(is.handle().release()); is.async_read_some(...); It would be nice if you could write: bp::child c = start_child(); bp::pistream &is = c.get_stdout(); is.async_read_some(...); The first question is then where to pass the io_service instance to Boost.Process? In Boost.Asio I/O objects are typically initialized with io_service. As both child and pistream are created in the library io_service would need to be passed to Boost.Process when the child is spawned. However developers who don't want to use asynchronous I/O really shouldn't create an io_service instance first. If io_service is not passed to the constructor I wonder where to pass it then? As far as I see there are no recommendations or guidelines in the Boost.Asio documentation (probably because all I/O objects so far are always initialized with io_service). Another idea is of course adding a new class to Boost.Process (pistream would then only be used for synchronous I/O)? Right now I'd probably go this way? Boris

Hello Boris, I tried the Process library with msvc .net 2008 (vc9) sp1 on win XP sp3. However, the example async_io.cpp does not work properly. The function end_read does not be called at all neither in debug nor in release mode. I looked into the asio implementation but got lost by the details which I haven't mastered.
It would be nice if you could write:
bp::child c = start_child(); bp::pistream &is = c.get_stdout(); is.async_read_some(...);
Yes, please.
The first question is then where to pass the io_service instance to Boost.Process? In Boost.Asio I/O objects are typically initialized with io_service. As both child and pistream are created in the library io_service would need to be passed to Boost.Process when the child is spawned. However developers who don't want to use asynchronous I/O really shouldn't create an io_service instance first.
Maybe not an asio service object but a lightweight wrapper of the object. I would hide the usage of asio from the Process interface.
Another idea is of course adding a new class to Boost.Process (pistream would then only be used for synchronous I/O)? Right now I'd probably go this way? Fine.
With best regards Johannes

On Fri, 03 Oct 2008 19:45:25 +0200, Johannes Brunen <JBrunen@datasolid.de> wrote: Hi Johannes,
I tried the Process library with msvc .net 2008 (vc9) sp1 on win XP sp3. However, the example async_io.cpp does not work properly. The function end_read does not be called at all neither in debug nor in release mode.
oh, looks like I forgot to call io_service.run(). Can you please try the attached file? I could build it with MSVC 2008 SP1 and run it successfully.
[...]Maybe not an asio service object but a lightweight wrapper of the object. I would hide the usage of asio from the Process interface.
Thanks for your comment! Boris

Hi Boris, "Boris" <boriss@web.de> schrieb im Newsbeitrag news:op.uigqffpn9dsao3@burk...
oh, looks like I forgot to call io_service.run(). Yes, now it works as expected. Thanks...
I have another question with respect to this example. Why are you using the bind call? Calling in.async_read_some(boost::asio::buffer(buffer), end_read) seems to work perfectly well. Best, Johannes

Hi Boris, yet another problem this time with win32_startup.cpp example. At first, I had to change the STARTUPINFO struct into a STARTUPINFOA struct in order to compile the code. However, a more serious problem showed up in file win32_ops.hpp line 81. boost::shared_array<char> cmdline(new char[size]); cmdline.get()[0] = '\0'; In the example the size is zero, because no arguments are provided. I do not know what exactly new char[0] should be in standardese. However, IMHO the next line does not work for this case. cmdline.get()[0] = '\0'; Later, on destruction of the shared_array cmdline an exception is thrown in function checked_array_delete on calling operator delete[]. Johannes

On Fri, 03 Oct 2008 22:35:03 +0200, Johannes Brunen <JBrunen@datasolid.de> wrote: Hi Johannes,
yet another problem this time with win32_startup.cpp example. At first, I had to change the STARTUPINFO struct into a STARTUPINFOA struct in order to compile the code.
the examples are automatically built but not run (only the test cases are). Looks like I have to check the examples again. I've fixed now async_io.cpp and win32_startup.cpp (fixed version attached) and will release another Boost.Process 0.31 version soon. Thanks for the bug reports, Boris
[...]
participants (2)
-
Boris
-
Johannes Brunen