Я использую boost::signals2 и у меня проблема с управлением соединением. Я сохраняю scoped_connections в списке, который позже сокращается. Однако я обнаружил, что если объект, владеющий связанным сигналом, был уничтожен, scoped_connection::disconnect() прерывается, потому что некоторые из его полей теперь недействительны.
signals2::connection conn =
client->connectRequest( RequestSignal::slot_type(
bind( &Manager::requestRefresh, this, _1 ) ).track( client ) );
mClients.push_back( ClientConnection( client, conn ) );
Клиентское соединение:
struct ClientConnection
{
weak_ptr<Client> client;
signals2::scoped_connection* connection;
ClientConnection( weak_ptr<Client> aClient, signals2::connection aConnection )
{
client = aClient;
connection = new signals2::scoped_connection( aConnection );
}
~ClientConnection()
{
delete connection;
}
}
Класс Manager владеет списком этих ClientConnections и периодически выполняет итерацию и пытается удалить записи, из которых он не может получить законный shared_ptr для клиента. Теперь я узнал, что track() не отключает соединение, когда срок действия его объекта истекает, как я думал; это просто предотвращает срабатывание сигнала. Когда клиент выходит за пределы области действия, scoped_connection в конечном итоге указывает на кучу плохой памяти, и я получаю предварительную выборку или прерывание данных, когда он выполняет разъединение().
Есть ли что-то в API signal2, что я упустил из виду, что может исправить эту проблему? Или мне нужно переосмыслить управление подключением? Я знаю, что кажется странным поддерживать соединения с сигналами клиентов с этого конца, но поток, который потребляет клиент, может выйти за рамки, поэтому в этом случае мне нужно отключить слот диспетчера от клиента.