Exemplo n.º 1
0
void *generator_new_(void (*fn)(void *), size_t retsize)
{
	char *base;
	size_t size = DEFAULT_STATE_SIZE;
	size_t metasize = generator_metasize(retsize);
	struct coroutine_stack *stack;
	void *ret;
	struct generator_ *gen;

	base = malloc(size);
	if (!base)
		abort();

	retsize = (retsize + STATE_ALIGN) & ~(STATE_ALIGN - 1);

	stack = coroutine_stack_init(base, size, metasize);
	gen = coroutine_stack_to_metadata(stack, metasize);
	ret = gen + 1;

	gen->base = base;
	gen->complete = false;

	coroutine_init(&gen->gen, fn, ret, stack);

	return ret;
}
Exemplo n.º 2
0
int main()
{
	coenv_t env = coroutine_init();

	myctx ctx1 = {1};
	myctx ctx2 = {2};
	myctx ctx3 = {3};

	int i;
	int co1, co2, co3;

	co1 = coroutine_new(env, cofunc, &ctx1);
	printf("coroutine_new %d\n", co1);
	co2 = coroutine_new(env, cofunc, &ctx2);
	printf("coroutine_new %d\n", co2);
	co3 = coroutine_new(env, cofunc, &ctx3);
	printf("coroutine_new %d\n", co3);

	for (i = 0; i < 10; i++)
	{
		coroutine_resume(env, co1);
		coroutine_resume(env, co2);
		coroutine_resume(env, co3);
	}

	coroutine_uninit(env);

	getchar();

	return 0;
}
Exemplo n.º 3
0
static rich_Sink* json_new_sink(void* _self, Output* out) {
  JSONSink* self = malloc(sizeof(JSONSink));
  self->base._impl = &json_sink_impl;
  self->out = out;
  coroutine_init(self->co);
  coroutine_push(self->co, &root_state, 0);
  return &self->base;
}
Exemplo n.º 4
0
rich_Sink* rich_bind_sink(rich_Schema* schema, void* to) {
  BoundSink* self = malloc(sizeof(BoundSink));
  self->base._impl = &bound_sink_impl;
  self->schema = schema;
  self->to = to;
  coroutine_init(self->co);
  *(BoundSink**)coroutine_push(self->co, &sink_root_state, sizeof(BoundSink*)) = self;
  return &self->base;
}
static gboolean connect_delayed(gpointer data)
{
    SpiceChannel *channel = data;
    spice_channel *c = channel->priv;
    struct coroutine *co;

    SPICE_DEBUG("Open coroutine starting %p", channel);
    c->connect_delayed_id = 0;

    co = &c->coroutine;

    co->stack_size = 16 << 20; /* 16Mb */
    co->entry = spice_channel_coroutine;
    co->release = NULL;

    coroutine_init(co);
    coroutine_yieldto(co, channel);

    return FALSE;
}
Exemplo n.º 6
0
static void test_coroutine_simple(void)
{
    struct coroutine *self = coroutine_self();
    struct coroutine co = {
        .stack_size = 16 << 20,
        .entry = co_entry_42,
    };
    gpointer result;

    g_assert(coroutine_self_is_main());

    coroutine_init(&co);
    result = coroutine_yieldto(&co, GINT_TO_POINTER(42));
    g_assert_cmpint(GPOINTER_TO_INT(result), ==, 0x42);

    g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*!to->exited*");
    coroutine_yieldto(&co, GINT_TO_POINTER(42));
    g_test_assert_expected_messages();

    g_assert(self == coroutine_self());
    g_assert(coroutine_self_is_main());
}

static gpointer co_entry_two(gpointer data)
{
    struct coroutine *self = coroutine_self();
    struct coroutine co = {
        .stack_size = 16 << 20,
        .entry = co_entry_check_self,
    };

    g_assert(!coroutine_self_is_main());
    coroutine_init(&co);
    coroutine_yieldto(&co, &co);

    g_assert(self == coroutine_self());
    return NULL;
}

static void test_coroutine_two(void)
{
    struct coroutine *self = coroutine_self();
    struct coroutine co = {
        .stack_size = 16 << 20,
        .entry = co_entry_two,
    };

    coroutine_init(&co);
    coroutine_yieldto(&co, NULL);

    g_assert(self == coroutine_self());
}

static gpointer co_entry_yield(gpointer data)
{
    gpointer val;

    g_assert(data == NULL);
    val = coroutine_yield(GINT_TO_POINTER(1));
    g_assert_cmpint(GPOINTER_TO_INT(val), ==, 2);

    g_assert(!coroutine_self_is_main());

    val = coroutine_yield(GINT_TO_POINTER(3));
    g_assert_cmpint(GPOINTER_TO_INT(val), ==, 4);

    return NULL;
}

static void test_coroutine_yield(void)
{
    struct coroutine *self = coroutine_self();
    struct coroutine co = {
        .stack_size = 16 << 20,
        .entry = co_entry_yield,
    };
    gpointer val;

    coroutine_init(&co);
    val = coroutine_yieldto(&co, NULL);

    g_assert(self == coroutine_self());
    g_assert_cmpint(GPOINTER_TO_INT(val), ==, 1);

    val = coroutine_yieldto(&co, GINT_TO_POINTER(2));

    g_assert(self == coroutine_self());
    g_assert_cmpint(GPOINTER_TO_INT(val), ==, 3);

    val = coroutine_yieldto(&co, GINT_TO_POINTER(4));

    g_assert(self == coroutine_self());
    g_assert(val == NULL);

    g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*!to->exited*");
    coroutine_yieldto(&co, GINT_TO_POINTER(42));
    g_test_assert_expected_messages();
}

int main(int argc, char* argv[])
{
    g_test_init(&argc, &argv, NULL);

    g_test_add_func("/coroutine/simple", test_coroutine_simple);
    g_test_add_func("/coroutine/two", test_coroutine_two);
    g_test_add_func("/coroutine/yield", test_coroutine_yield);

    return g_test_run ();
}