当前位置 : 主页 > 编程语言 > c++ >

C:跨线程的错误处理问题

来源:互联网 收集:自由互联 发布时间:2021-06-23
一般来说,我使用异常来处理错误,但是我在这里遇到的问题是错误适用于不同于导致错误的线程. 基本上,窗口有自己的线程,并且必须由创建窗口的同一线程创建并重置direct3d设备.但是
一般来说,我使用异常来处理错误,但是我在这里遇到的问题是错误适用于不同于导致错误的线程.

基本上,窗口有自己的线程,并且必须由创建窗口的同一线程创建并重置direct3d设备.但是,创建设备可能会失败,因此我需要在尝试创建实例的线程中抛出异常,而不是窗口代码

回调函数:

void Callback(HWND hwnd, boost::function<void(HWND,LPARAM)> call, LPARAM lParam)
{
    //Make our stack allocated function object into a heap allocated one
    boost::function<void(HWND,LPARAM)> *callH = new boost::function<void(HWND,LPARAM)>(call);
    //send a message with a pointer to our function object in the WPARAM
    PostMessage(hwnd, WM_CALLBACK, (unsigned)callH, lParam);
}
LRESULT CALLBACK HookProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    //check for our custom message
    if(msg == WM_CALLBACK)
    {
        //retreive the function pointer from the WPARAM
        boost::function<void(HWND,LPARAM)> *callH = (boost::function<void(HWND,LPARAM)>*)wParam;
        //call it
        (*callH)(hwnd,lParam);
        //delete our heap allocated function object
        delete callH;
        return 0;
    }
    else
        //if there was nothing relevant to us, call the old message procedure
        return CallWindowProc(hooked[hwnd], hwnd, msg, wParam, lParam);
}
//std::map<HWND, WNDPROC> hooked;

请求窗口线程创建设备的代码

Graphics::Graphics(IWindow *_window, Size2<unsigned> _size)
:lost(false), reset(false), refCnt(0), backCol(0xFF000000),
started(false), exited(false),
window(_window), size(_size)
{
    window->AddRef();
    HWND hwnd = *((HWND*)window->GetHandle());
    CallbackHook(hwnd);
    Callback(hwnd, boost::bind(&Graphics::create, this), 0);

    while(!started)Sleep(100);
}
void Graphics::create()
{
...code that may throw various exceptions
    started = true;
}

所以基本上我需要create()方法抛出的异常被创建Graphics对象的异常handelers捕获,这是另一个线程.

也许你可以使用 Boost.Exception将调用包装在另一个函数中.

以下代码不起作用,但您可能会得到这个想法.

class Context
{
public:
    Context(HWND hwnd, const boost::function<void(HWND,LPARAM)>& f, LPARAM lParam)
    {
        // TODO: reroute call through Wrapper function.
    }

    void wait()
    {
        mutex::scoped_lock l(m);
        while (!finished)
        {
            c.wait(l);
        }
        if (ex)
            rethrow_exception(ex);
    }

private:
    void Wrapper()
    {
        try
        {
            f(/*params*/);
        }
        catch (...)
        {
            ex = current_exception();
        }
        mutex::scoped_lock l(m);
        finished = true;
        c.notify_all();
    }

    boost::function<void(HWND,LPARAM)> f;
    exception_ptr ex;
    bool finished;
    mutex m;
    condition c;
};

void Callback(HWND hwnd, const boost::function<void(HWND,LPARAM)>& f, LPARAM lParam)
{
    Context ctx(hwnd, f, lParam);

    ctx.wait();
}
网友评论