예제 #1
0
파일: aiop_poll.c 프로젝트: DonkeyWs/tbox
static tb_long_t tb_aiop_rtor_poll_wait(tb_aiop_rtor_impl_t* rtor, tb_aioe_t* list, tb_size_t maxn, tb_long_t timeout)
{   
    // check
    tb_aiop_rtor_poll_impl_t* impl = (tb_aiop_rtor_poll_impl_t*)rtor;
    tb_assert_and_check_return_val(impl && impl->pfds && impl->cfds && list && maxn, -1);

    // the aiop
    tb_aiop_impl_t* aiop = rtor->aiop;
    tb_assert_and_check_return_val(aiop, tb_false);

    // loop
    tb_long_t wait = 0;
    tb_bool_t stop = tb_false;
    tb_hong_t time = tb_mclock();
    while (!wait && !stop && (timeout < 0 || tb_mclock() < time + timeout))
    {
        // copy pfds
        tb_spinlock_enter(&impl->lock.pfds);
        tb_vector_copy(impl->cfds, impl->pfds);
        tb_spinlock_leave(&impl->lock.pfds);

        // cfds
        struct pollfd*  cfds = (struct pollfd*)tb_vector_data(impl->cfds);
        tb_size_t       cfdm = tb_vector_size(impl->cfds);
        tb_assert_and_check_return_val(cfds && cfdm, -1);

        // wait
        tb_long_t cfdn = poll(cfds, cfdm, timeout);
        tb_assert_and_check_return_val(cfdn >= 0, -1);

        // timeout?
        tb_check_return_val(cfdn, 0);

        // sync
        tb_size_t i = 0;
        for (i = 0; i < cfdm && wait < maxn; i++)
        {
            // the sock
            tb_socket_ref_t sock = tb_fd2sock(cfds[i].fd);
            tb_assert_and_check_return_val(sock, -1);

            // the events
            tb_size_t events = cfds[i].revents;
            tb_check_continue(events);

            // spak?
            if (sock == aiop->spak[1] && (events & POLLIN))
            {
                // read spak
                tb_char_t spak = '\0';
                if (1 != tb_socket_recv(aiop->spak[1], (tb_byte_t*)&spak, 1)) return -1;

                // killed?
                if (spak == 'k') return -1;

                // stop to wait
                stop = tb_true;

                // continue it
                continue ;
            }

            // skip spak
            tb_check_continue(sock != aiop->spak[1]);

            // the aioo
            tb_size_t       code = TB_AIOE_CODE_NONE;
            tb_cpointer_t   priv = tb_null;
            tb_aioo_impl_t*      aioo = tb_null;
            tb_spinlock_enter(&impl->lock.hash);
            if (impl->hash)
            {
                aioo = (tb_aioo_impl_t*)tb_hash_get(impl->hash, sock);
                if (aioo) 
                {
                    // save code & data
                    code = aioo->code;
                    priv = aioo->priv;

                    // oneshot? clear it
                    if (aioo->code & TB_AIOE_CODE_ONESHOT)
                    {
                        aioo->code = TB_AIOE_CODE_NONE;
                        aioo->priv = tb_null;
                    }
                }
            }
            tb_spinlock_leave(&impl->lock.hash);
            tb_check_continue(aioo && code);
            
            // init aioe
            tb_aioe_t   aioe = {0};
            aioe.priv   = priv;
            aioe.aioo   = (tb_aioo_ref_t)aioo;
            if (events & POLLIN)
            {
                aioe.code |= TB_AIOE_CODE_RECV;
                if (code & TB_AIOE_CODE_ACPT) aioe.code |= TB_AIOE_CODE_ACPT;
            }
            if (events & POLLOUT) 
            {
                aioe.code |= TB_AIOE_CODE_SEND;
                if (code & TB_AIOE_CODE_CONN) aioe.code |= TB_AIOE_CODE_CONN;
            }
            if ((events & POLLHUP) && !(code & (TB_AIOE_CODE_RECV | TB_AIOE_CODE_SEND))) 
                aioe.code |= TB_AIOE_CODE_RECV | TB_AIOE_CODE_SEND;

            // save aioe
            list[wait++] = aioe;

            // oneshot?
            if (code & TB_AIOE_CODE_ONESHOT)
            {
                tb_spinlock_enter(&impl->lock.pfds);
                struct pollfd* pfds = (struct pollfd*)tb_vector_data(impl->pfds);
                if (pfds) pfds[i].events = 0;
                tb_spinlock_leave(&impl->lock.pfds);
            }
        }
    }

    // ok
    return wait;
}
예제 #2
0
파일: draw.c 프로젝트: cosim/gbox2
static __tb_inline__ tb_void_t g2_gl_draw_stencil_clip_path(g2_gl_draw_t* draw, g2_clipper_item_t const* item)
{
	// check
	tb_assert_and_check_return(item->type == G2_CLIPPER_ITEM_PATH);

	// the clip path
	g2_gl_path_t* path = (g2_gl_path_t*)item->u.path;
	tb_assert_and_check_return(path);

	// null?
	tb_check_return(!g2_path_null(path));

	// like
	g2_gl_path_make_like(path);

	// like rect?
	if (path->like == G2_GL_PATH_LIKE_RECT)
	{
		// clip bounds
		g2_gl_draw_stencil_clip_bounds(draw, &path->rect);

		// ok
		return ;
	}
	// like triangle?
	else if (path->like == G2_GL_PATH_LIKE_TRIG)
	{
		// clip triangle
		g2_clipper_item_t clip = {0};
		clip.type = G2_CLIPPER_ITEM_TRIANGLE;
		clip.mode = item->mode;
		clip.u.triangle = path->trig;
		g2_gl_draw_stencil_clip_triangle(draw, &clip);

		// ok
		return ;
	}

	// make draw
	if (!g2_gl_path_make_fill(path)) return ;

	// check
	tb_assert(path->fill.data && tb_vector_size(path->fill.data));
	tb_assert(path->fill.size && tb_vector_size(path->fill.size));
	tb_check_return(path->fill.rect.x1 < path->fill.rect.x2 && path->fill.rect.y1 < path->fill.rect.y2);
	
	// init vertices
	if (draw->context->version < 0x20)
		g2_glVertexPointer(2, G2_GL_FLOAT, 0, tb_vector_data(path->fill.data));
	else g2_glVertexAttribPointer(g2_gl_program_location(draw->program, G2_GL_PROGRAM_LOCATION_VERTICES), 2, G2_GL_FLOAT, G2_GL_FALSE, 0, tb_vector_data(path->fill.data));

	// clip path
	tb_size_t 	head = 0;
	tb_size_t 	size = 0;
	tb_size_t 	itor = tb_iterator_head(path->fill.size);
	tb_size_t 	tail = tb_iterator_tail(path->fill.size);
	for (; itor != tail; itor++)
	{
		size = tb_iterator_item(path->fill.size, itor);
		g2_glDrawArrays(G2_GL_TRIANGLE_FAN, (g2_GLint_t)head, (g2_GLint_t)size);
		head += size;
	}
}
예제 #3
0
tb_long_t tb_poller_wait(tb_poller_ref_t self, tb_poller_event_func_t func, tb_long_t timeout)
{
    // check
    tb_poller_poll_ref_t poller = (tb_poller_poll_ref_t)self;
    tb_assert_and_check_return_val(poller && poller->pfds && poller->cfds && func, -1);

    // loop
    tb_long_t wait = 0;
    tb_bool_t stop = tb_false;
    tb_hong_t time = tb_mclock();
    while (!wait && !stop && (timeout < 0 || tb_mclock() < time + timeout))
    {
        // pfds
        struct pollfd*  pfds = (struct pollfd*)tb_vector_data(poller->pfds);
        tb_size_t       pfdm = tb_vector_size(poller->pfds);
        tb_assert_and_check_return_val(pfds && pfdm, -1);

        // wait
        tb_long_t pfdn = poll(pfds, pfdm, timeout);
        tb_assert_and_check_return_val(pfdn >= 0, -1);

        // timeout?
        tb_check_return_val(pfdn, 0);

        // copy fds
        tb_vector_copy(poller->cfds, poller->pfds);

        // walk the copied fds
        pfds = (struct pollfd*)tb_vector_data(poller->cfds);
        pfdm = tb_vector_size(poller->cfds);

        // sync
        tb_size_t i = 0;
        for (i = 0; i < pfdm; i++)
        {
            // the sock
            tb_socket_ref_t sock = tb_fd2sock(pfds[i].fd);
            tb_assert_and_check_return_val(sock, -1);

            // the poll events
            tb_size_t poll_events = pfds[i].revents;
            tb_check_continue(poll_events);

            // spak?
            if (sock == poller->pair[1] && (poll_events & POLLIN))
            {
                // read spak
                tb_char_t spak = '\0';
                if (1 != tb_socket_recv(poller->pair[1], (tb_byte_t*)&spak, 1)) return -1;

                // killed?
                if (spak == 'k') return -1;

                // stop to wait
                stop = tb_true;

                // continue it
                continue ;
            }

            // skip spak
            tb_check_continue(sock != poller->pair[1]);

            // init events
            tb_size_t events = TB_POLLER_EVENT_NONE;
            if (poll_events & POLLIN) events |= TB_POLLER_EVENT_RECV;
            if (poll_events & POLLOUT) events |= TB_POLLER_EVENT_SEND;
            if ((poll_events & POLLHUP) && !(events & (TB_POLLER_EVENT_RECV | TB_POLLER_EVENT_SEND))) 
                events |= TB_POLLER_EVENT_RECV | TB_POLLER_EVENT_SEND;

            // call event function
            func(self, sock, events, tb_poller_hash_get(poller, sock));

            // update the events count
            wait++;
        }
    }

    // ok
    return wait;
}
예제 #4
0
파일: draw.c 프로젝트: cosim/gbox2
tb_void_t g2_gl_draw_path(g2_gl_painter_t* painter, tb_size_t mode, g2_gl_path_t const* path)
{
	// check
	tb_assert_and_check_return(painter && path);
	tb_assert_and_check_return((mode == G2_STYLE_MODE_FILL) || (mode == G2_STYLE_MODE_STOK));

	// null?
	tb_check_return(!g2_path_null(path));

	// make like
	g2_gl_path_make_like((g2_gl_path_t*)path);

	// make draw
	if (!g2_gl_path_make_fill((g2_gl_path_t*)path)) return ;
	
	// check
	tb_assert(path->fill.data && tb_vector_size(path->fill.data));
	tb_assert(path->fill.size && tb_vector_size(path->fill.size));
	tb_check_return(path->fill.rect.x1 < path->fill.rect.x2 && path->fill.rect.y1 < path->fill.rect.y2);
	
	// like rect?
	if (path->like == G2_GL_PATH_LIKE_RECT)
	{
		// draw bounds
		g2_gl_draw_bounds(painter, mode, &path->rect);

		// ok
		return ;
	}
	// like triangle?
	else if (path->like == G2_GL_PATH_LIKE_TRIG)
	{
		// draw triangle
		g2_gl_draw_triangle(painter, mode, &path->trig);

		// ok
		return ;
	}

	// init draw
	g2_gl_draw_t draw = {0};
	if (!g2_gl_draw_init(&draw, painter, mode, path->like == G2_GL_PATH_LIKE_CONX? G2_GL_DRAW_FLAG_CONVEX : G2_GL_DRAW_FLAG_NONE)) return ;

	// init bounds
	g2_gl_rect_t bounds = path->fill.rect;
	if (draw.mode == G2_STYLE_MODE_STOK) g2_gl_bounds_stok(&bounds, 1);

	// clip draw
	g2_gl_draw_clip(&draw, &bounds);

	// init vertices
	if (draw.context->version < 0x20)
		g2_glVertexPointer(2, G2_GL_FLOAT, 0, tb_vector_data(path->fill.data));
	else g2_glVertexAttribPointer(g2_gl_program_location(draw.program, G2_GL_PROGRAM_LOCATION_VERTICES), 2, G2_GL_FLOAT, G2_GL_FALSE, 0, tb_vector_data(path->fill.data));

	// draw vertices
	tb_size_t 	head = 0;
	tb_size_t 	size = 0;
	tb_size_t 	itor = tb_iterator_head(path->fill.size);
	tb_size_t 	tail = tb_iterator_tail(path->fill.size);
	g2_GLenum_t gmode = (draw.mode == G2_STYLE_MODE_FILL)? G2_GL_TRIANGLE_FAN : G2_GL_LINE_STRIP;
	for (; itor != tail; itor++)
	{
		size = tb_iterator_item(path->fill.size, itor);
		g2_glDrawArrays(gmode, (g2_GLint_t)head, (g2_GLint_t)size);
		head += size;
	}

	// draw fill
	g2_gl_draw_fill(&draw, &bounds);

	// exit draw
	g2_gl_draw_exit(&draw);
}