2013年1月2日水曜日

boost::asio::io_service と cancel

なんか、以下のようなコードのコンパイルが通らなくて、???てなってたんですわ。
void foo( const boost::system::error_code& error ) {
  if( error ) {
    // キャンセル操作
  } else {
    // 通常操作
  }
}

int main() {
  boost::asio::io_service service;

  service.post( boost::bind( foo, boost::asio::placeholders::error ) );

  return 0;
}
えーっ?なんでー?と思ったら、そもそも boost::asio::io_service には、cancel 操作も無ければ、キューに溜め込んだ handler をクリアする仕組みも無いみたいで。stackoverflow には、こんなワークアラウンドが…
void clear( boost::asio::io_service& service )
{
    service.stop();
    service.~io_service();
    new( &service ) boost::asio::io_service;
}
見ての通り、プレスメント・コンストラクタ使って強引にクリアしてます。いや、まぁ、いいけど…。なんでキャンセルなりクリアなりの操作が無いんだろうか?ちょっと納得がいかない…。  こっちのんが、まだ抵抗感は少ないけど、同じですね。
  std::auto_ptr service( new boost::asio::io_service );

  ...
  service.reset( new boost::asio::io_service );
2013/1/3 追記: 結局キャンセル処理は、クラスメンバ関数を bind させて、クラスメンバのフラグで制御する事にしました。以下のような感じのコード
  class Foo {
  private:
    bool canceled_;
  private:
    void a_handler() {
      if( canceled_ ) {
        // キャンセル処理
      } else {
        // 通常処理
      }
    } 
 public:
    Foo() : canceled_(false) {}
  };

  ...

  Foo f;
  service.post( std::bind( &Foo::a_handler, &f ) );

0 件のコメント: