2016-11-04 8 views
-2

ドメイン(asio::local::stream_protocol::endpoint)とTCPソケット(asio::ip::tcp::endpoint)に接続するためにasio::generic::stream_protocol::socketを使用するクラスがあります。ユニットテストを実行するとio_serviceが無期限にブロックされるようです

このクラスをテストするには、Catchフレームワークを使用して、1つのファイルに一連の単体テストがあります。

私は突然問題に遭遇しました。テストを実行すると、突然動かなくなります。 -DASIO_ENABLE_HANDLER_TRACKINGをコンパイラのフラグに渡すと、async_connectに固執することがわかります。これは私がすべてのテストをコメントすると起こりません。私は2つのテストを持っている場合、彼らはドメインやTCPソケットに接続するかどうか、またはそれぞれのいずれかに接続しても、私は閉塞を取得します。

ASIOの出力が変化するが、これは一例です:

$ tests/unit_tests 
@asio|1478248907.3|0*1|[email protected]_wait 
@asio|1478248907.301276|0*2|[email protected]_resolve 
@asio|1478248907.301322|>1|ec=system:0 
@asio|1478248907.301328|<1| 
@asio|1478248907.302052|>2|ec=system:0,... 
@asio|1478248907.302186|2*3|[email protected]_connect 
@asio|1478248907.302302|<2| 
@asio|1478248907.302468|>3|ec=system:0 
@asio|1478248907.302481|<3| 
@asio|1478248907.302551|0*4|[email protected]_send 
@asio|1478248907.302611|>4|ec=system:0,bytes_transferred=23 
@asio|1478248907.302617|<4| 
@asio|1478248907.302621|0*5|[email protected]_receive(null_buffers) 
@asio|1478248907.356478|>5|ec=system:0,bytes_transferred=0 
@asio|1478248907.356547|<5| 
@asio|1478248907.356622|0|[email protected] 
@asio|1478248907.372967|0|deadli[email protected] 
@asio|1478248907.372981|0|[email protected] 
@asio|1478248907.373509|0*6|[email protected]_wait 
@asio|1478248907.373526|0*7|[email protected]_resolve 
@asio|1478248907.374910|>7|ec=system:0,... 
@asio|1478248907.374946|7*8|[email protected]_connect 
@asio|1478248907.375014|<7| 
@asio|1478248907.375127|>8|ec=system:0 
@asio|1478248907.375135|<8| 

私の質問は:ユニットテストオープンとクローズの接続を実行している問題は何ですか?これがno-noの場合、async_openを使用する単体テストをどのように記述しますか?

+2

あなたは[mcve]を提供していただけますか?ハンドラトラッキング出力は、成功したとして2つの 'async_connect'オペレーションを示します。デバッガが接続されている場合、ブロックされたスレッドのトレースバックは何ですか? 'async_open'はユーザー定義のより高いレベルの操作ですか? –

答えて

0

問題は、私がtcp :: resolverの出力を反復していた方法に関連しているようです。

0

io_serviceは、実際に完了ハンドラを実行runrun_onepollpoll_one方法を有しています。 Boost asioは独自のスレッドを持っているかもしれませんが、それらのスレッド状態はあなたのハンドラを呼び出すために正しくないかもしれません。したがって、単体テストでも、どのスレッドが補完ハンドラを呼び出すのかを把握する必要があります。

第2に、runが完了して実行されます。あなたの説明(最初のテストが成功すると、2番目のテストが失敗する)から、runに電話したように聞こえますが、resetrunio_serviceになりませんでした。

+0

テストは失敗せず、ただ凍ります。同じクラスの異なるインスタンスがスレッドを共有できますか? Asioのすべての用途で共有される単一の状態はありますか? – ruipacheco

+0

@ruipacheco:オブジェクトがスレッドを共有できるかどうかはわかりません。 Boost asioは 'io_service'に状態を持ち、1つのオブジェクトを共有するのか複数のインスタンスを使うのかをもう一度決めます。 'io_service.run()'は複数のスレッドから呼び出すことができます。 – MSalters

関連する問題