ActiveObject support classes

Listing 1. FutureResult

/**
FutureResult is parameterised on result type,
so we can use this class for all results
*/
template <typename ResultT>
class FutureResult
{
public:
    FutureResult() :
        m_resultReady(false)
    {}

    // find whether result can be retrieved yet
    bool isResultReady() const
    {
        boost::mutex::scoped_lock lock(m_mutex);
        return m_resultReady;
    }

    // retrieve result, blocking if not yet available
    ResultT getResult()
    {
        boost::mutex::scoped_lock lock(m_mutex);
        if(m_resultReady == false)
        {
            // block until result becomes available
            m_resultReadyCondition.wait(lock);
        }
        return m_result;
    }

    void setResult(const ResultT& result)
    {
        boost::mutex::scoped_lock lock(m_mutex);
        m_result = result;
        m_resultReady = true;

        // wake all threads waiting on the result to arrive
        m_resultReadyCondition.notify_all();
    }

private:
    boost::mutex m_mutex;
    boost::condition m_resultReadyCondition;

    bool m_resultReady;
    ResultT m_result;
};

Listing 2. MethodRequest and ConcreteMethod

/**
Abstract base class allows all ConcreteMethods (possibly with different return types)
to be executed polymorphically. This decouples the Activation List from the concrete type 
of a method request.
*/
class MethodRequest
{
public:
    virtual void execute() = 0;
    virtual ~MethodRequest();
};


/**
The design of ConcreteMethod is strongly coupled to:
- FutureResult
- the use of boost::shared_ptr for the ref-counted FutureResult
- the use of boost::function for the callback type
These aspects could have been factored into template parameters, but were coupled (by design)
since these components are designed to work together. These additional constraints
make them safer and easier to use together.
*/
template <typename ReturnT>
class ConcreteMethod : public MethodRequest
{
public:
    typedef boost::function<ReturnT (void)> CallbackT;

    ConcreteMethod(shared_ptr<FutureResult<ReturnT> > resultFuture, CallbackT callback) : 
        m_resultFuture(resultFuture),
        m_callback(callback)
    {}

    virtual void execute()
    {
        // call the callback (which will have been bound to a method on the Servant)
        // and assign the result to the shared FutureResult object
        // (making the result available to, and waking, any waiting clients)
        m_resultFuture->setResult(m_callback());
    }

private:
    shared_ptr<FutureResult<ReturnT> > m_resultFuture;
    CallbackT m_callback;
};