Межпотоковое кидание исключений
От: adontz Грузия http://adontz.wordpress.com/
Дата: 03.06.05 12:34
Оценка: 27 (4)
Решение судя по всему кросс-компиляторное.
Что кинуть исключение в другом потоке (и вообще как метод одноразовой передачи сообщения потоку)
template <typename _type_exception>
void _throw_remote_proc(_type_exception * exception_object)
{
    throw exception_object;
}
//
template <typename _type_exception>
__declspec(noreturn) void throw_remote(DWORD thread_id, _type_exception * exception_object)
{
    HANDLE hThread = OpenThread(THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, FALSE, thread_id);
    SuspendThread(hThread);
    CONTEXT context;
    ZeroMemory(&context, sizeof(context));
    context.ContextFlags = CONTEXT_CONTROL;
    GetThreadContext(hThread, &context);
    context.Eip = (DWORD)((void(*)(_type_exception *))&_throw_remote_proc<_type_exception>);
    *((DWORD *)context.Esp) = (DWORD)exception_object;
    context.Esp -= 4;
    SetThreadContext(hThread, &context);
    ResumeThread(hThread);
    CloseHandle(hThread);
}

тест

class ex
{
    public:
        int data;
    public:
        ex(): data(0)
        {
        }
        ex(int _data): data(_data)
        {
        }
};
//
bool ready = false;
//
DWORD CALLBACK ThreadProc(LPVOID lpParam)
{
    ready = true;
    try
    {
        for(;;)
        {
            Sleep(1);
        }
    }
    catch (ex * e)
    {
        // Попадаем сюда, то есть всё работает
        int x = e->data;
        delete e;
    }
    ready = true;
    return 0;
}
//
int main(int argc, char * argv[])
{
    DWORD thread_id;
    CloseHandle(CreateThread(NULL, 0, ThreadProc, NULL, 0, &thread_id));
    while (!ready)
    {
        Sleep(1);
    }
    ex * e = new ex(10);
    ready = false;
    throw_remote(thread_id, e);
    while (!ready)
    {
        Sleep(1);
    }
    return 0;
}

Мне такое удобно делать, чтоб остановить поток слушающий сокет, потому что message-queue там нету и по-другому сообщение не передать.
A journey of a thousand miles must begin with a single step © Lau Tsu
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.