mirror of https://github.com/yandex/odyssey.git
machinarium: implement mm_condition/mm_signal functions
This commit is contained in:
parent
765d7f0e94
commit
7b08be8d08
58
src/mm.c
58
src/mm.c
|
@ -176,3 +176,61 @@ mm_cancel(mm_t envp, uint64_t id)
|
|||
mm_fiber_cancel(fiber);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mm_condition_timer_cb(uv_timer_t *handle)
|
||||
{
|
||||
mmfiber *fiber = handle->data;
|
||||
assert(fiber->condition);
|
||||
fiber->condition_status = -ETIMEDOUT;
|
||||
mm *f = fiber->data;
|
||||
mm_wakeup(f, fiber);
|
||||
}
|
||||
static inline void
|
||||
mm_condition_cancel_cb(mmfiber *fiber, void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
uv_timer_stop(&fiber->timer);
|
||||
uv_handle_t *handle = (uv_handle_t*)&fiber->timer;
|
||||
if (! uv_is_closing(handle))
|
||||
uv_close(handle, NULL);
|
||||
assert(fiber->condition);
|
||||
fiber->condition_status = -ECANCELED;
|
||||
mm *f = fiber->data;
|
||||
mm_wakeup(f, fiber);
|
||||
}
|
||||
|
||||
MM_API int
|
||||
mm_condition(mm_t envp, uint64_t time_ms)
|
||||
{
|
||||
mm *env = envp;
|
||||
mmfiber *fiber = mm_scheduler_current(&env->scheduler);
|
||||
if (mm_fiber_is_cancel(fiber))
|
||||
return -ECANCELED;
|
||||
fiber->condition = 1;
|
||||
fiber->condition_status = -1;
|
||||
uv_timer_start(&fiber->timer, mm_condition_timer_cb, time_ms, 0);
|
||||
mm_fiber_op_begin(fiber, mm_condition_cancel_cb, NULL);
|
||||
mm_scheduler_yield(&env->scheduler);
|
||||
mm_fiber_op_end(fiber);
|
||||
fiber->condition = 0;
|
||||
return fiber->condition_status;
|
||||
}
|
||||
|
||||
MM_API int
|
||||
mm_signal(mm_t envp, uint64_t id)
|
||||
{
|
||||
mm *env = envp;
|
||||
mmfiber *fiber = mm_scheduler_match(&env->scheduler, id);
|
||||
if (fiber == NULL)
|
||||
return -1;
|
||||
if (! fiber->condition)
|
||||
return -1;
|
||||
uv_timer_stop(&fiber->timer);
|
||||
uv_handle_t *handle = (uv_handle_t*)&fiber->timer;
|
||||
if (! uv_is_closing(handle))
|
||||
uv_close(handle, NULL);
|
||||
fiber->condition_status = 0;
|
||||
mm_wakeup(env, fiber);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ void mm_fiber_init(mmfiber *fiber)
|
|||
{
|
||||
memset(fiber, 0, sizeof(mmfiber));
|
||||
fiber->state = MM_FNEW;
|
||||
fiber->condition = 0;
|
||||
fiber->condition_status = 0;
|
||||
mm_fiber_op_end(fiber);
|
||||
mm_listinit(&fiber->waiters);
|
||||
mm_listinit(&fiber->link);
|
||||
|
|
|
@ -36,6 +36,8 @@ struct mmfiber {
|
|||
mmcontext context;
|
||||
mmfiber *resume;
|
||||
uv_timer_t timer;
|
||||
int condition;
|
||||
int condition_status;
|
||||
void *scheduler;
|
||||
void *data;
|
||||
mmlist waiters;
|
||||
|
|
Loading…
Reference in New Issue