boost::asio::deadline_timer
削除されたクラスに属する関数がによって呼び出され、セグメンテーション違反が発生することがある実際のコードに問題があります。
私が抱えている問題は、deadline_timerの削除が同じio_serviceの別のタイマーから実行されることです。最初の呼び出しを削除deadline_timer
すると、実行する関数への最後の呼び出しが1回トリガーされ、boost::asio::error::operation_aborted
エラーが発生します。io_service
ただし、これは削除が終了した後(同じ)にのみスケジュールできますが、それまでにオブジェクトはすでに削除されているため、無効になります。
だから私の質問は:どうすればこれが起こらないようにすることができますか?
以下は、同じ障害のある単純化された例です。
//============================================================================
// Name : aTimeToKill.cpp
// Author : Pelle
// Description : Delete an object using a timer, from a timer
//============================================================================
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
using namespace std;
using namespace boost;
struct TimeBomb
{
bool m_active;
asio::deadline_timer m_runTimer;
TimeBomb(boost::asio::io_service& ioService)
: m_active(true)
, m_runTimer(ioService)
{
cout << "Bomb placed @"<< hex << (int)this << endl;
m_runTimer.expires_from_now(boost::posix_time::millisec(1000));
m_runTimer.async_wait(boost::bind(&TimeBomb::executeStepFunction, this, _1));
}
~TimeBomb()
{
m_active = false;
m_runTimer.cancel();
cout << "Bomb defused @"<< hex << (int)this << endl;
}
void executeStepFunction(const boost::system::error_code& error)
{
// Canceled timer
if (error == boost::asio::error::operation_aborted)
{
std::cout << "Timer aborted: " << error.message() << " @" << std::hex << (int)this << std::endl;
return;
}
if (m_active)
{
// Schedule next step
cout << "tick .." <<endl;
m_runTimer.expires_from_now(
boost::posix_time::millisec(1000));
m_runTimer.async_wait(boost::bind(&TimeBomb::executeStepFunction, this, _1));
}
}
};
struct BomberMan
{
asio::deadline_timer m_selfDestructTimer;
TimeBomb* myBomb;
BomberMan(boost::asio::io_service& ioService)
: m_selfDestructTimer(ioService)
{
cout << "BomberMan ready " << endl;
myBomb = new TimeBomb(ioService);
m_selfDestructTimer.expires_from_now(boost::posix_time::millisec(10500));
m_selfDestructTimer.async_wait(boost::bind(&BomberMan::defuseBomb, this, _1));
}
void defuseBomb(const boost::system::error_code& error)
{
cout << "Defusing TimeBomb" << endl;
delete myBomb;
}
};
int main()
{
boost::asio::io_service m_ioService;
BomberMan* b = new BomberMan(m_ioService);
m_ioService.run();
return 0;
}
./aTimeToKill
BomberMan ready
Bomb placed @9c27198
tick ..
tick ..
tick ..
tick ..
tick ..
tick ..
tick ..
tick ..
tick ..
tick ..
Defusing TimeBomb
Bomb defused @9c27198
Timer aborted: Operation canceled @9c27198
最後の行は削除後に印刷され、私の問題を示しています。