#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)
	: isAsyncOperationComplete(false), io_service(io_service)
	{}

	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
