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