2012-02-15 3 views
4

Я писал продолжение - в конкретной библиотеке coroutine. Он похож на std :: thread (кроме того, что он является кооперативным) - каждый контекст исполнения представлен в объекте продолжения.Есть ли какой-либо метод, который вызывает разворот целых стеков в C++? (за исключением исключения)

Проблема примерно продолжение объект уничтожение. Если dtor для объекта продолжения вызывается, пока контекст выполнения не вышел изящно, он должен быть принудительно закрыт контекстом, разрушающим объект.

Таким образом, каждый объект C++ в стеке стека не будет уничтожен должным образом. Это может быть приятной ситуацией для всех - поэтому я решил найти решение.

В первый раз я думал использовать исключение для разворачивания фрейма стека, как показано ниже. (Обратите внимание, что ниже только недостатки псевдо-код.)

coroutine::~coroutine() 
{ 
    status = FORCED_EXIT; 
    switch_to(*this); 
} 

void coroutine::yield(coroutine& other_coroutine) 
{ 
    // switch to other context, halt until invocation by other context 
    switch_to(other_coroutine); 

    if (status_ != FORCED_EXIT) { 
     return; // resume 
    } else { 
     throw ContextClosingException; 
    } 
} 

void coroutine::entrypoint() 
{ 
    try { 
     entry_function_(); 
    } catch(ContextClosingException& e) { 
     switch_to(caller_coroutine); 
    } 
} 

Однако, я нашел критический недостаток. Любой код пользователя, который «исключает проглатывание», как показано ниже, полностью нарушит предположение о совместном планировании.

try { 
    ... 
} catch(...) { // ContextClosingException 
    // do nothing, just swallow exception. 
} 

Поэтому мне нужно найти другой способ вызова стека разматывать (или любой другой способ для уничтожения объекта стека в продолжении). Стандартный способ соответствия был бы приятным - но сама реализация продолжения зависит от API, специфичного для платформы, поэтому непривлекательный способ будет приемлемым. (Я использую win32)

+1

Если вы хотите совместное планирование в Windows, почему бы вам не использовать [волокна Win32] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682661.aspx)? –

+0

André Caron // Реализация самого планирования не является проблемой. Мое намерение состоит в том, чтобы сосредоточиться на разрушении контекста. – summerlight

+0

Но это происходит, если вы не выполняете свое собственное планирование? –

ответ

1

В стандарте C++ ничего не существует, что позволяет разворачивать стек за исключением исключений. Coroutines (или поддержка corountines) могут быть предложены после C++ 11 (об этом говорили во время конференции Going Native).

Вам нужно будет использовать вызовы C, специфичные для ОС (если они существуют, и я так не думаю), но, скорее всего, вы сами по себе с ASM. Вы можете взглянуть на библиотеку boost.context для типового решения.

+0

Вы можете посмотреть на функции 'ucontext' (' getcontext'/'setcontext'/etc). – Hugh