汎用的な Balking コンテナ

を作ってみた。

#ifndef ANMELT_THREAD_BALKING_CONTAINER_H_INCLUDED
#define ANMELT_THREAD_BALKING_CONTAINER_H_INCLUDED

// Boost
#include <boost/thread.hpp>

namespace anmelt{ namespace thread
{

template<class Container, class Adapter>
class balking_container
{
private:
    Container container_;
    boost::mutex mutex_;

public:
    template<class T>
    bool push(T v)
    {
        boost::mutex::scoped_lock lock(mutex_);
        return Adapter::push(container_, v);
    }

    template<class T>
    bool pop(T& v)
    {
        boost::mutex::scoped_lock lock(mutex_);
        return Adapter::pop(container_, v);
    }
};

}}

#endif // ANMELT_THREAD_BALKING_CONTAINER_H_INCLUDED

コンテナが受け付けられる状態じゃない場合は、blocking_container みたいに待つのではなく、さっさと false を返す。
これを前回作った Adapter と組み合わせれば、

template<class T>
class balking_queue :
    public balking_container<std::queue<T>, infinite_push_queue_adapter<T> > { };

template<class T, boost::uint32_t MaxSize>
class limited_balking_stack :
    public balking_container<std::stack<T>, limited_push_stack_adapter<T, MaxSize> > { };

こうやって書くことが出来る。


他にも n 回リトライするコンテナや、n ミリ秒待ってからリトライするようなコンテナなんかも Adapter を使い回して簡単に作ることが出来るはず。