예제 #1
0
파일: main.cpp 프로젝트: JohnsonRanger/cerl
int main()
{
	coro_initialize();
	enum { STACKSIZE = 4096 };

	struct timeval tpend, tpstart;
	void* stack;
	stack = malloc(STACKSIZE);
	void* args = NULL;
	int count = 0;

	coro_create(testContext, test, args, stack, STACKSIZE);
	gettimeofday(&tpstart, 0);
	while(count++ < 1000000)
	{
		coro_transfer(mainContext, testContext);
	}
	gettimeofday(&tpend, 0);
	
	float timeuse = 1000000 * (tpend.tv_sec - tpstart.tv_sec) + tpend.tv_usec - tpstart.tv_usec; 
	timeuse /= 1000000; 
	printf("libcoro 切换1百万次耗时: %f 秒\n",timeuse); 

	free(stack);
//	printf("\nreturn to the main\n");
	return 0;
}
예제 #2
0
int _prepareFiber( Fiber *to, void *code, uintptr_t arg )
{
    /* Need to allocate stack manually. */
    to->sptr = last_stack ? (char *)last_stack : (char *)malloc( STACK_SIZE );
    coro_create( &to->coro_ctx, (coro_func)code, (void *)arg, to->sptr, STACK_SIZE );

    return 0;
}
예제 #3
0
int main(void){
	CoroP b = coro_create("ping", ping);
	CoroP c = coro_create("pong", pong);
	int i,j = 0;

	for(i=0; i<5; i++){
		coro_resume(b, j);
		j++;
		printf("main: %d\n", i);
		coro_resume(c, j);
		printf("main: %d\n", i);
	}

	j = coro_resume(b,0);
	j = coro_resume(c,0);
	return 0;
}
예제 #4
0
파일: co_sche.c 프로젝트: archyyu/kendylib
int32_t sche_spawn(sche_t s,void*(*fun)(void*),void*arg)
{
	if(s->coro_size > s->max_coro)
		return -1;
	coro_t co = coro_create(s,s->stack_size,coro_fun);
	co->arg = arg;
	co->fun = fun;
	++s->coro_size;
	double_link_push(&s->coros,&co->dblink);
	uthread_switch(s->co->ut,co->ut,co);
	return 0;
}
예제 #5
0
파일: co_sche.c 프로젝트: archyyu/kendylib
sche_t sche_create(int32_t max_coro,int32_t stack_size,void (*idel)(void*),void *idel_arg)
{
	init_system_time(10);
	sche_t s = calloc(1,sizeof(*s));
	s->stack_size = stack_size;
	s->max_coro = max_coro;
	s->active_list_1 = LINK_LIST_CREATE();
	s->active_list_2 = LINK_LIST_CREATE();
	s->_minheap = minheap_create(max_coro,_less);
	s->next_check_timeout = GetSystemMs() + 200;
	s->co = coro_create(s,0,NULL);
	s->idel = idel;
	s->idel_arg = idel_arg;
	double_link_clear(&s->coros);
	set_current_coro(s->co);
	return s;
}
예제 #6
0
coroutine* coro_alloc(void (*fn)(void*), void *arg, size_t stack) 
{
    coroutine *co = nil;
    co = cs_alloc(sizeof(coroutine) + stack);
    if(co == nil) {
        log_error("%s", "coro_alloc fail");
        return nil;
    } 
    memset(co, 0, sizeof(coroutine));
    //co->cid = coroidgen++;
    void* stk = (void*)(co + 1);   
    coro_create(&co->ctx, fn, arg, stk, stack);
    co->status = M_FREE;
    co->sched = nil;
    co->need_parallel = false;
    return co;
}
예제 #7
0
파일: uvc.c 프로젝트: whtc123/libuvc
void uvc_create(char *name, unsigned int size, coro_func func, void *arg){
	uvc_ctx *ctx = (uvc_ctx *)malloc(sizeof(uvc_ctx));
	memset(ctx, 0, sizeof(uvc_ctx));
	//ctx->data=arg;
	coro_stack_alloc(&ctx->stack, size);
	coro_create(&ctx->cur, func, arg, ctx->stack.sptr, ctx->stack.ssze);
	if (name == NULL || strlen(name) == 0){
		sprintf(ctx->name, "coro");
	}
	else{
		sprintf(ctx->name, name);
	}
	uvc_ready(ctx);
	//uvc_resume(ctx);

	return;
}
예제 #8
0
파일: uvc.c 프로젝트: whtc123/libuvc
static uvc_thread_env *uvc_get_env(){
	uvc_ctx *ctx = NULL;
	uv_once(&once,uvc_init);
	uvc_thread_env *env=(uvc_thread_env *)uv_key_get(&uvc_key);
	if(env==NULL){
		env=(uvc_thread_env *)malloc(sizeof(uvc_thread_env));
		memset(env,0,sizeof(uvc_thread_env));
		env->loop = uv_loop_new();
		queue_init(&env->pending_queue);
		queue_init(&env->ready_queue);
		
		ctx = (uvc_ctx *)malloc(sizeof(uvc_ctx));
		memset(ctx, 0, sizeof(uvc_ctx));
		coro_stack_alloc(&ctx->stack, 0);
		coro_create(&ctx->cur, NULL, NULL, ctx->stack.sptr, ctx->stack.ssze);
		sprintf(ctx->name, "ROOT");
		env->schedule_task = ctx;
		env->runing_task = ctx;
		ctx->status = UVC_STATUS_RUNING;
		uv_key_set(&uvc_key,env);
	}
	return env;
}
void swoole_websocket_onOpen(http_context *ctx)
{
#if PHP_MAJOR_VERSION < 7
    TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL);
#endif

    int fd = ctx->fd;

    swConnection *conn = swWorker_get_connection(SwooleG.serv, fd);
    if (!conn)
    {
        swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_CLOSED, "session[%d] is closed.", fd);
        return;
    }
    conn->websocket_status = WEBSOCKET_STATUS_ACTIVE;

    zend_fcall_info_cache *cache = php_swoole_server_get_cache(SwooleG.serv, conn->from_fd, SW_SERVER_CB_onOpen);
    if (cache)
    {
        swServer *serv = SwooleG.serv;
        zval *zserv = (zval *) serv->ptr2;
        zval *zrequest_object = ctx->request.zobject;
        zval *retval = NULL;

#ifndef SW_COROUTINE
        zval **args[2];
        args[0] = &zserv;
        args[1] = &zrequest_object;
#else
        zval *args[2];
        args[0] = zserv;
        args[1] = zrequest_object;
#endif

#ifndef SW_COROUTINE
        zval *zcallback = php_swoole_server_get_callback(SwooleG.serv, conn->from_fd, SW_SERVER_CB_onOpen);
        if (sw_call_user_function_fast(zcallback, cache, &retval, 2, args TSRMLS_CC) == FAILURE)
        {
            swoole_php_error(E_WARNING, "onOpen handler error");
        }
#else
        int ret = coro_create(cache, args, 2, &retval, NULL, NULL);
        if (ret != 0)
        {
            if (ret == CORO_LIMIT)
            {
                SwooleG.serv->factory.end(&SwooleG.serv->factory, fd);
            }
            return;
        }
#endif
        if (EG(exception))
        {
            zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
        }
        if (retval)
        {
            sw_zval_ptr_dtor(&retval);
        }
    }
}
int swoole_websocket_onMessage(swEventData *req)
{
#if PHP_MAJOR_VERSION < 7
    TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL);
#endif

    int fd = req->info.fd;

    zval *zdata;
    SW_MAKE_STD_ZVAL(zdata);

    char frame_header[2];
    php_swoole_get_recv_data(zdata, req, frame_header, 2);

    long finish = frame_header[0] ? 1 : 0;
    long opcode = frame_header[1];

    zval *zframe;
    SW_MAKE_STD_ZVAL(zframe);
    object_init_ex(zframe, swoole_websocket_frame_class_entry_ptr);

    zend_update_property_long(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("fd"), fd TSRMLS_CC);
    zend_update_property_bool(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("finish"), finish TSRMLS_CC);
    zend_update_property_long(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("opcode"), opcode TSRMLS_CC);
    zend_update_property(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("data"), zdata TSRMLS_CC);

    swServer *serv = SwooleG.serv;
    zval *zserv = (zval *) serv->ptr2;

#ifndef SW_COROUTINE
    zval **args[2];
    args[0] = &zserv;
    args[1] = &zframe;
#else
    zval *args[2];
    args[0] = zserv;
    args[1] = zframe;
#endif

    zval *retval = NULL;

#ifndef SW_COROUTINE
    zend_fcall_info_cache *fci_cache = php_swoole_server_get_cache(serv, req->info.from_fd, SW_SERVER_CB_onMessage);
    zval *zcallback = php_swoole_server_get_callback(SwooleG.serv, req->info.from_fd, SW_SERVER_CB_onMessage);
    if (sw_call_user_function_fast(zcallback, fci_cache, &retval, 2, args TSRMLS_CC) == FAILURE)
    {
        swoole_php_error(E_WARNING, "onMessage handler error");
    }
#else
    zend_fcall_info_cache *cache = php_swoole_server_get_cache(serv, req->info.from_fd, SW_SERVER_CB_onMessage);
    int ret = coro_create(cache, args, 2, &retval, NULL, NULL);
    if (ret != 0)
    {
        sw_zval_ptr_dtor(&zdata);
        sw_zval_ptr_dtor(&zframe);
        if (ret == CORO_LIMIT)
        {
            SwooleG.serv->factory.end(&SwooleG.serv->factory, fd);
        }
        return SW_OK;
    }
#endif
    if (EG(exception))
    {
        zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
    }
    if (retval)
    {
        sw_zval_ptr_dtor(&retval);
    }
    sw_zval_ptr_dtor(&zdata);
    sw_zval_ptr_dtor(&zframe);
    return SW_OK;
}
예제 #11
0
static PHP_METHOD(swoole_coroutine_util, create)
{
    zval *callback;
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &callback) == FAILURE)
    {
        return;
    }

    sw_zval_add_ref(&callback);
    callback = sw_zval_dup(callback);

    char *func_name = NULL;
    zend_fcall_info_cache *func_cache = emalloc(sizeof(zend_fcall_info_cache));
    if (!sw_zend_is_callable_ex(callback, NULL, 0, &func_name, NULL, func_cache, NULL TSRMLS_CC))
    {
        swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name);
        sw_zval_free(callback);
        efree(func_name);
        return;
    }
    efree(func_name);

    php_swoole_check_reactor();

    if (swReactorCheckPoint == NULL)
    {
        coro_init(TSRMLS_C);
    }

    zval *retval = NULL;
    zval *args[1];

    jmp_buf *prev_checkpoint = swReactorCheckPoint;
    swReactorCheckPoint = emalloc(sizeof(jmp_buf));

    php_context *cxt = emalloc(sizeof(php_context));
    coro_save(cxt);
    int ret = coro_create(func_cache, args, 0, &retval, NULL, NULL);
    efree(func_cache);
    efree(swReactorCheckPoint);

    if (ret < 0)
    {
        sw_zval_free(callback);
        RETURN_FALSE;
    }
    //save callback
    COROG.current_coro->function = callback;

    swReactorCheckPoint = prev_checkpoint;
    coro_resume_parent(cxt, retval, retval);
    efree(cxt);
    if (EG(exception))
    {
        zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
    }
    if (retval != NULL)
    {
        sw_zval_ptr_dtor(&retval);
    }
    RETURN_TRUE;
}
예제 #12
0
파일: client.c 프로젝트: anhdocphys/ugh
static
void ugh_client_wcb_recv(EV_P_ ev_io *w, int tev)
{
	int nb;
	ugh_client_t *c = aux_memberof(ugh_client_t, wev_recv, w);

	nb = aux_unix_recv(w->fd, c->buf_recv.data, c->buf_recv.size);
	log_debug("client recv: %d: %.*s", nb, nb, c->buf_recv.data);

	if (0 == nb)
	{
		ugh_client_del(c);
		return;
	}

	if (0 > nb)
	{
		if (EAGAIN == errno)
		{
			ev_timer_again(loop, &c->wev_timeout);
			return;
		}

		ugh_client_del(c);
		return;
	}

	c->buf_recv.data += nb;
	c->buf_recv.size -= nb;

	ev_timer_again(loop, &c->wev_timeout);

	if (NULL == c->request_end)
	{
		int status = ugh_parser_client(c, c->buf_recv.data - nb, nb);

		if (UGH_AGAIN == status)
		{
			return;
		}

		if (UGH_HTTP_BAD_REQUEST <= status)
		{
			ugh_client_send(c, status);
			return;
		}

		if (UGH_HTTP_POST == c->method)
		{
			ugh_header_t *hdr_content_length = ugh_client_header_get_nt(c, "Content-Length");

			if (0 != hdr_content_length->value.size)
			{
				c->content_length = atoi(hdr_content_length->value.data);

				if (c->content_length > (c->buf_recv.size + (c->buf_recv.data - c->request_end)))
				{
					c->body.data = aux_pool_nalloc(c->pool, c->content_length);
					c->body.size = c->buf_recv.data - c->request_end;

					memcpy(c->body.data, c->request_end, c->body.size);

					c->buf_recv.data = c->body.data + c->body.size;
					c->buf_recv.size = c->content_length - c->body.size;
				}
				else
				{
					c->body.data = c->request_end;
					c->body.size = c->buf_recv.data - c->request_end;
				}

				if (c->body.size < c->content_length)
				{
					return;
				}
			}
		}
	}
	else if (UGH_HTTP_POST == c->method)
	{
		c->body.size += nb;

		if (c->body.size < c->content_length)
		{
			return;
		}
	}

	ev_io_stop(loop, &c->wev_recv);
	ev_timer_stop(loop, &c->wev_timeout);

#if 1 /* prepare post args */
	ugh_header_t *hdr_content_type = ugh_client_header_get_nt(c, "Content-Type");

	if (sizeof("application/x-www-form-urlencoded") - 1 == hdr_content_type->value.size &&
		0 == strncmp(hdr_content_type->value.data, "application/x-www-form-urlencoded", hdr_content_type->value.size))
	{
		ugh_parser_client_body(c, c->body.data, c->body.size);
	}
#endif

#if 1 /* UGH_CORO ENABLE */
	c->stack = aux_pool_malloc(c->pool, UGH_CORO_STACK);

	if (NULL == c->stack)
	{
		ugh_client_send(c, UGH_HTTP_INTERNAL_SERVER_ERROR);
		return;
	}

	coro_create(&c->ctx, ugh_client_ccb_handle, c, c->stack, UGH_CORO_STACK, &ctx_main);
	is_main_coro = 0;
	coro_transfer(&ctx_main, &c->ctx);
	is_main_coro = 1;
#endif

#if 0 /* UGH_CORO DISABLE */
	ugh_client_ccb_handle(c);
#endif
}