On 11/06/2016 12:40 PM, Klemens Morgenstern wrote:
Am 06.11.2016 um 12:26 schrieb Bjorn Reese:
The pattern used in Asio is to have both synchronous and asynchronous functions:
return_value foo(args); return_value foo(args, error_code); void async_foo(args, void (*)(return_value, error_code));
If async_foo supports boost::asio::async_result, then the coroutine and fiber support can be implemented seperately from your library. Well there are two things. First you can use async_pipe as any asio I/O-Object, thus this should work with fiber. Secondly there's a special case for process::system, where you can suspend the coroutine for the time the process runs. This requires a custom solution, since the event handler is different - and must be. The reason is, that I need to start the async-wait on posix before launching the process, which would be sort of difficult, if the corutine get's suspendend when I do that.
Here is how you could implement an async_system() with async_result on Posix platforms. Replace waitpid() in bp::child with a self-pipe [1], set up a SIGCHLD handler which writes to the pipe (using the syscall write(2) to be async-signal-safe), and use asio to read from the pipe with the yield context. The biggest task here is that the signal handler must serve all child processes, so you would need one self-pipe per process, and the management of that map of self-pipes and process identifiers have to be async-signal-safe (which means you have to go lock-free.) Next, add async_result to async_system() and forward the handler to the asio read operation. This will immediately give you support for coroutines, futures, and (using the example from fiber.) With the above, you can completely remove the yield context meta programming from the process library, and thereby avoid having to mess around with its internals. [1] http://cr.yp.to/docs/selfpipe.html
I don't know really if anyone would like to use boost.fiber here; this however would require an implementation inside process/system.hpp. So I wouldn't add this now.
The point with async_result is that this can be done outside the process library.