C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: deadline_timerの延長方法


(過去ログ 92 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■55111 / inTopicNo.1)  deadline_timerの延長方法
  
□投稿者/ 出水 (1回)-(2010/11/17(Wed) 09:03:26)

分類:[C/C++] 

・イベントが飛んできたら30秒のタイマーを設置
・タイマー設置中にイベントが飛んできたら、タイマーを30秒にリセット
・30秒間イベントが飛んでこない場合、ある処理を実行

これをboost::asioとdeadline_timerを使って実現したいです

deadline_timerに何らかの手を加えてしまうと、async_waitに登録されたイベントが
即座に走ってしまうようです

deadline_timerにresetをかければ、エラーコードとしてboost::asio::error::operation_aborted が来るので、
これが来たときは再度30秒後に設定し直せばよさそうです
ただ、終了処理を目的としてresetをした時、30秒後に設定されてはまずいので、
絶対に起こり得ないエラーコードを使ってresetをかければ良いだろう、という方針まではあります

ですが、システムで予約されていないエラーコードを使う方法があればそれを知りたいです

よって、
・async_waitのイベントが呼ばれない形でタイマーを再設定する方法
・ユーザー定義のエラーコードの作成方法
のどちらかが知りたいです
引用返信 編集キー/
■55194 / inTopicNo.2)  Re[1]: deadline_timerの延長方法
□投稿者/ xyuyux (1回)-(2010/11/19(Fri) 19:45:42)
> よって、
> ・async_waitのイベントが呼ばれない形でタイマーを再設定する方法
> ・ユーザー定義のエラーコードの作成方法
> のどちらかが知りたいです


ユーザー定義のエラーコードの作成方法

#include <string>
#include <boost/system/error_code.hpp>

namespace api {
enum api_errors
{
  timer_reset = 1
};

// エラーのカテゴリを作成
class api_category_impl
  : public boost::system::error_category
{
public:
    virtual const char* name() const { return "api error"; }
    virtual std::string message(int ev) consessage(int ev) const
    {
        switch(ev)
        {
        case timer_reset:
            return "timer reset";
        default:
            return "unknown";
        }
    }
};

static const api_category_impl api_category_instance;

inline const boost::system::error_category& get_api_category()
{
    return api_category_instance;
}
} // namespace api

// error_conditionがシステムに依存しないユーザ定義用なのでerror_conditionに登録
namespace boost {
namespace system {
template<> struct is_error_condition_enum<api::api_errors>
{
    static const bool value = true;
};

} // namespace system
} // namespace boost

namespace api {

// error_codeへの変換関数
inline boost::system::error_code make_error_code(api::api_errors e)
{
    return boost::system::error_code(
        static_cast<int>(e), get_api_category());
}

// if (error == api::timer_reset)が出来るようにするために以下を作成
inline boost::system::error_condition make_error_condition(api::api_errors e)
{
    return boost::system::error_condition(
        static_cast<int>(e), get_api_category());
}

} // namespace api

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/shared_ptr.hpp>

void handler(const boost::system::error_code& error, boost::shared_ptr<boost::asio::deadline_timer>& timer)
{
    if (error == boost::asio::error::operation_aborted)
    {
        // キャンセル
        std::cout << "Abort." << std::endl;
    }
    else if (error == api::timer_reset)
    {
        // タイマリセット
        std::cout << "Try Again." << std::endl;
        timer->expires_from_now(boost::posix_time::seconds(10));
        timer->async_wait(boost::bind(&handler, _1, timer));
    }
    else
    {
        // Timer expired.
        std::cout << "Timer expired." << std::endl;
    }
}

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

    // 30秒タイマ設定
    boost::shared_ptr<boost::asio::deadline_timer> timer(
        new boost::asio::deadline_timer(io_service, boost::posix_time::seconds(30)));
    timer->async_wait(boost::bind(&handler, _1, timer));

    // タイマキャンセル
    timer->cancel();
    // タイマを再設定
    timer->get_io_service().post(boost::bind(&handler, api::make_error_code(api::timer_reset), timer));

    io_service.run();
    return 0;
}

引用返信 編集キー/
■55195 / inTopicNo.3)  Re[1]: deadline_timerの延長方法
□投稿者/ xyuyux (2回)-(2010/11/19(Fri) 19:48:18)
> よって、
> ・async_waitのイベントが呼ばれない形でタイマーを再設定する方法
> ・ユーザー定義のエラーコードの作成方法
> のどちらかが知りたいです


ユーザー定義のエラーコードの作成方法

#include <string>
#include <boost/system/error_code.hpp>

namespace api {
// エラーコードを定義
enum api_errors
{
  timer_reset = 1
};

// エラーのカテゴリを作成
class api_category_impl
  : public boost::system::error_category
{
public:
    virtpublic:
    virtual const char* name() const { return "api error"; }
    virtual std::string message(int ev) const
    {
        switch(ev)
        {
        case timer_reset:
            return "timer reset";
        default:
            return "unknown";
        }
    }
};

static const api_category_impl api_category_instance;

inline const boost::system::error_category& get_api_category()
{
    return api_category_instance;
}
} // namespace api

// error_conditionがシステムに依存しないユーザ定義用なのでerror_conditionに登録
namespace boost {
namespace system {
template<> struct is_error_condition_enum<api::api_errors>
{
    static const bool value = true;
};

} // namespace system
} // namespace boost

namespace api {

// error_codeへの変換関数
inline boost::system::error_code make_error_code(api::api_errors e)
{
    return boost::system::error_code(
        static_cast<int>(e), get_api_category());
}

// if (error == api::timer_reset)が出来るようにするために以下を作成
inline boost::system::error_condition make_error_condition(api::api_errors e)
{
    return boost::system::error_condition(
        static_cast<int>(e), get_api_category());
}

} // namespace api

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/shared_ptr.hpp>

void handler(const boost::system::error_code& error, boost::shared_ptr<boost::asio::deadline_timer>& timer)
{
    if (error == boost::asio::error::operation_aborted)
    {
        // キャンセル
        std::cout << "Abort." << std::endl;
    }
    else if (error == api::timer_reset)
    {
        // タイマリセット
        std::cout << "Try Again." << std::endl;
        timer->expires_from_now(boost::posix_time::seconds(10));
        timer->async_wait(boost::bind(&handler, _1, timer));
    }
    else
    {
        // Timer expired.
        std::cout << "Timer expired." << std::endl;
    }
}

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

    // 30秒タイマ設定
    boost::shared_ptr<boost::asio::deadline_timer> timer(
        new boost::asio::deadline_timer(io_service, boost::posix_time::seconds(30)));
    timer->async_wait(boost::bind(&handler, _1, timer));

    // タイマキャンセル
    timer->cancel();
    // タイマを再設定
    timer->get_io_service().post(boost::bind(&handler, api::make_error_code(api::timer_reset), timer));

    io_service.run();
    return 0;
}

引用返信 編集キー/
■55196 / inTopicNo.4)  Re[2]: deadline_timerの延長方法
□投稿者/ xyuyux (3回)-(2010/11/19(Fri) 19:50:02)
二重に投稿されちゃいました。orz
引用返信 編集キー/
■55233 / inTopicNo.5)  Re[3]: deadline_timerの延長方法
□投稿者/ 出水 (2回)-(2010/11/23(Tue) 03:41:25)
すいません、返事遅れました

ソースを動かしてチェックしていたら気が付いたのですが、
cancelに引数を渡したらasync_waitのハンドラーに
その引数が渡っていくものだと勘違いしていました。

また、async_waitハンドラーで無理に再設定しなくても
timer->expires_from_now(boost::posix_time::seconds(10));
timer->async_wait(boost::bind(&handler, _1, timer));
と呼び出してしまえば良さそうという気がしています。

とりあえずこの方法でやってみようと思います

ありがとうございました
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -