| 267 | }; |
| 268 | |
| 269 | void resume(const fiber_t &fi_p) |
| 270 | { |
| 271 | static global_ctx_holder global_ctx; |
| 272 | win32_fiber *fi = static_cast<win32_fiber *>(fi_p.get()); |
| 273 | if (fi == nullptr) |
| 274 | throw internal_error("Resuming a corrupted fiber."); |
| 275 | if (fi->state == fiber_state::running || fi->state == fiber_state::finished) |
| 276 | throw lang_error("Fiber is not reentrant."); |
| 277 | if (fi->state == fiber_state::ready) { |
| 278 | fi->ctx = CreateFiber(fi->stack_size, win32_fiber::entry, fi); |
| 279 | if (fi->ctx == nullptr) |
| 280 | throw lang_error("Fiber create failed."); |
| 281 | if (!current_process->fiber_stack.empty()) |
| 282 | fi->prev_ctx = static_cast<win32_fiber *>(current_process->fiber_stack.top().get())->ctx; |
| 283 | else |
| 284 | fi->prev_ctx = global_ctx.ctx; |
| 285 | } |
| 286 | else if (fi->state == fiber_state::suspended) { |
| 287 | if (fi->prev_ctx == nullptr) |
| 288 | throw internal_error("Fiber context corrupted."); |
| 289 | fi->state = fiber_state::running; |
| 290 | } |
| 291 | current_process->fiber_stack.push(fi_p); |
| 292 | fi->cs_swap_in(); |
| 293 | SwitchToFiber(fi->ctx); |
| 294 | if (!current_process->fiber_stack.empty()) |
| 295 | current_process->fiber_stack.pop(); |
| 296 | else |
| 297 | throw internal_error("Fiber stack corrupted."); |
| 298 | if (!current_process->fiber_stack.empty()) |
| 299 | static_cast<win32_fiber *>(current_process->fiber_stack.top().get())->cs_swap_in(); |
| 300 | else |
| 301 | fi->cs_swap_out(); |
| 302 | if (fi->eptr != nullptr) { |
| 303 | std::exception_ptr e = nullptr; |
| 304 | std::swap(fi->eptr, e); |
| 305 | std::rethrow_exception(e); |
| 306 | } |
| 307 | } |
| 308 | |
| 309 | void yield() |
| 310 | { |
nothing calls this directly
no test coverage detected