Poco::HTTPServerの使用で問題が発生しています。TCPServerのドキュメントに記載されているように:
stop()を呼び出した後、新しい接続は受け入れられず、キューに入れられたすべての接続が破棄されます。ただし、すでに提供されている接続は引き続き提供されます。
すべての接続は独自のスレッドで実行されます。デストラクタは正常に接続と呼ばれているように見えますが、スレッドはまだ存在し、接続を提供しているため、セグメンテーション違反が発生します。
すべての接続をキャンセルしたい。したがってPoco::ThreadPool::defaultPool().stopAll();
、サーバークラスのデストラクタで使用します。これにより、ThreadPoolのドキュメントにも記載されている動作が発生します(10秒かかり、オブジェクトは削除されません)。
スレッドが10秒以内に停止しなかった場合(たとえば、プログラミングエラーのため)、基になるスレッドオブジェクトは削除されず、このメソッドはとにかく戻ります。これにより、スレッドの動作が正しくない場合に、多かれ少なかれ正常にシャットダウンできます。
私の質問は:どうすればもっと優雅な方法を達成できますか?Pocoライブラリ内のプログラミングエラーはありますか?
編集:IDEとしてEclipse+cdtを備えたGNU/Linux(Ubuntu 10.04)を使用しています。ターゲットシステムは組み込みLinux(カーネル2.6.9)です。両方のシステムで、説明されている動作を体験しました。
私が取り組んでいるアプリケーションは、Webインターフェイスを介して構成する必要があります。そのため、サーバーは(新しい構成のアップロード時に)イベントをmainに送信して再起動します。
概要は次のとおりです。
main{
while (true){
server = new Server(...);
server->start();
// wait for termination request
server->stop();
delete server;
}
}
class Server{
Poco:HTTPServer m_Server;
Server(...):
m_Server(requestHandlerFactory, socket, params);
{
}
~Server(){
[...]
Poco::ThreadPool::defaultPool().stopAll(); // This takes 10 seconds!
// without the above line I get segmentation faults,
// because connections are still being served.
}
start() { m_Server.start(); }
stop() { m_Server.stop(); }
}