0

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 は大量の不良メモリを指し示し、disconnect() を実行するとプリフェッチまたはデータの中止が発生します。

この問題を修正できる、見落としていた signal2 API に何かありますか? または、接続管理を再考する必要がありますか? この端からクライアントのシグナルへの接続を維持する必要があるのは奇妙に思えますが、クライアントが消費するストリームが範囲外になる可能性があるため、その場合はマネージャーのスロットをクライアントから切断する必要があります。

4

1 に答える 1

0

これは、signals2 の問題ではなく、オブジェクトの有効期間の問題であることがわかりました。コピー不可のプロパティを回避するために、スコープ接続への生のポインターを使用しました。しかし、私が見落としていたのは、リストに挿入されたときに構造体がコピー構築されると、元の構造体が破壊され、ポインタのメモリが削除されるということです...

共有ポインターに変更すると、この問題が修正されました。

于 2016-05-25T14:34:47.250 に答える