Figure 5: IOUSink class implements method RequestComplete of the IResultNotifier interface

#ifndef _IOUSINK_H
#define _IOUSINK_H

#include "resultIOU.h"
#include <assert.h>

class IOUSink : public IResultNotifier
{
    long m_cRef;
    ITypeInfo *m_pTypeInfo;
    ResultIOU* m_pResultIOU;
    HANDLE resultMutex_;

public:
    IOUSink()
        : m_cRef(0), m_pResultIOU(0)
    {
        resultMutex_ = ::CreateMutex (NULL, FALSE, NULL);
    }

    IOUSink(ResultIOU* ResultIOU)
        : m_cRef(0), m_pResultIOU(ResultIOU)
    {
        resultMutex_ = ::CreateMutex (NULL, FALSE, NULL);
    }

    ~IOUSink()
    {
    }

    // IUnknown methods
    STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
    {
        if (riid == IID_IUnknown)
            *ppv = (IResultNotifier*)this;
        else if (riid == IID_IResultNotifier)
            *ppv = (IResultNotifier*)this;
        else if (riid == IID_IDispatch)
            *ppv = m_pTypeInfo ? (IResultNotifier*)this : 0;
        else 
        {
            *ppv = 0;
            return E_NOINTERFACE;
        }
        ((IUnknown*)*ppv)->AddRef();
        return S_OK;
    }

    STDMETHODIMP_(ULONG) AddRef()
    {
        return InterlockedIncrement(&m_cRef);
    }

    STDMETHODIMP_(ULONG) Release()
    {
        if (InterlockedDecrement(&m_cRef))
            return m_cRef;
        delete this;
        return 0;
    }


// IDispatch methods
    STDMETHODIMP GetTypeInfoCount(UINT *pctinfo)
    {
        *pctinfo = 1;
        return S_OK;
    }

    STDMETHODIMP GetTypeInfo(UINT ctinfo, 
                             LCID lcid, 
                             ITypeInfo **ppti)
    {
        if (ctinfo != 0)
        {
            *ppti = 0;
            return DISP_E_BADINDEX;
        }
        (*ppti = m_pTypeInfo)->AddRef();
        return S_OK;
    }

    STDMETHODIMP GetIDsOfNames(REFIID riid,
                               OLECHAR **rgszNames,
                               UINT cNames,
                               LCID lcid,
                               DISPID *rgdispid)
    {
        return m_pTypeInfo->GetIDsOfNames(rgszNames, 
                                          cNames, 
                                          rgdispid);
    }

    STDMETHODIMP Invoke(DISPID dispidMember,
                        REFIID riid,
                        LCID lcid,
                        WORD wFlags,
                        DISPPARAMS *pdispparams,
                        VARIANT *pvarResultIOU,
                        EXCEPINFO *pexcepinfo,
                        UINT *puArgErr)
    {
        return m_pTypeInfo->Invoke((IResultNotifier*)this,
                                   dispidMember, wFlags,
                                   pdispparams, pvarResultIOU,
                                   pexcepinfo, puArgErr);
    }


    STDMETHODIMP RequestComplete()
    {
        assert(m_pResultIOU);

        WaitForSingleObject(resultMutex_, INFINITE );
        m_pResultIOU->ResultIOUComplete();
        ReleaseMutex(resultMutex_);

        return S_OK;
    }

    void setResultIOU(ResultIOU* ResultIOU)
    {
        assert(ResultIOU);

        m_pResultIOU = ResultIOU;
    }
};