У меня есть объект, который работает вокруг boost::asio::io_service
, который имеет некоторые свойства. Нечто подобное:Как подождать обработчик asio?
class Foo
{
private:
// Not an int in my real code, but it doesn't really matter.
int m_bar;
boost::asio::io_service& m_io_service;
boost::asio::strand m_bar_strand;
};
m_bar
должен использоваться только из обработчика, который вызывается через нити m_bar_strand
. Это позволяет мне не блокироваться внутри этих обработчиков.
Чтобы установить m_bar
свойство из вне потока, который проходит io_service::run()
я написал asynchronous_setter, например так:
class Foo
{
public:
void async_get_bar(function<void (int)> handler)
{
m_bar_strand.post(bind(&Foo::do_get_bar, this, handler));
}
void async_set_bar(int value, function<void()> handler)
{
m_bar_strand.post(bind(&Foo::do_set_bar, this, value, handler));
}
private:
void do_get_bar(function<void (int)> handler)
{
// This is only called from within the m_bar_strand, so we are safe.
// Run the handler to notify the caller.
handler(m_bar);
}
void do_set_bar(int value, function<void()> handler)
{
// This is only called from within the m_bar_strand, so we are safe.
m_bar = value;
// Run the handler to notify the caller.
handler();
}
int m_bar;
boost::asio::io_service& m_io_service;
boost::asio::strand m_bar_strand;
};
Это прекрасно работает, но теперь я хотел бы написать синхронную версию set_bar
, что устанавливает значение и возвращает только тогда, когда набор был эффективным. Он должен по-прежнему гарантировать, что эффективный набор будет установлен в пределах m_bar_strand
. В идеале, что-то повторное.
Я могу представить решения с семафорами, которые были бы изменены изнутри обработчика, но все, что я придумал, кажется хакерским и действительно не изящным. Есть ли что-то в Boost/Boost Asio, которое позволяет такое?
Как вы примените этот метод?
пустот sync_set_bar (INT значение, функции обработчик) { m_bar = значение; handler();} И идем вперед make m_bar boost :: atomic . –
IdeaHat
(хотя я не уверен, что вам требуется управление синхронизацией на m_bar, поэтому я могу просто надуть вас). Не нужно использовать asio, когда все не асинхронно. – IdeaHat
@MadScienceDreams: значение 'm_bar' (независимо от его типа) должно быть изменено (или доступно) из ** внутри ** обработчика, который запускается внутри' m_bar_strand'. Это предотвращает условия гонки без использования мьютексов и выглядит неплохо. Я просто хочу превратить асинхронный вызов в синхронный. – ereOn