Как я могу предотвратить прерывание signal2::scoped_connection в разъединении ()?

Я использую 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, что я упустил из виду, что может исправить эту проблему? Или мне нужно переосмыслить управление подключением? Я знаю, что кажется странным поддерживать соединения с сигналами клиентов с этого конца, но поток, который потребляет клиент, может выйти за рамки, поэтому в этом случае мне нужно отключить слот диспетчера от клиента.


person pelotron    schedule 24.05.2016    source источник


Ответы (1)


Оказывается, это проблема времени жизни объекта, а не проблема signal2. Я использовал необработанный указатель на соединение с ограниченной областью действия, чтобы обойти его некопируемое свойство. Но я упустил из виду, что когда структура копируется, когда она вставляется в список, оригинал уничтожается, что удаляет память указателя...

Изменение его на общий указатель устранило эту проблему.

person pelotron    schedule 25.05.2016