AsyncBridge: Add new wrapper class that bridges async sequences
This class encapsulates all the logic and operations required to correctly bridge an async operation into a sync function. In particular, it also makes it less easy to forget to check if the io_service exited because it was stop()ped.
This commit is contained in:
@@ -0,0 +1,47 @@
|
|||||||
|
#ifndef ASYNCHRONOUS_BRIDGE_H
|
||||||
|
#define ASYNCHRONOUS_BRIDGE_H
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
|
namespace smo {
|
||||||
|
|
||||||
|
class AsynchronousBridge
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AsynchronousBridge(boost::asio::io_service &io_service)
|
||||||
|
: io_service(io_service), isAsyncOperationComplete(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void setAsyncOperationComplete(void)
|
||||||
|
{
|
||||||
|
/** EXPLANATION:
|
||||||
|
* This empty post()ed message is necessary to ensure that the thread
|
||||||
|
* that's waiting on the io_service is signaled to wake up and check
|
||||||
|
* the io_service's queue.
|
||||||
|
*/
|
||||||
|
isAsyncOperationComplete.store(true);
|
||||||
|
io_service.post([]{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void waitForAsyncOperationCompleteOrIoServiceStopped(void)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
io_service.run_one();
|
||||||
|
if (isAsyncOperationComplete.load() || io_service.stopped())
|
||||||
|
{ break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool exitedBecauseIoServiceStopped(void) const
|
||||||
|
{ return io_service.stopped(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::atomic<bool> isAsyncOperationComplete;
|
||||||
|
boost::asio::io_service &io_service;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace smo
|
||||||
|
|
||||||
|
#endif // ASYNCHRONOUS_BRIDGE_H
|
||||||
Reference in New Issue
Block a user