Пример #1
0
tb_bool_t tb_lo_scheduler_io_cancel(tb_lo_scheduler_io_ref_t scheduler_io, tb_socket_ref_t sock)
{
    // check
    tb_assert(scheduler_io && sock && scheduler_io->poller && scheduler_io->scheduler);

    // get the current coroutine
    tb_lo_coroutine_t* coroutine = tb_lo_scheduler_running(scheduler_io->scheduler);
    tb_check_return_val(coroutine, tb_false);

    // trace
    tb_trace_d("coroutine(%p): cancel socket(%p) ..", coroutine, sock);

    // remove the this socket from poller
    if (coroutine->rs.wait.sock == sock)
    {
        // remove the previous socket first if exists
        if (!tb_poller_remove(scheduler_io->poller, sock))
        {
            // trace
            tb_trace_e("failed to remove sock(%p) to poller on coroutine(%p)!", sock, coroutine);

            // failed
            coroutine->rs.wait.events_result = -1;
            return tb_false;
        }

        // clear waited socket
        coroutine->rs.wait.sock = tb_null;

        // remove ok
        coroutine->rs.wait.events_result = 0;
        return tb_true;
    }

    // no this socket
    return tb_false;
}
Пример #2
0
tb_double_t tb_oc_number_double(tb_object_ref_t object)
{
    // check
    tb_oc_number_t* number = tb_oc_number_cast(object);
    tb_assert_and_check_return_val(number, 0);

    // double
    switch (number->type)
    {
    case TB_OC_NUMBER_TYPE_DOUBLE:
        return number->v.d;
    case TB_OC_NUMBER_TYPE_FLOAT:
        return (tb_double_t)number->v.f;
    case TB_OC_NUMBER_TYPE_UINT8:
        return (tb_double_t)number->v.u8;
    case TB_OC_NUMBER_TYPE_SINT8:
        return (tb_double_t)number->v.s8;
    case TB_OC_NUMBER_TYPE_UINT16:
        return (tb_double_t)number->v.u16;
    case TB_OC_NUMBER_TYPE_SINT16:
        return (tb_double_t)number->v.s16;
    case TB_OC_NUMBER_TYPE_UINT32:
        return (tb_double_t)number->v.u32;
    case TB_OC_NUMBER_TYPE_SINT32:
        return (tb_double_t)number->v.s32;
    case TB_OC_NUMBER_TYPE_UINT64:
        return (tb_double_t)number->v.u64;
    case TB_OC_NUMBER_TYPE_SINT64:
        return (tb_double_t)number->v.s64;
    default:
        break;
    }

    tb_assert(0);
    return 0;
}
Пример #3
0
tb_void_t gb_mesh_edge_list_kill(gb_mesh_edge_list_ref_t list, gb_mesh_edge_ref_t edge)
{
    // check
    gb_mesh_edge_list_impl_t* impl = (gb_mesh_edge_list_impl_t*)list;
    tb_assert_and_check_return(impl && impl->pool && edge);

    // make sure the edge points to the first half-edge
    if (edge->sym < edge) edge = edge->sym;

#ifdef __gb_debug__
    // check
    tb_assert(edge->id && edge->sym->id);

    // clear id
    edge->id        = 0;
    edge->sym->id   = 0;
#endif

    // remove it from the list
    gb_mesh_edge_remove_done(edge);

    // exit it
    tb_fixed_pool_free(impl->pool, edge);
}
Пример #4
0
static tb_size_t tb_vector_remove_last_test()
{
    // init
    tb_vector_ref_t vector = tb_vector_init(TB_VECTOR_GROW_SIZE, tb_element_long());
    tb_assert_and_check_return_val(vector, 0);

    __tb_volatile__ tb_size_t i = 0;
    __tb_volatile__ tb_size_t n = 10000;
    tb_vector_ninsert_head(vector, (tb_pointer_t)0xf, n);
    tb_hong_t t = tb_mclock();
    for (i = 0; i < n; i++) tb_vector_remove_last(vector);
    t = tb_mclock() - t;

    // time
    tb_trace_i("tb_vector_remove_last(%lu): %lld ms, size: %lu, maxn: %lu", n, t, tb_vector_size(vector), tb_vector_maxn(vector));

    // check
    tb_assert(!tb_vector_size(vector));

    // exit
    tb_vector_exit(vector);

    return n / ((tb_uint32_t)(t) + 1);
}
Пример #5
0
Файл: exp1.c Проект: waruqi/tbox
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
tb_double_t tb_exp1(tb_double_t x)
{
    tb_assert(x >= -1 && x <= 1);
    return (1 + (x) + ((x) * (x)) / 2 + ((x) * (x) * (x)) / 6);
}
Пример #6
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
tb_float_t tb_expif(tb_long_t x)
{
    tb_assert(x >= -31 && x <= 31);

    // x = [-31, 31]
    static tb_float_t table[47] = 
    {
        // [-15, -1]
        0.000000f
    ,   0.000001f
    ,   0.000002f
    ,   0.000006f
    ,   0.000017f
    ,   0.000045f
    ,   0.000123f
    ,   0.000335f
    ,   0.000912f
    ,   0.002479f
    ,   0.006738f
    ,   0.018316f
    ,   0.049787f
    ,   0.135335f
    ,   0.367879f

        // 0
    ,   1.000000f

        // [1, 31]
    ,   2.718282f
    ,   7.389056f
    ,   20.085537f
    ,   54.598150f
    ,   148.413159f
    ,   403.428793f
    ,   1096.633158f
    ,   2980.957987f
    ,   8103.083928f
    ,   22026.465795f
    ,   59874.141715f
    ,   162754.791419f
    ,   442413.392009f
    ,   1202604.284165f
    ,   3269017.372472f
    ,   8886110.520508f
    ,   24154952.753575f
    ,   65659969.137331f
    ,   178482300.963187f
    ,   485165195.409790f
    ,   1318815734.483215f
    ,   3584912846.131592f
    ,   9744803446.248903f
    ,   26489122129.843472f
    ,   72004899337.385880f
    ,   195729609428.838776f
    ,   532048240601.798645f
    ,   1446257064291.475098f
    ,   3931334297144.041992f
    ,   10686474581524.462891f
    ,   29048849665247.425781f

    };
    return table[((x) + 15) & 0x3f];
}
Пример #7
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * private implementation
 */
static tb_bool_t xm_os_find_walk(tb_char_t const* path, tb_file_info_t const* info, tb_cpointer_t priv)
{
    // check
    tb_value_ref_t tuple = (tb_value_ref_t)priv;
    tb_assert_and_check_return_val(path && info && tuple, tb_false);

    // the lua
    lua_State* lua = (lua_State*)tuple[0].ptr;
    tb_assert_and_check_return_val(lua, tb_false);

    // the pattern
    tb_char_t const* pattern = (tb_char_t const*)tuple[1].cstr;
    tb_assert_and_check_return_val(pattern, tb_false);

    // find directory?
    tb_bool_t findir = tuple[2].b;

    // the count
    tb_size_t* pcount = &(tuple[3].ul);

    // trace
    tb_trace_d("path[%c]: %s", info->type == TB_FILE_TYPE_DIRECTORY? 'd' : 'f', path);

    // find file or directory?
    if ((findir && info->type == TB_FILE_TYPE_DIRECTORY) || (!findir && info->type == TB_FILE_TYPE_FILE))
    {
        // done path:match(pattern)
        lua_getfield(lua, -1, "match");
        lua_pushstring(lua, path);
        lua_pushstring(lua, pattern);
        if (lua_pcall(lua, 2, 1, 0)) 
        {
            // trace
            tb_printf("error: call string.match(%s, %s) failed: %s!\n", path, pattern, lua_tostring(lua, -1));

            // failed
            return tb_false;
        }

        // match ok? 
        if (lua_isstring(lua, -1) && !tb_strcmp(path, lua_tostring(lua, -1)))
        {
            // exists excludes?
            tb_bool_t excluded = tb_false;
            if (lua_istable(lua, 5))
            {
                // the root directory
                size_t              rootlen = 0;
                tb_char_t const*    rootdir = luaL_checklstring(lua, 1, &rootlen);
                tb_assert_and_check_return_val(rootdir && rootlen, tb_false);

                // check
                tb_assert(!tb_strcmp(path, rootdir));
                tb_assert(rootlen + 1 <= tb_strlen(path));

                // skip the rootdir 
                path += rootlen + 1;

                // exclude pathes
                tb_size_t i = 0;
                tb_size_t count = luaL_getn(lua, 5);
                for (i = 0; i < count && !excluded; i++)
                {
                    // get exclude
                    lua_rawgeti(lua, 5, i + 1);
                    tb_char_t const* exclude = lua_tostring(lua, -1);
                    if (exclude) 
                    {
                        // done path:match(exclude)
                        lua_getfield(lua, -3, "match");
                        lua_pushstring(lua, path);
                        lua_pushstring(lua, exclude);
                        if (lua_pcall(lua, 2, 1, 0)) 
                        {
                            // trace
                            tb_printf("error: call string.match(%s, %s) failed: %s!\n", path, exclude, lua_tostring(lua, -1));
                        }

                        // matched?
                        excluded = lua_isstring(lua, -1) && !tb_strcmp(path, lua_tostring(lua, -1));

                        // pop the match result
                        lua_pop(lua, 1);
                    }

                    // pop exclude
                    lua_pop(lua, 1);
                }
            }

            // save this path
            if (!excluded) lua_rawseti(lua, -3, ++*pcount);
            // pop this return value
            else lua_pop(lua, 1);
        }
        // pop this return value
        else lua_pop(lua, 1);
    }

    // continue 
    return tb_true;
}
Пример #8
0
	easy_spin_locker(easy_atomic_t *_lock) :
			lock(_lock) {
		tb_assert(lock!=NULL)
		easy_spin_lock(lock);
	}
Пример #9
0
tb_bool_t tb_lo_scheduler_start(tb_lo_scheduler_t* scheduler, tb_lo_coroutine_func_t func, tb_cpointer_t priv, tb_lo_coroutine_free_t free)
{
    // check
    tb_assert(func);

    // done
    tb_bool_t           ok = tb_false;
    tb_lo_coroutine_t*  coroutine = tb_null;
    do
    {
        // trace
        tb_trace_d("start ..");

        // get the current scheduler
        if (!scheduler) scheduler = (tb_lo_scheduler_t*)tb_lo_scheduler_self_();
        tb_assert_and_check_break(scheduler);

        // have been stopped? do not continue to start new coroutines
        tb_check_break(!scheduler->stopped);

        // reuses dead coroutines in init function
        if (tb_list_entry_size(&scheduler->coroutines_dead))
        {
            // get the next entry from head
            tb_list_entry_ref_t entry = tb_list_entry_head(&scheduler->coroutines_dead);
            tb_assert_and_check_break(entry);

            // remove it from the ready coroutines
            tb_list_entry_remove_head(&scheduler->coroutines_dead);

            // get the dead coroutine
            coroutine = (tb_lo_coroutine_t*)tb_list_entry(&scheduler->coroutines_dead, entry);

            // reinit this coroutine
            tb_lo_coroutine_reinit(coroutine, func, priv, free);
        }

        // init coroutine
        if (!coroutine) coroutine = tb_lo_coroutine_init((tb_lo_scheduler_ref_t)scheduler, func, priv, free);
        tb_assert_and_check_break(coroutine);

        // ready coroutine
        tb_lo_scheduler_make_ready(scheduler, coroutine);

        // the dead coroutines is too much? free some coroutines
        while (tb_list_entry_size(&scheduler->coroutines_dead) > TB_SCHEDULER_DEAD_CACHE_MAXN)
        {
            // get the next entry from head
            tb_list_entry_ref_t entry = tb_list_entry_head(&scheduler->coroutines_dead);
            tb_assert(entry);

            // remove it from the ready coroutines
            tb_list_entry_remove_head(&scheduler->coroutines_dead);

            // exit this coroutine
            tb_lo_coroutine_exit((tb_lo_coroutine_t*)tb_list_entry(&scheduler->coroutines_dead, entry));
        }

        // ok
        ok = tb_true;

    } while (0);

    // trace
    tb_trace_d("start %s", ok? "ok" : "no");

    // ok?
    return ok;
}
Пример #10
0
static tb_long_t tb_aiop_rtor_epoll_wait(tb_aiop_rtor_impl_t* rtor, tb_aioe_ref_t list, tb_size_t maxn, tb_long_t timeout)
{   
    // check
    tb_aiop_rtor_epoll_impl_t* impl = (tb_aiop_rtor_epoll_impl_t*)rtor;
    tb_assert_and_check_return_val(impl && impl->epfd > 0, -1);

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

    // init grow
    tb_size_t grow = tb_align8((rtor->aiop->maxn >> 3) + 1);

    // init events
    if (!impl->evts)
    {
        impl->evtn = grow;
        impl->evts = tb_nalloc0(impl->evtn, sizeof(struct epoll_event));
        tb_assert_and_check_return_val(impl->evts, -1);
    }
    
    // wait events
    tb_long_t evtn = epoll_wait(impl->epfd, impl->evts, impl->evtn, timeout);

    // interrupted?(for gdb?) continue it
    if (evtn < 0 && errno == EINTR) return 0;

    // check error?
    tb_assert_and_check_return_val(evtn >= 0 && evtn <= impl->evtn, -1);
    
    // timeout?
    tb_check_return_val(evtn, 0);

    // grow it if events is full
    if (evtn == impl->evtn)
    {
        // grow size
        impl->evtn += grow;
        if (impl->evtn > rtor->aiop->maxn) impl->evtn = rtor->aiop->maxn;

        // grow data
        impl->evts = tb_ralloc(impl->evts, impl->evtn * sizeof(struct epoll_event));
        tb_assert_and_check_return_val(impl->evts, -1);
    }
    tb_assert(evtn <= impl->evtn);

    // limit 
    evtn = tb_min(evtn, maxn);

    // sync
    tb_size_t i = 0;
    tb_size_t wait = 0; 
    for (i = 0; i < evtn; i++)
    {
        // the aioo
        tb_aioo_impl_t* aioo = (tb_aioo_impl_t*)tb_u2p(impl->evts[i].data.u64);
        tb_assert_and_check_return_val(aioo, -1);

        // the sock 
        tb_socket_ref_t sock = aioo->sock;
        tb_assert_and_check_return_val(sock, -1);

        // the events
        tb_size_t events = impl->evts[i].events;

        // spak?
        if (sock == aiop->spak[1] && (events & EPOLLIN)) 
        {
            // 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;

            // continue it
            continue ;
        }

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

        // save aioe
        tb_aioe_ref_t aioe = &list[wait++];
        aioe->code = TB_AIOE_CODE_NONE;
        aioe->priv = aioo->priv;
        aioe->aioo = (tb_aioo_ref_t)aioo;
        if (events & EPOLLIN) 
        {
            aioe->code |= TB_AIOE_CODE_RECV;
            if (aioo->code & TB_AIOE_CODE_ACPT) aioe->code |= TB_AIOE_CODE_ACPT;
        }
        if (events & EPOLLOUT) 
        {
            aioe->code |= TB_AIOE_CODE_SEND;
            if (aioo->code & TB_AIOE_CODE_CONN) aioe->code |= TB_AIOE_CODE_CONN;
        }
        if (events & (EPOLLHUP | EPOLLERR) && !(aioe->code & (TB_AIOE_CODE_RECV | TB_AIOE_CODE_SEND))) 
            aioe->code |= TB_AIOE_CODE_RECV | TB_AIOE_CODE_SEND;

        // oneshot? clear it
        if (aioo->code & TB_AIOE_CODE_ONESHOT)
        {
            // clear code
            aioo->code = TB_AIOE_CODE_NONE;
            aioo->priv = tb_null;

            // clear events manually if no epoll oneshot
#ifndef EPOLLONESHOT
            struct epoll_event e = {0};
            if (epoll_ctl(impl->epfd, EPOLL_CTL_DEL, tb_sock2fd(aioo->sock), &e) < 0) 
            {
                // trace
                tb_trace_e("clear aioo[%p] failed manually for oneshot, error: %d", aioo, errno);
            }
#endif
        }
    }

    // ok
    return wait;
}
Пример #11
0
tb_iterator_ref_t tb_ifaddrs_itor(tb_ifaddrs_ref_t ifaddrs, tb_bool_t reload)
{
    // check
    tb_list_ref_t interfaces = (tb_list_ref_t)ifaddrs;
    tb_assert_and_check_return_val(interfaces, tb_null);

    // uses the cached interfaces?
    tb_check_return_val(reload, (tb_iterator_ref_t)interfaces); 

    // clear interfaces first
    tb_list_clear(interfaces);

    // query the list of interfaces.
    struct ifaddrs* list = tb_null;
    if (!getifaddrs(&list) && list)
    {
#if 0
        // init sock
        tb_long_t sock = socket(AF_INET, SOCK_DGRAM, 0);
#endif

        // done
        struct ifaddrs* item = tb_null;
        for (item = list; item; item = item->ifa_next)
        {
            // check
            tb_check_continue(item->ifa_addr && item->ifa_name);

            /* attempt to get the interface from the cached interfaces
             * and make a new interface if no the cached interface
             */
            tb_ifaddrs_interface_t      interface_new = {0};
            tb_ifaddrs_interface_ref_t  interface = tb_ifaddrs_interface_find((tb_iterator_ref_t)interfaces, item->ifa_name);
            if (!interface) interface = &interface_new;

            // check
            tb_assert(interface == &interface_new || interface->name);

            // done
            switch (item->ifa_addr->sa_family)
            {
            case AF_INET:
                {
                    // the address
                    struct sockaddr_storage const* addr = (struct sockaddr_storage const*)item->ifa_addr;

                    // save ipaddr4
                    tb_ipaddr_t ipaddr4;
                    if (!tb_sockaddr_save(&ipaddr4, addr)) break;
                    interface->ipaddr4 = ipaddr4.u.ipv4;

                    // save flags
                    interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR4;
                    if ((item->ifa_flags & IFF_LOOPBACK) || tb_ipaddr_ip_is_loopback(&ipaddr4)) 
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_IS_LOOPBACK;

#if 0
                    // no hwaddr? get it
                    if (!(interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR))
                    {
                        // attempt get the hwaddr
                        struct ifreq ifr;
                        tb_memset(&ifr, 0, sizeof(ifr));
                        tb_strcpy(ifr.ifr_name, item->ifa_name);
                        if (!ioctl(sock, SIOCGIFHWADDR, &ifr))
                        {
                            // have hwaddr
                            interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR;

                            // save hwaddr
                            tb_memcpy(interface->hwaddr.u8, ifr.ifr_hwaddr.sa_data, sizeof(interface->hwaddr.u8));
                        }
                    }
#endif

                    // new interface? save it
                    if (interface == &interface_new)
                    {
                        // save interface name
                        interface->name = tb_strdup(item->ifa_name);
                        tb_assert(interface->name);

                        // save interface
                        tb_list_insert_tail(interfaces, interface);
                    }
                }
                break;
            case AF_INET6:
                {
                    // the address
                    struct sockaddr_storage const* addr = (struct sockaddr_storage const*)item->ifa_addr;

                    // save ipaddr6
                    tb_ipaddr_t ipaddr6;
                    if (!tb_sockaddr_save(&ipaddr6, addr)) break;
                    interface->ipaddr6 = ipaddr6.u.ipv6;

                    // save flags
                    interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR6;
                    if ((item->ifa_flags & IFF_LOOPBACK) || tb_ipaddr_ip_is_loopback(&ipaddr6))
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_IS_LOOPBACK;

#if 0
                    // no hwaddr? get it
                    if (!(interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR))
                    {
                        // attempt get the hwaddr
                        struct ifreq ifr;
                        tb_memset(&ifr, 0, sizeof(ifr));
                        tb_strcpy(ifr.ifr_name, item->ifa_name);
                        if (!ioctl(sock, SIOCGIFHWADDR, &ifr))
                        {
                            // have hwaddr
                            interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR;

                            // save hwaddr
                            tb_memcpy(interface->hwaddr.u8, ifr.ifr_hwaddr.sa_data, sizeof(interface->hwaddr.u8));
                        }
                    }
#endif

                    // new interface? save it
                    if (interface == &interface_new)
                    {
                        // save interface name
                        interface->name = tb_strdup(item->ifa_name);
                        tb_assert(interface->name);

                        // save interface
                        tb_list_insert_tail(interfaces, interface);
                    }
                }
                break;
            case AF_PACKET:
                {
                    // the address
                    struct sockaddr_ll const* addr = (struct sockaddr_ll const*)item->ifa_addr;

                    // check
                    tb_check_break(addr->sll_halen == sizeof(interface->hwaddr.u8));

                    // no hwaddr? get it
                    if (!(interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR))
                    {
                        // have hwaddr
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR;

                        // save hwaddr
                        tb_memcpy(interface->hwaddr.u8, addr->sll_addr, sizeof(interface->hwaddr.u8));

                        // new interface? save it
                        if (interface == &interface_new)
                        {
                            // save interface name
                            interface->name = tb_strdup(item->ifa_name);
                            tb_assert(interface->name);

                            // save interface
                            tb_list_insert_tail(interfaces, interface);
                        }
                    }
                }
                break;
            default:
                {
                    // trace
                    tb_trace_d("unknown family: %d", item->ifa_addr->sa_family);
                }
                break;
            }
        }

#if 0
        // exit socket
        if (sock) close(sock);
        sock = 0;
#endif

        // exit the interface list
        freeifaddrs(list);
    }

    // ok?
    return (tb_iterator_ref_t)interfaces;
}
Пример #12
0
tb_bool_t tb_timer_spak(tb_timer_ref_t timer)
{
    // check
    tb_timer_impl_t* impl = (tb_timer_impl_t*)timer;
    tb_assert_and_check_return_val(impl && impl->pool && impl->heap, tb_false);

    // stoped?
    tb_check_return_val(!tb_atomic_get(&impl->stop), tb_false);

    // enter
    tb_spinlock_enter(&impl->lock);

    // done
    tb_bool_t               ok = tb_false;
    tb_timer_task_func_t    func = tb_null;
    tb_cpointer_t           priv = tb_null;
    tb_bool_t               killed = tb_false;
    do
    {
        // empty? 
        if (!tb_heap_size(impl->heap))
        {
            ok = tb_true;
            break;
        }

        // the top task
        tb_timer_task_impl_t* task_impl = (tb_timer_task_impl_t*)tb_heap_top(impl->heap);
        tb_assert_and_check_break(task_impl);

        // check refn
        tb_assert(task_impl->refn);

        // the now
        tb_hong_t now = tb_timer_now(impl);

        // timeout?
        if (task_impl->when <= now)
        {
            // pop it
            tb_heap_pop(impl->heap);

            // save func and data for calling it later
            func = task_impl->func;
            priv = task_impl->priv;

            // killed?
            killed = task_impl->killed? tb_true : tb_false;

            // repeat?
            if (task_impl->repeat)
            {
                // update when
                task_impl->when = now + task_impl->period;

                // continue task_impl
                tb_heap_put(impl->heap, task_impl);
            }
            else 
            {
                // refn--
                if (task_impl->refn > 1) task_impl->refn--;
                // remove it from pool directly
                else tb_fixed_pool_free(impl->pool, task_impl);
            }
        }

        // ok
        ok = tb_true;

    } while (0);

    // leave
    tb_spinlock_leave(&impl->lock);

    // done func
    if (func) func(killed, priv);

    // ok?
    return ok;
}
Пример #13
0
static tb_void_t gb_window_sdl_loop(gb_window_ref_t window)
{
    // check
    gb_window_sdl_impl_t* impl = (gb_window_sdl_impl_t*)window;
    tb_assert_and_check_return(impl);

    // init canvas
    if (!impl->canvas) impl->canvas = gb_canvas_init_from_window(window);
    tb_assert(impl->canvas);

    // done init
    if (impl->base.info.init && !impl->base.info.init((gb_window_ref_t)impl, impl->canvas, impl->base.info.priv)) return ;

    // loop
    SDL_Event evet;
    tb_hong_t time;
    tb_bool_t stop = tb_false;
    tb_size_t delay = 1000 / (impl->base.info.framerate? impl->base.info.framerate : GB_WINDOW_DEFAULT_FRAMERATE);
    while (!stop)
    {
        // spak
        time = gb_window_impl_spak((gb_window_ref_t)impl);

        // lock the surface
        SDL_LockSurface(impl->surface);

        // draw
        gb_window_impl_draw((gb_window_ref_t)impl, impl->canvas);

        // unlock the surface
        SDL_UnlockSurface(impl->surface);

        // flip 
        if (SDL_Flip(impl->surface) < 0) stop = tb_true;

        // poll
        while (SDL_PollEvent(&evet))
        {
            // done
            switch (evet.type)
            {
            case SDL_MOUSEMOTION:
                {
                    // init event
                    gb_event_t              event = {0};
                    event.type              = GB_EVENT_TYPE_MOUSE;
                    event.u.mouse.code      = GB_MOUSE_MOVE;
                    event.u.mouse.button    = impl->button;
                    gb_point_imake(&event.u.mouse.cursor, evet.motion.x, evet.motion.y);

                    // done event
                    gb_window_impl_event((gb_window_ref_t)impl, &event);
                }
                break;
            case SDL_MOUSEBUTTONUP:
            case SDL_MOUSEBUTTONDOWN:
                {
                    // init event
                    gb_event_t              event = {0};
                    event.type              = GB_EVENT_TYPE_MOUSE;
                    event.u.mouse.code      = evet.type == SDL_MOUSEBUTTONDOWN? GB_MOUSE_DOWN : GB_MOUSE_UP;
                    gb_point_imake(&event.u.mouse.cursor, evet.button.x, evet.button.y);

                    // init button
                    switch (evet.button.button)
                    {
                    case SDL_BUTTON_LEFT:   event.u.mouse.button = GB_MOUSE_BUTTON_LEFT;    break;
                    case SDL_BUTTON_RIGHT:  event.u.mouse.button = GB_MOUSE_BUTTON_RIGHT;   break;
                    case SDL_BUTTON_MIDDLE: event.u.mouse.button = GB_MOUSE_BUTTON_MIDDLE;  break;
                    default:                event.u.mouse.button = GB_MOUSE_BUTTON_NONE;    break;
                    }

                    // save button
                    impl->button = evet.type == SDL_MOUSEBUTTONDOWN? event.u.mouse.button : GB_MOUSE_BUTTON_NONE;

                    // done event
                    gb_window_impl_event((gb_window_ref_t)impl, &event);
                }
                break;
            case SDL_KEYDOWN:
            case SDL_KEYUP:
                {
                    // init event
                    gb_event_t                  event = {0};
                    event.type                  = GB_EVENT_TYPE_KEYBOARD;
                    event.u.keyboard.pressed    = evet.type == SDL_KEYDOWN? tb_true : tb_false;

                    // init code
                    switch ((tb_size_t)evet.key.keysym.sym)
                    {
                    case SDLK_F1:           event.u.keyboard.code = GB_KEY_F1;          break;
                    case SDLK_F2:           event.u.keyboard.code = GB_KEY_F2;          break;
                    case SDLK_F3:           event.u.keyboard.code = GB_KEY_F3;          break;
                    case SDLK_F4:           event.u.keyboard.code = GB_KEY_F4;          break;
                    case SDLK_F5:           event.u.keyboard.code = GB_KEY_F5;          break;
                    case SDLK_F6:           event.u.keyboard.code = GB_KEY_F6;          break;
                    case SDLK_F7:           event.u.keyboard.code = GB_KEY_F7;          break;
                    case SDLK_F8:           event.u.keyboard.code = GB_KEY_F8;          break;
                    case SDLK_F9:           event.u.keyboard.code = GB_KEY_F9;          break;
                    case SDLK_F10:          event.u.keyboard.code = GB_KEY_F10;         break;
                    case SDLK_F11:          event.u.keyboard.code = GB_KEY_F11;         break;
                    case SDLK_F12:          event.u.keyboard.code = GB_KEY_F12;         break;

                    case SDLK_LEFT:         event.u.keyboard.code = GB_KEY_LEFT;        break;
                    case SDLK_UP:           event.u.keyboard.code = GB_KEY_UP;          break;
                    case SDLK_RIGHT:        event.u.keyboard.code = GB_KEY_RIGHT;       break;
                    case SDLK_DOWN:         event.u.keyboard.code = GB_KEY_DOWN;        break;

                    case SDLK_HOME:         event.u.keyboard.code = GB_KEY_HOME;        break;
                    case SDLK_END:          event.u.keyboard.code = GB_KEY_END;         break;
                    case SDLK_INSERT:       event.u.keyboard.code = GB_KEY_INSERT;      break;
                    case SDLK_PAGEUP:       event.u.keyboard.code = GB_KEY_PAGEUP;      break;
                    case SDLK_PAGEDOWN:     event.u.keyboard.code = GB_KEY_PAGEDOWN;    break;

                    case SDLK_HELP:         event.u.keyboard.code = GB_KEY_HELP;        break;
                    case SDLK_PRINT:        event.u.keyboard.code = GB_KEY_PRINT;       break;
                    case SDLK_SYSREQ:       event.u.keyboard.code = GB_KEY_SYSREQ;      break;
                    case SDLK_BREAK:        event.u.keyboard.code = GB_KEY_BREAK;       break;
                    case SDLK_MENU:         event.u.keyboard.code = GB_KEY_MENU;        break;
                    case SDLK_POWER:        event.u.keyboard.code = GB_KEY_POWER;       break;
                    case SDLK_EURO:         event.u.keyboard.code = GB_KEY_EURO;        break;
                    case SDLK_UNDO:         event.u.keyboard.code = GB_KEY_UNDO;        break;

                    case SDLK_NUMLOCK:      event.u.keyboard.code = GB_KEY_NUMLOCK;     break;
                    case SDLK_CAPSLOCK:     event.u.keyboard.code = GB_KEY_CAPSLOCK;    break;
                    case SDLK_SCROLLOCK:    event.u.keyboard.code = GB_KEY_SCROLLLOCK;  break;
                    case SDLK_RSHIFT:       event.u.keyboard.code = GB_KEY_RSHIFT;      break;
                    case SDLK_LSHIFT:       event.u.keyboard.code = GB_KEY_LSHIFT;      break;
                    case SDLK_RCTRL:        event.u.keyboard.code = GB_KEY_RCTRL;       break;
                    case SDLK_LCTRL:        event.u.keyboard.code = GB_KEY_LCTRL;       break;
                    case SDLK_RALT:         event.u.keyboard.code = GB_KEY_RALT;        break;
                    case SDLK_LALT:         event.u.keyboard.code = GB_KEY_LALT;        break;
                    case 0x136:             event.u.keyboard.code = GB_KEY_RCMD;        break;
                    case 0x135:             event.u.keyboard.code = GB_KEY_LCMD;        break;

                    case SDLK_PAUSE:        event.u.keyboard.code = GB_KEY_PAUSE;       break;

                    default :
                        if (evet.key.keysym.sym < 256)
                        {
                            // the char code
                            event.u.keyboard.code = evet.key.keysym.sym;
                        }
                        break;
                    }

                    // done event
                    if (event.u.keyboard.code) gb_window_impl_event((gb_window_ref_t)impl, &event);
                }
                break;
            case SDL_VIDEORESIZE:
                {
                    // trace
                    tb_trace_d("resize: type: %d, %dx%d", evet.resize.type, evet.resize.w, evet.resize.h);

                    // TODO
                    // ...
                }
                break;
            case SDL_ACTIVEEVENT:
                {
                    // trace
                    tb_trace_d("active: type: %d, gain: %d, state: %d", evet.active.type, evet.active.gain, evet.active.state);

                    // active?
                    if (evet.active.state == SDL_APPACTIVE)
                    {
                        // init event
                        gb_event_t              event = {0};
                        event.type              = GB_EVENT_TYPE_ACTIVE;
                        event.u.active.code     = evet.active.gain? GB_ACTIVE_FOREGROUND : GB_ACTIVE_BACKGROUND;

                        // done event
                        gb_window_impl_event((gb_window_ref_t)impl, &event);
                    }
                }
                break;
            case SDL_QUIT:
                {
                    // stop it
                    stop = tb_true;
                }
                break;
            default:
                // trace
                tb_trace_e("unknown event: %x", evet.type);
                break;
            }
        }

        // compute the delta time
        time = tb_cache_time_spak() - time;

        // wait 
        if (delay > (tb_size_t)time) SDL_Delay(delay - (tb_size_t)time);
    }
 
    // done exit
    if (impl->base.info.exit) impl->base.info.exit((gb_window_ref_t)impl, impl->canvas, impl->base.info.priv);
}
Пример #14
0
static tb_void_t gb_window_sdl_fullscreen(gb_window_ref_t window, tb_bool_t fullscreen)
{
    // check
    gb_window_sdl_impl_t* impl = (gb_window_sdl_impl_t*)window;
    tb_assert_and_check_return(impl);

    // the pixmap
    gb_pixmap_ref_t pixmap = gb_pixmap(impl->base.pixfmt, 0xff);
    tb_assert_and_check_return(pixmap);

    // fullscreen?
    tb_size_t changed = tb_false;
    if (fullscreen && !(impl->base.flag & GB_WINDOW_FLAG_FULLSCREEN)) 
    {
        // exit surface
        if (impl->surface) SDL_FreeSurface(impl->surface);

        // init mode
        tb_size_t mode = SDL_DOUBLEBUF | SDL_FULLSCREEN;

        // TODO
        // the screen width and height
        tb_uint16_t screen_width  = 0;//tb_screen_width();
        tb_uint16_t screen_height = 0;//tb_screen_height();
        tb_assert(screen_width && screen_height && screen_width <= GB_WIDTH_MAXN && screen_height <= GB_HEIGHT_MAXN);

        // init surface
        impl->surface = SDL_SetVideoMode(screen_width, screen_height, pixmap->bpp, mode | SDL_HWSURFACE);
        if (!impl->surface) impl->surface = SDL_SetVideoMode(screen_width, screen_height, pixmap->bpp, mode | SDL_SWSURFACE);
        tb_assert(impl->surface && impl->surface->pixels);

        // update flag
        impl->base.flag |= GB_WINDOW_FLAG_FULLSCREEN;

        // save the normal width and height
        impl->normal_width      = (tb_uint16_t)gb_window_width(window);
        impl->normal_height     = (tb_uint16_t)gb_window_height(window);

        // update the window width and height
        impl->base.width        = screen_width;
        impl->base.height       = screen_height;

        // changed
        changed = tb_true;
    }
    else if (impl->base.flag & GB_WINDOW_FLAG_FULLSCREEN)
    {
        // exit surface
        if (impl->surface) SDL_FreeSurface(impl->surface);

        // init mode
        tb_size_t mode = SDL_DOUBLEBUF;
        if (impl->base.flag & GB_WINDOW_FLAG_HIHE_TITLEBAR) mode |= SDL_NOFRAME;
        if (impl->base.flag & GB_WINDOW_FLAG_NOT_REISZE) mode &= ~SDL_RESIZABLE;
        else mode |= SDL_RESIZABLE;

        // init surface
        impl->surface = SDL_SetVideoMode(impl->normal_width, impl->normal_height, pixmap->bpp, mode | SDL_HWSURFACE);
        if (!impl->surface) impl->surface = SDL_SetVideoMode(impl->normal_width, impl->normal_height, pixmap->bpp, mode | SDL_SWSURFACE);
        tb_assert(impl->surface && impl->surface->pixels);

        // update flag
        impl->base.flag &= ~GB_WINDOW_FLAG_FULLSCREEN;

        // update the window width and height
        impl->base.width        = impl->normal_width;
        impl->base.height       = impl->normal_height;

        // changed
        changed = tb_true;
    }

    // ok?
    if (changed)
    {
        // exit canvas first
        if (impl->canvas) gb_canvas_exit(impl->canvas);

        // exit bitmap first
        if (impl->base.bitmap) tb_free(impl->base.bitmap);

        // init bitmap
        impl->base.bitmap = gb_bitmap_init(impl->surface->pixels, impl->base.pixfmt, impl->base.width, impl->base.height, impl->surface->pitch, tb_false);
        tb_assert(impl->base.bitmap);

        // init canvas
        impl->canvas = gb_canvas_init_from_window(window);
        tb_assert(impl->canvas);

        // done resize
        if (impl->base.info.resize) impl->base.info.resize((gb_window_ref_t)impl, impl->canvas, impl->base.info.priv);
    }
}
Пример #15
0
static tb_void_t tb_element_null_nrepl(tb_element_ref_t element, tb_pointer_t buff, tb_cpointer_t data, tb_size_t size)
{
    tb_assert(data == tb_null);
}
Пример #16
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * private implementation
 */
static tb_pool_data_empty_head_t* tb_static_fixed_pool_malloc_pred(tb_static_fixed_pool_t* pool)
{
    // check
    tb_assert_and_check_return_val(pool, tb_null);

    // done
    tb_pool_data_empty_head_t* data_head = tb_null;
    do
    {
        // exists the predict index?
        tb_check_break(pool->pred_index);

        // the predict index
        tb_size_t pred_index = pool->pred_index - 1;
        tb_assert((pred_index << TB_CPU_SHIFT) < pool->item_maxn);
    
        // the predict data
        tb_size_t* data = (tb_size_t*)pool->used_info + pred_index;

        // full?
        tb_check_break((*data) + 1);

        // the free bit index
        tb_size_t index = (pred_index << TB_CPU_SHIFT) + tb_static_fixed_pool_find_free(*data);
        
        // out of range?
        if (index >= pool->item_maxn)
        {
            // clear the pred index
            pool->pred_index = 0;
            break;
        }

        // check
        tb_assert(!tb_static_fixed_pool_used_bset(pool->used_info, index));

        // the data head
        data_head = (tb_pool_data_empty_head_t*)(pool->data + index * pool->item_space);

        // allocate it
        tb_static_fixed_pool_used_set1(pool->used_info, index);

        // the predict data is full
        if (!((*data) + 1)) 
        {
            // clear the predict index
            pool->pred_index = 0;

            // predict the next index
            if (index + 1 < pool->item_maxn && !tb_static_fixed_pool_used_bset(pool->used_info, index + 1))
                tb_static_fixed_pool_cache_pred(pool, index + 1);
        }

    } while (0);

#ifdef __tb_debug__
    // update the predict failed count
    if (!data_head) pool->pred_failed++;
#endif

    // ok?
    return data_head;
}
Пример #17
0
static tb_pointer_t tb_database_sqlite3_result_col_iterator_item(tb_iterator_ref_t iterator, tb_size_t itor)
{
    // check
    tb_database_sqlite3_result_row_t* row = (tb_database_sqlite3_result_row_t*)iterator;
    tb_assert_and_check_return_val(row && itor < row->count, tb_null);

    // the sqlite
    tb_database_sqlite3_t* sqlite = (tb_database_sqlite3_t*)iterator->priv;
    tb_assert_and_check_return_val(sqlite, tb_null);

    // result?
    if (sqlite->result.result)
    {
        // init value
        tb_database_sql_value_name_set(&row->value, (tb_char_t const*)sqlite->result.result[itor]);
        tb_database_sql_value_set_text(&row->value, (tb_char_t const*)sqlite->result.result[((1 + sqlite->result.row.row) * row->count) + itor], 0);
        return (tb_pointer_t)&row->value;
    }
    // statement result?
    else if (sqlite->result.statement)
    {
        // init name
        tb_database_sql_value_name_set(&row->value, sqlite3_column_name(sqlite->result.statement, (tb_int_t)itor));

        // init type
        tb_size_t type = sqlite3_column_type(sqlite->result.statement, (tb_int_t)itor);
        switch (type)
        {
        case SQLITE_INTEGER:
            tb_database_sql_value_set_int32(&row->value, sqlite3_column_int(sqlite->result.statement, (tb_int_t)itor));
            break;
        case SQLITE_TEXT:
            tb_database_sql_value_set_text(&row->value, (tb_char_t const*)sqlite3_column_text(sqlite->result.statement, (tb_int_t)itor), sqlite3_column_bytes(sqlite->result.statement, (tb_int_t)itor));
            break;
        case SQLITE_FLOAT:
#ifdef TB_CONFIG_TYPE_HAVE_FLOAT
            tb_database_sql_value_set_double(&row->value, sqlite3_column_double(sqlite->result.statement, (tb_int_t)itor));
            break;
#else
            // trace
            tb_trace1_e("float type is not supported, at col: %lu, please enable float config!", itor);
            return tb_null;
#endif
        case SQLITE_BLOB:
            tb_database_sql_value_set_blob32(&row->value, (tb_byte_t const*)sqlite3_column_blob(sqlite->result.statement, (tb_int_t)itor), sqlite3_column_bytes(sqlite->result.statement, (tb_int_t)itor), tb_null);
            break;
        case SQLITE_NULL:
            tb_database_sql_value_set_null(&row->value);
            break;
        default:
            tb_trace_e("unknown field type: %s, at col: %lu", type, itor);
            return tb_null;
        }

        // ok
        return (tb_pointer_t)&row->value;
    }

    // failed
    tb_assert(0);
    return tb_null;
}
Пример #18
0
static tb_bool_t it_find_symtab_addrs(mach_vm_address_t dyldImageLoadAddress, tb_uint32_t ncmds, mach_vm_size_t sizeofcmds, struct load_command* cmds, tb_bool_t swap, tb_size_t nlist_size, it_symtab_bundle_t* symtab, mach_vm_address_t* slide_)
{   
    // init offset
    tb_uint32_t             symoff = 0;
    tb_uint32_t             stroff = 0;

    // clear
    memset(symtab, 0, sizeof(*symtab));

    // walk
    mach_vm_address_t       vma = 0;
    struct load_command*    lc = cmds;
    tb_size_t               ln = ncmds;
    while (ln--)
    {
        tb_uint32_t cmdsize = it_swap_u32(lc->cmdsize);
        tb_assert(sizeofcmds >= sizeof(struct load_command) && sizeofcmds >= cmdsize);
        sizeofcmds -= cmdsize;

        if (!vma && it_swap_u32(lc->cmd) == LC_SEGMENT) 
        {
            struct segment_command* sc = (tb_pointer_t) lc;
            tb_assert(cmdsize >= sizeof(*sc));
            vma = it_swap_u32(sc->vmaddr);
        }
        else if (!vma && it_swap_u32(lc->cmd) == LC_SEGMENT_64) 
        {
            struct segment_command_64* sc = (tb_pointer_t) lc;
            tb_assert(cmdsize >= sizeof(*sc));
            vma = it_swap_u64(sc->vmaddr);
        }
        else if (it_swap_u32(lc->cmd) == LC_SYMTAB)
        {
            struct symtab_command* sc = (tb_pointer_t) lc;
            tb_assert(cmdsize >= sizeof(*sc));

            symoff = it_swap_u32(sc->symoff);
            symtab->nsyms = it_swap_u32(sc->nsyms);

            stroff = it_swap_u32(sc->stroff);
            symtab->strsize = it_swap_u32(sc->strsize);
            tb_assert(symtab->strsize < 10000000 && symtab->nsyms < 10000000);
        }

        // next
        lc = (tb_pointer_t) ((tb_char_t*) lc + it_swap_u32(lc->cmdsize));
    }

    // check
    tb_assert_and_check_return_val(symoff && vma, tb_false);

    // slide
    mach_vm_address_t slide = dyldImageLoadAddress - vma;
    *slide_ = slide;

    // walk
    lc = cmds;
    ln = ncmds;
    while (ln--)
    {
#define CATCH(SWAP, off, size, addr) tb_assert(SWAP(sc->fileoff) + SWAP(sc->filesize) >= SWAP(sc->fileoff)); if (SWAP(sc->fileoff) <= (off) && (SWAP(sc->fileoff) + SWAP(sc->filesize) - (off)) >= (size)) (addr) = SWAP(sc->vmaddr) + slide + (off) - SWAP(sc->fileoff);       
        if (it_swap_u32(lc->cmd) == LC_SEGMENT)
        {
            struct segment_command* sc = (tb_pointer_t) lc;
            if(!vma) vma = it_swap_u32(sc->vmaddr);
            CATCH(it_swap_u32, symoff, symtab->nsyms * nlist_size, symtab->symaddr);
            CATCH(it_swap_u32, stroff, symtab->strsize, symtab->straddr);
        }
        else if (it_swap_u32(lc->cmd) == LC_SEGMENT_64)
        {
            struct segment_command_64* sc = (tb_pointer_t) lc;
            CATCH(it_swap_u64, symoff, symtab->nsyms * nlist_size, symtab->symaddr);
            CATCH(it_swap_u64, stroff, symtab->strsize, symtab->straddr);
        }
        lc = (tb_pointer_t) ((tb_char_t*)lc + it_swap_u32(lc->cmdsize));
    }

    tb_assert(symtab->straddr);
    tb_assert(symtab->symaddr);

    // ok
    return tb_true;
}
Пример #19
0
void tdhs_dbcontext::open_table(tdhs_request_t &req) {
	//MARK 针对request type 需要进行判断,不需要open table的直接退出
	if (req.type == REQUEST_TYPE_BATCH) {
		return;
	}
	if (pool_for_open_table == NULL) {
		pool_for_open_table = easy_pool_create(MAX_POOL_SIZE_FOR_OPEN_TABLE);
	}
	if (already_cached_table_num > 0) {
		tb_assert(already_cached_table_num<=cache_table_num);
		for (unsigned int i = 0; i < already_cached_table_num; i++) {
			cached_table_t &cached_t = cached_table[i];
			if (cached_t.table != NULL) {
				TABLE* t = cached_t.table;
				opened_table_t& opened_t = for_cached_opened_table[i];
				opened_t.mysql_table = t;
				easy_hash_add(hash_table_for_opened,
						cached_t.hash_code_for_table > 0 ?
								cached_t.hash_code_for_table :
								make_hash_code_for_table(t->s->db.str,t->s->db.length,t->s->table_name.str,t->s->table_name.length)
								, &opened_t.hash);
				if (opened_table_num < DBCONTEXT_MAX_CACHE_LOCK_TABLES) {
					need_lock_tables[opened_table_num++] = t;
				} else {
					opened_table_num++;
				}
				cached_t.table = NULL; //置空
				cached_t.hash_code_for_table = 0; //置空
			}
		}
		already_cached_table_num = 0; //置0
	}

	{
		opened_table_t * opened_table = (opened_table_t *) easy_hash_find_ex(
				hash_table_for_opened, req.table_info.hash_code_table(),
				compare_table_info, &req.table_info);
		if (opened_table != NULL) {
			req.opened_table = opened_table;
		} else {
			opened_table = (opened_table_t *) easy_pool_calloc(
					pool_for_open_table, sizeof(opened_table_t));
			if (opened_table != NULL) {
				req.opened_table = opened_table;
				TABLE* t = tdhs_open_table(thd, req.table_info,
						this->need_write());
				if (t != NULL) {
					req.opened_table->mysql_table = t;
					easy_hash_add(hash_table_for_opened,
							req.table_info.hash_code_table(),
							&req.opened_table->hash);
					if (opened_table_num < DBCONTEXT_MAX_CACHE_LOCK_TABLES) {
						need_lock_tables[opened_table_num++] = t;
					} else {
						opened_table_num++;
					}
				}
			} else {
				//if opened_table==NULL because of memory is not enough
				easy_error_log(
						"TDHS:not enough memory for calloc opened_table_t!");
			}
		}

	}
}
Пример #20
0
static kern_return_t it_stuff(task_t task, cpu_type_t* cputype, it_addr_bundle_t* addrs)
{
    // make the optimizer happy
    *cputype = 0; 

    // init the task info
    task_dyld_info_data_t   info = {0};
    mach_msg_type_number_t  count = TASK_DYLD_INFO_COUNT;
    if (task_info(task, TASK_DYLD_INFO, (task_info_t) &info, &count)) return tb_false;

    // read all image info
    union 
    {
        it_dyld_all_image_infos_t       data;
        it_dyld_all_image_infos_64_t    data64;

    } u;
    mach_vm_size_t data_size = sizeof(u);
    if (info.all_image_info_size < data_size) data_size = info.all_image_info_size;
    if (mach_vm_read_overwrite(task, info.all_image_info_addr, data_size, it_address_cast(&u), &data_size)) return tb_false;
    if (u.data.version <= 1) return tb_false;

    // read mach header
#if defined(TB_ARCH_x86) || defined(TB_ARCH_x64) || defined(TB_ARCH_ARM64)
    tb_bool_t proc64 = u.data64.dyldImageLoadAddress > 0? tb_true : tb_false;
#else
    tb_bool_t proc64 = tb_false;
#endif 
    tb_trace_d("proc64: %p", proc64);   
    struct mach_header  mach_hdr = {0};
    mach_vm_address_t   dyldImageLoadAddress = proc64? u.data64.dyldImageLoadAddress : u.data.dyldImageLoadAddress;
    if (mach_vm_read_overwrite(task, dyldImageLoadAddress, (mach_vm_size_t)sizeof(mach_hdr), it_address_cast(&mach_hdr), &data_size)) return tb_false;

    // swap?
    tb_bool_t               swap = (mach_hdr.magic == MH_CIGAM || mach_hdr.magic == MH_CIGAM_64)? tb_true : tb_false;
    tb_trace_d("swap: %u", swap);

    // save sputype
    *cputype = it_swap_u32(mach_hdr.cputype);

    // read cmds
    mach_vm_size_t          sizeofcmds = it_swap_u32(mach_hdr.sizeofcmds);
    struct load_command*    cmds = malloc(sizeofcmds);
    tb_bool_t               mh64 = (mach_hdr.magic == MH_MAGIC_64 || mach_hdr.magic == MH_CIGAM_64)? tb_true : tb_false;
    tb_trace_d("mh64: %u", mh64);   
    if (mach_vm_read_overwrite(task, dyldImageLoadAddress + (mh64 ? sizeof(struct mach_header_64) : sizeof(struct mach_header)), (mach_vm_size_t)sizeofcmds, it_address_cast(cmds), &sizeofcmds)) return tb_false;

    // read symtab
    mach_vm_address_t       slide;
    it_symtab_bundle_t      symtab;
    tb_size_t               nlist_size = mh64 ? sizeof(struct nlist_64) : sizeof(struct nlist);
    if (!it_find_symtab_addrs(dyldImageLoadAddress, mach_hdr.ncmds, sizeofcmds, cmds, swap, nlist_size, &symtab, &slide)) return tb_false;

    // read strs & syms
    tb_char_t*      strs = malloc(symtab.strsize);
    tb_pointer_t    syms = malloc(symtab.nsyms * nlist_size);
    if (mach_vm_read_overwrite(task, symtab.straddr, (mach_vm_size_t)(symtab.strsize), it_address_cast(strs), &data_size)) return tb_false;
    if (mach_vm_read_overwrite(task, symtab.symaddr, (mach_vm_size_t)(symtab.nsyms * nlist_size), it_address_cast(syms), &data_size)) return tb_false;

    // read address
    memset(addrs, 0, sizeof(*addrs));
    if (mh64) 
    {
        struct nlist_64 const* nl = syms;
        while (symtab.nsyms--) 
        {
            tb_uint32_t strx = (tb_uint32_t) it_swap_u32(nl->n_un.n_strx);
            tb_assert(strx < symtab.strsize);
            it_handle_sym(strs + strx, symtab.strsize - strx, (mach_vm_address_t) it_swap_u64(nl->n_value) + slide, addrs);
            nl++;
        }
    } 
    else 
    {
        struct nlist const* nl = syms;
        while (symtab.nsyms--)
        {
            tb_uint32_t strx = it_swap_u32(nl->n_un.n_strx);
            tb_assert(strx < symtab.strsize);
            it_handle_sym(strs + strx, symtab.strsize - strx, (mach_vm_address_t) it_swap_u32(nl->n_value) + slide, addrs);
            nl++;
        }
    }
    tb_assert(addrs->dlopen);
    tb_assert(addrs->syscall);

    // free
    if (cmds) free(cmds);
    if (strs) free(strs);
    if (syms) free(syms);

    // ok
    return tb_true;
}
Пример #21
0
static tb_pointer_t tb_aiop_spak_loop(tb_cpointer_t priv)
{
    // check
    tb_aiop_ptor_impl_t*    impl = (tb_aiop_ptor_impl_t*)priv;
    tb_aicp_impl_t*         aicp = impl? impl->base.aicp : tb_null;

    // done
    do
    {
        // check
        tb_assert_and_check_break(impl && impl->aiop && impl->list && impl->timer && impl->ltimer && aicp);

        // trace
        tb_trace_d("loop: init");

        // loop
        while (!tb_atomic_get(&aicp->kill))
        {
            // the delay
            tb_size_t delay = tb_timer_delay(impl->timer);

            // the ldelay
            tb_size_t ldelay = tb_ltimer_delay(impl->ltimer);
            tb_assert_and_check_break(ldelay != -1);

            // trace
            tb_trace_d("loop: wait: ..");

            // wait aioe
            tb_long_t real = tb_aiop_wait(impl->aiop, impl->list, impl->maxn, tb_min(delay, ldelay));

            // trace
            tb_trace_d("loop: wait: %ld", real);

            // spak ctime
            tb_cache_time_spak();

            // spak timer
            if (!tb_timer_spak(impl->timer)) break;

            // spak ltimer
            if (!tb_ltimer_spak(impl->ltimer)) break;

            // killed?
            tb_check_break(real >= 0);

            // error? out of range
            tb_assert_and_check_break(real <= impl->maxn);

            // timeout?
            tb_check_continue(real);

            // grow it if aioe is full
            if (real == impl->maxn)
            {
                // grow size
                impl->maxn += (aicp->maxn >> 4) + 16;
                if (impl->maxn > aicp->maxn) impl->maxn = aicp->maxn;

                // grow list
                impl->list = tb_ralloc(impl->list, impl->maxn * sizeof(tb_aioe_t));
                tb_assert_and_check_break(impl->list);
            }

            // walk aioe list
            tb_size_t i = 0;
            tb_bool_t end = tb_false;
            for (i = 0; i < real && !end; i++)
            {
                // the aioe
                tb_aioe_ref_t aioe = &impl->list[i];
                tb_assert_and_check_break_state(aioe, end, tb_true);

                // the aice
                tb_aice_ref_t aice = (tb_aice_ref_t)aioe->priv;
                tb_assert_and_check_break_state(aice, end, tb_true);

                // the aico
                tb_aiop_aico_t* aico = (tb_aiop_aico_t*)aice->aico;
                tb_assert_and_check_break_state(aico, end, tb_true);

                // have wait?
                tb_check_continue(aice->code);

                // have been waited ok for the timer timeout/killed func? need not spak it repeatly
                tb_check_continue(!aico->wait_ok);

                // sock?
                if (aico->base.type == TB_AICO_TYPE_SOCK)
                {
                    // push the acpt aice
                    if (aice->code == TB_AICE_CODE_ACPT) end = tb_aiop_push_acpt(impl, aice)? tb_false : tb_true;
                    // push the sock aice
                    else end = tb_aiop_push_sock(impl, aice)? tb_false : tb_true;
                }
                else if (aico->base.type == TB_AICO_TYPE_FILE)
                {
                    // poll file
                    tb_aicp_file_poll(impl);
                }
                else tb_assert(0);
            }

            // end?
            tb_check_break(!end);

            // work it
            tb_aiop_spak_work(impl);
        }

    } while (0);

    // trace
    tb_trace_d("loop: exit");

    // kill
    tb_aicp_kill((tb_aicp_ref_t)aicp);

    // exit
    tb_thread_return(tb_null);
    return tb_null;
}
Пример #22
0
Файл: mesh.c Проект: waruqi/gbox
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
tb_bool_t gb_tessellator_mesh_make(gb_tessellator_impl_t* impl, gb_polygon_ref_t polygon)
{
    // check
    tb_assert(impl && polygon);

    // the points
    gb_point_ref_t      points = polygon->points;
    tb_uint16_t const*  counts = polygon->counts;
    tb_assert_and_check_return_val(points && counts, tb_false);

    // not exists mesh?
    if (!impl->mesh) 
    {
        // init func
        tb_element_t edge_element    = tb_element_mem(sizeof(gb_tessellator_edge_t), tb_null, tb_null);
        tb_element_t face_element    = tb_element_mem(sizeof(gb_tessellator_face_t), tb_null, tb_null);
        tb_element_t vertex_element  = tb_element_mem(sizeof(gb_tessellator_vertex_t), tb_null, tb_null);

#ifdef __gb_debug__
        // init func cstr for gb_mesh_dump
        edge_element.cstr      = gb_tessellator_edge_cstr;
        face_element.cstr      = gb_tessellator_face_cstr;
        vertex_element.cstr    = gb_tessellator_vertex_cstr;
#endif

        // init mesh
        impl->mesh = gb_mesh_init(edge_element, face_element, vertex_element);

        /* init the order
         *
         * the new edges/faces/vertice will be inserted to the head of list
         */
        gb_mesh_edge_order_set(impl->mesh,      GB_MESH_ORDER_INSERT_HEAD);
        gb_mesh_face_order_set(impl->mesh,      GB_MESH_ORDER_INSERT_HEAD);
        gb_mesh_vertex_order_set(impl->mesh,    GB_MESH_ORDER_INSERT_HEAD);

        // init listener
        gb_mesh_listener_set(impl->mesh, gb_tessellator_listener, impl->mesh);
        gb_mesh_listener_event_add(impl->mesh, GB_MESH_EVENT_FACE_SPLIT | GB_MESH_EVENT_EDGE_SPLIT);
    }

    // check
    gb_mesh_ref_t mesh = impl->mesh;
    tb_assert_and_check_return_val(mesh, tb_false);

    // clear mesh first
    gb_mesh_clear(mesh);

    // done
    gb_point_ref_t      point       = tb_null;
    tb_uint16_t         count       = *counts++;
    tb_size_t           index       = 0;
    gb_mesh_edge_ref_t  edge        = tb_null;
    gb_mesh_edge_ref_t  edge_first  = tb_null;
    while (index < count)
    {
        // the point
        point = points++;

        // first point?
        if (!index) 
        {
            // must be closed contour
            tb_assertf(gb_point_eq(point, point + count - 1), "this contour(%lu: %{point} => %{point}) is not closed!", count, point, point + count - 1);
            
            // clear the edge
            edge = tb_null;

            // clear the first edge
            edge_first = tb_null;

            // trace
            tb_trace_d("move_to: %{point}", point);
        }
        // closed?
        else if (index + 1 == count)
        {
            // trace
            tb_trace_d("closed: %{point}", point);

            // connect an edge to the first edge
            edge = gb_mesh_edge_connect(mesh, edge, edge_first);

            // init edge.faces.inside
            gb_tessellator_face_inside_set(gb_mesh_edge_lface(edge), 0);
            gb_tessellator_face_inside_set(gb_mesh_edge_rface(edge), 0);
        }
        else 
        {
            // trace
            tb_trace_d("line_to: %{point}", point);

            // exists the first edge?
            if (edge_first)
            {
                // append an edge
                edge = gb_mesh_edge_append(mesh, edge);
            }
            else
            {
                // make a new non-loop edge
                edge = gb_mesh_edge_make(mesh);

                // save the first edge
                edge_first = edge;
            }
        }

        // has new edge?
        if (edge)
        {
            // init edge.winding
            gb_tessellator_edge_winding_set(edge, 1);
            gb_tessellator_edge_winding_set(gb_mesh_edge_sym(edge), -1);

            // init edge.region
            gb_tessellator_edge_region_set(edge, tb_null);
            gb_tessellator_edge_region_set(gb_mesh_edge_sym(edge), tb_null);

            // init edge.dst
            gb_tessellator_vertex_point_set(gb_mesh_edge_dst(edge), point);
        }

        // next point
        index++;

        // next polygon
        if (index == count) 
        {
            // next
            count = *counts++;
            index = 0;
        }
    }

#ifdef __gb_debug__
    // check mesh
    gb_mesh_check(mesh);
#endif

    // ok?
    return !gb_mesh_is_empty(mesh);
}
Пример #23
0
tb_bool_t tb_hwaddr_cstr_set(tb_hwaddr_ref_t hwaddr, tb_char_t const* cstr)
{
    // check
    tb_assert_and_check_return_val(cstr, tb_false);

    // done
    tb_uint32_t         v = 0;
    tb_char_t           c = '\0';
    tb_size_t           i = 0;
    tb_char_t const*    p = cstr;
    tb_bool_t           ok = tb_true;
    tb_hwaddr_t         temp;
    do
    {
        // the character
        c = *p++;

        // digit?
        if (tb_isdigit16(c) && v <= 0xff)
        {
            // update value
            if (tb_isdigit10(c))
                v = (v << 4) + (c - '0');
            else if (c > ('a' - 1) && c < ('f' + 1))
                v = (v << 4) + (c - 'a') + 10;
            else if (c > ('A' - 1) && c < ('F' + 1))
                v = (v << 4) + (c - 'A') + 10;
            else 
            {
                // abort
                tb_assert(0);

                // failed
                ok = tb_false;
                break;
            }
        }
        // ':' or "-" or '\0'?
        else if (i < 6 && (c == ':' || c == '-' || !c) && v <= 0xff)
        {
            // save value
            temp.u8[i++] = v;

            // clear value
            v = 0;
        }
        // failed?
        else 
        {
            ok = tb_false;
            break;
        }

    } while (c);

    // failed
    if (i != 6) ok = tb_false;

    // save it if ok
    if (ok && hwaddr) *hwaddr = temp;

    // trace
//    tb_assertf(ok, "invalid hwaddr: %s", cstr);

    // ok?
    return ok;
}
Пример #24
0
static tb_void_t tb_ifaddrs_interface_load6(tb_list_ref_t interfaces)
{
    // check
    tb_assert_and_check_return(interfaces);

    // done
    PIP_ADAPTER_ADDRESSES addresses = tb_null;
    do
    {
        // make the addresses
        addresses = (PIP_ADAPTER_ADDRESSES)tb_malloc0_type(IP_ADAPTER_ADDRESSES);
        tb_assert_and_check_break(addresses);

        // get the real adapter info size
        ULONG size = sizeof(IP_ADAPTER_ADDRESSES);
        if (tb_iphlpapi()->GetAdaptersAddresses(AF_INET6, GAA_FLAG_SKIP_DNS_SERVER, tb_null, addresses, &size) == ERROR_BUFFER_OVERFLOW)
        {
            // grow the adapter info buffer
            addresses = (PIP_ADAPTER_ADDRESSES)tb_ralloc(addresses, size);
            tb_assert_and_check_break(addresses);

            // reclear it
            tb_memset(addresses, 0, size);
        }
     
        // get the addresses
        if (tb_iphlpapi()->GetAdaptersAddresses(AF_INET6, GAA_FLAG_SKIP_DNS_SERVER, tb_null, addresses, &size) != NO_ERROR) break;

        // done
        PIP_ADAPTER_ADDRESSES address = addresses;
        while (address)
        {
            // check
            tb_assert(address->AdapterName);

            /* attempt to get the interface from the cached interfaces
             * and make a new interface if no the cached interface
             */
            tb_ifaddrs_interface_t      interface_new = {0};
            tb_ifaddrs_interface_ref_t  interface = tb_ifaddrs_interface_find((tb_iterator_ref_t)interfaces, address->AdapterName);
            if (!interface) interface = &interface_new;

            // check
            tb_assert(interface == &interface_new || interface->name);

            // save flags
            if (address->IfType == IF_TYPE_SOFTWARE_LOOPBACK) interface->flags |= TB_IFADDRS_INTERFACE_FLAG_IS_LOOPBACK;

            // save hwaddr
            if (address->PhysicalAddressLength == sizeof(interface->hwaddr.u8))
            {
                interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR;
                tb_memcpy(interface->hwaddr.u8, address->PhysicalAddress, sizeof(interface->hwaddr.u8));
            }

            // save ipaddrs
            PIP_ADAPTER_UNICAST_ADDRESS ipAddress = address->FirstUnicastAddress;
            while (ipAddress && (interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR) != TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR)
            {
                // done
                tb_ipaddr_t ipaddr;
                struct sockaddr_storage* saddr = (struct sockaddr_storage*)ipAddress->Address.lpSockaddr;
                if (saddr && tb_sockaddr_save(&ipaddr, saddr))
                {
                    if (ipaddr.family == TB_IPADDR_FAMILY_IPV4)
                    {
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR4;
                        interface->ipaddr4 = ipaddr.u.ipv4;
                    }
                    else if (ipaddr.family == TB_IPADDR_FAMILY_IPV6)
                    {
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR6;
                        interface->ipaddr6 = ipaddr.u.ipv6;
                    }
                }

                // the next
                ipAddress = ipAddress->Next;
            }

            // new interface? save it
            if (    interface == &interface_new
                &&  interface->flags)
            {
                // save interface name
                interface->name = tb_strdup(address->AdapterName);
                tb_assert(interface->name);

                // save interface
                tb_list_insert_tail(interfaces, interface);
            }

            // the next address
            address = address->Next;
        }

    } while (0);

    // exit the addresses
    if (addresses) tb_free(addresses);
    addresses = tb_null;
}
Пример #25
0
	pthread_mutex_locker(pthread_mutex_t *_lock) :
			lock(_lock) {
		tb_assert(lock!=NULL)
		pthread_mutex_lock(lock);
	}
Пример #26
0
static tb_void_t tb_ifaddrs_interface_done_ipaddr(tb_list_ref_t interfaces, tb_hash_map_ref_t names, struct nlmsghdr* response)
{
    // check
    tb_assert_and_check_return(interfaces && names && response);

    // the info
    struct ifaddrmsg* info = (struct ifaddrmsg *)NLMSG_DATA(response);

    // must be not link 
    tb_assert_and_check_return(info->ifa_family != AF_PACKET);

    // attempt to find the interface name
    tb_bool_t   owner = tb_false;
    tb_char_t*  name = (tb_char_t*)tb_hash_map_get(names, tb_u2p(info->ifa_index));
    if (!name)
    {
        // get the interface name
        struct rtattr*  rta = tb_null;
        tb_size_t       rta_size = NLMSG_PAYLOAD(response, sizeof(struct ifaddrmsg));
        for(rta = IFA_RTA(info); RTA_OK(rta, rta_size); rta = RTA_NEXT(rta, rta_size))
        {
            // done
            tb_pointer_t    rta_data = RTA_DATA(rta);
            tb_size_t       rta_data_size = RTA_PAYLOAD(rta);
            switch(rta->rta_type)
            {
                case IFA_LABEL:
                    {
                        // make name
                        name = (tb_char_t*)tb_ralloc(name, rta_data_size + 1);
                        tb_assert_and_check_break(name);

                        // copy name
                        tb_strlcpy(name, rta_data, rta_data_size + 1);

                        // save name
                        tb_hash_map_insert(names, tb_u2p(info->ifa_index), name);
                        owner = tb_true;
                    }
                    break;
                default:
                    break;
            }
        }
    }

    // check
    tb_check_return(name);

    // done
    struct rtattr*  rta = tb_null;
    tb_size_t       rta_size = NLMSG_PAYLOAD(response, sizeof(struct ifaddrmsg));
    for(rta = IFA_RTA(info); RTA_OK(rta, rta_size); rta = RTA_NEXT(rta, rta_size))
    {
        /* attempt to get the interface from the cached interfaces
         * and make a new interface if no the cached interface
         */
        tb_ifaddrs_interface_t      interface_new = {0};
        tb_ifaddrs_interface_ref_t  interface = tb_ifaddrs_interface_find((tb_iterator_ref_t)interfaces, name);
        if (!interface) interface = &interface_new;

        // check
        tb_assert(interface == &interface_new || interface->name);

        // done
        tb_pointer_t rta_data = RTA_DATA(rta);
        switch(rta->rta_type)
        {
            case IFA_LOCAL:
            case IFA_ADDRESS:
                {
                    // make ipaddr
                    tb_ipaddr_t ipaddr;
                    if (!tb_ifaddrs_netlink_ipaddr_save(&ipaddr, info->ifa_family, info->ifa_index, rta_data)) break;

                    // save flags
                    if ((info->ifa_flags & IFF_LOOPBACK) || tb_ipaddr_ip_is_loopback(&ipaddr)) 
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_IS_LOOPBACK;

                    // save ipaddr
                    switch (tb_ipaddr_family(&ipaddr))
                    {
                    case TB_IPADDR_FAMILY_IPV4:
                        {
                            interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR4;
                            interface->ipaddr4 = ipaddr.u.ipv4;
                        }
                        break;
                    case TB_IPADDR_FAMILY_IPV6:
                        {
                            interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR6;
                            interface->ipaddr6 = ipaddr.u.ipv6;
                        }
                        break;
                    default:
                        break;
                    }

                    // trace
                    tb_trace_d("name: %s, ipaddr: %{ipaddr}", name, &ipaddr);

                    // new interface? save it
                    if (tb_ipaddr_family(&ipaddr) && interface == &interface_new)
                    {
                        // save interface name
                        interface->name = tb_strdup(name);
                        tb_assert(interface->name);

                        // save interface
                        tb_list_insert_tail(interfaces, interface);
                    }
                }
                break;
            case IFA_LABEL:
            case IFA_BROADCAST:
                break;
            default:
                break;
        }
    }

    // exit name
    if (name && owner) tb_free(name);
    name = tb_null;
}
Пример #27
0
static tb_long_t tb_aiop_rtor_kqueue_wait(tb_aiop_rtor_impl_t* rtor, tb_aioe_ref_t list, tb_size_t maxn, tb_long_t timeout)
{   
    // check
    tb_aiop_rtor_kqueue_impl_t* impl = (tb_aiop_rtor_kqueue_impl_t*)rtor;
    tb_assert_and_check_return_val(impl && impl->kqfd >= 0 && rtor->aiop && list && maxn, -1);

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

    // init time
    struct timespec t = {0};
    if (timeout > 0)
    {
        t.tv_sec = timeout / 1000;
        t.tv_nsec = (timeout % 1000) * 1000000;
    }

    // init grow
    tb_size_t grow = tb_align8((rtor->aiop->maxn >> 3) + 1);

    // init events
    if (!impl->evts)
    {
        impl->evtn = grow;
        impl->evts = tb_nalloc0(impl->evtn, sizeof(struct kevent));
        tb_assert_and_check_return_val(impl->evts, -1);
    }

    // wait events
    tb_long_t evtn = kevent(impl->kqfd, tb_null, 0, impl->evts, impl->evtn, timeout >= 0? &t : tb_null);
    tb_assert_and_check_return_val(evtn >= 0 && evtn <= impl->evtn, -1);
    
    // timeout?
    tb_check_return_val(evtn, 0);

    // grow it if events is full
    if (evtn == impl->evtn)
    {
        // grow size
        impl->evtn += grow;
        if (impl->evtn > rtor->aiop->maxn) impl->evtn = rtor->aiop->maxn;

        // grow data
        impl->evts = tb_ralloc(impl->evts, impl->evtn * sizeof(struct kevent));
        tb_assert_and_check_return_val(impl->evts, -1);
    }
    tb_assert(evtn <= impl->evtn);

    // limit 
    evtn = tb_min(evtn, maxn);

    // sync
    tb_size_t i = 0;
    tb_size_t wait = 0;
    for (i = 0; i < evtn; i++)
    {
        // the kevents 
        struct kevent* e = impl->evts + i;

        // the aioo
        tb_aioo_impl_t* aioo = (tb_aioo_impl_t*)e->udata;
        tb_assert_and_check_return_val(aioo && aioo->sock, -1);
        
        // the sock 
        tb_socket_ref_t sock = aioo->sock;

        // spak?
        if (sock == aiop->spak[1] && e->filter == EVFILT_READ) 
        {
            // 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;

            // continue it
            continue ;
        }

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

        // init the aioe
        tb_aioe_ref_t aioe = &list[wait++];
        aioe->code = TB_AIOE_CODE_NONE;
        aioe->aioo = (tb_aioo_ref_t)aioo;
        aioe->priv = aioo->priv;
        if (e->filter == EVFILT_READ) 
        {
            aioe->code |= TB_AIOE_CODE_RECV;
            if (aioo->code & TB_AIOE_CODE_ACPT) aioe->code |= TB_AIOE_CODE_ACPT;
        }
        if (e->filter == EVFILT_WRITE) 
        {
            aioe->code |= TB_AIOE_CODE_SEND;
            if (aioo->code & TB_AIOE_CODE_CONN) aioe->code |= TB_AIOE_CODE_CONN;
        }
        if ((e->flags & EV_ERROR) && !(aioe->code & (TB_AIOE_CODE_RECV | TB_AIOE_CODE_SEND))) 
            aioe->code |= TB_AIOE_CODE_RECV | TB_AIOE_CODE_SEND;

        // oneshot? clear it
        if (aioo->code & TB_AIOE_CODE_ONESHOT) 
        {
            aioo->code = TB_AIOE_CODE_NONE;
            aioo->priv = tb_null;
        }
    }

    // ok
    return wait;
}
Пример #28
0
static tb_void_t tb_ifaddrs_interface_done_hwaddr(tb_list_ref_t interfaces, tb_hash_map_ref_t names, struct nlmsghdr* response)
{
    // check
    tb_assert_and_check_return(interfaces && names && response);

    // the info
    struct ifaddrmsg* info = (struct ifaddrmsg *)NLMSG_DATA(response);

    // attempt to find the interface name
    tb_bool_t   owner = tb_false;
    tb_char_t*  name = (tb_char_t*)tb_hash_map_get(names, tb_u2p(info->ifa_index));
    if (!name)
    {
        // get the interface name
        struct rtattr*  rta = tb_null;
        tb_size_t       rta_size = NLMSG_PAYLOAD(response, sizeof(struct ifaddrmsg));
        for(rta = IFLA_RTA(info); RTA_OK(rta, rta_size); rta = RTA_NEXT(rta, rta_size))
        {
            // done
            tb_pointer_t    rta_data = RTA_DATA(rta);
            tb_size_t       rta_data_size = RTA_PAYLOAD(rta);
            switch(rta->rta_type)
            {
                case IFLA_IFNAME:
                    {
                        // make name
                        name = (tb_char_t*)tb_ralloc(name, rta_data_size + 1);
                        tb_assert_and_check_break(name);

                        // copy name
                        tb_strlcpy(name, rta_data, rta_data_size + 1);

                        // save name
                        tb_hash_map_insert(names, tb_u2p(info->ifa_index), name);
                        owner = tb_true;
                    }
                    break;
                default:
                    break;
            }
        }
    }

    // check
    tb_check_return(name);

    // done
    struct rtattr*  rta = tb_null;
    tb_size_t       rta_size = NLMSG_PAYLOAD(response, sizeof(struct ifaddrmsg));
    for(rta = IFLA_RTA(info); RTA_OK(rta, rta_size); rta = RTA_NEXT(rta, rta_size))
    {
        /* attempt to get the interface from the cached interfaces
         * and make a new interface if no the cached interface
         */
        tb_ifaddrs_interface_t      interface_new = {0};
        tb_ifaddrs_interface_ref_t  interface = tb_ifaddrs_interface_find((tb_iterator_ref_t)interfaces, name);
        if (!interface) interface = &interface_new;

        // check
        tb_assert(interface == &interface_new || interface->name);

        // done
        tb_pointer_t    rta_data = RTA_DATA(rta);
        tb_size_t       rta_data_size = RTA_PAYLOAD(rta);
        switch(rta->rta_type)
        {
            case IFLA_ADDRESS:
                {
                    // no hwaddr?
                    if (!(interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR))
                    {
                        // check
                        tb_check_break(rta_data_size == sizeof(interface->hwaddr.u8));

                        // save flags
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR;
                        if (info->ifa_flags & IFF_LOOPBACK) interface->flags |= TB_IFADDRS_INTERFACE_FLAG_IS_LOOPBACK;

                        // save hwaddr
                        tb_memcpy(interface->hwaddr.u8, rta_data, sizeof(interface->hwaddr.u8));

                        // trace
                        tb_trace_d("name: %s, hwaddr: %{hwaddr}", name, &interface->hwaddr);

                        // new interface? save it
                        if (interface == &interface_new)
                        {
                            // save interface name
                            interface->name = tb_strdup(name);
                            tb_assert(interface->name);

                            // save interface
                            tb_list_insert_tail(interfaces, interface);
                        }
                    }
                }
                break;
            case IFLA_IFNAME:
            case IFLA_BROADCAST:
            case IFLA_STATS:
                break;
            default:
                break;
        }
    }

    // exit name
    if (name && owner) tb_free(name);
    name = tb_null;
}
Пример #29
0
static tb_void_t tb_ifaddrs_interface_load4(tb_list_ref_t interfaces)
{
    // check
    tb_assert_and_check_return(interfaces);

    // done
    PIP_ADAPTER_INFO adapter_info = tb_null;
    do
    {
        // make the adapter info 
        adapter_info = tb_malloc0_type(IP_ADAPTER_INFO);
        tb_assert_and_check_break(adapter_info);

        // get the real adapter info size
        ULONG size = sizeof(IP_ADAPTER_INFO);
        if (tb_iphlpapi()->GetAdaptersInfo(adapter_info, &size) == ERROR_BUFFER_OVERFLOW)
        {
            // grow the adapter info buffer
            adapter_info = (PIP_ADAPTER_INFO)tb_ralloc(adapter_info, size);
            tb_assert_and_check_break(adapter_info);

            // reclear it
            tb_memset(adapter_info, 0, size);
        }
    
        // get the adapter info 
        if (tb_iphlpapi()->GetAdaptersInfo(adapter_info, &size) != NO_ERROR) break;

        // done
        PIP_ADAPTER_INFO adapter = adapter_info;
        while (adapter)
        {
            // check
            tb_assert(adapter->AdapterName);

            /* attempt to get the interface from the cached interfaces
             * and make a new interface if no the cached interface
             */
            tb_ifaddrs_interface_t      interface_new = {0};
            tb_ifaddrs_interface_ref_t  interface = tb_ifaddrs_interface_find((tb_iterator_ref_t)interfaces, adapter->AdapterName);
            if (!interface) interface = &interface_new;

            // check
            tb_assert(interface == &interface_new || interface->name);

            // save flags
            if (adapter->Type == MIB_IF_TYPE_LOOPBACK) interface->flags |= TB_IFADDRS_INTERFACE_FLAG_IS_LOOPBACK;

            // save hwaddr
            if (adapter->AddressLength == sizeof(interface->hwaddr.u8))
            {
                interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR;
                tb_memcpy(interface->hwaddr.u8, adapter->Address, sizeof(interface->hwaddr.u8));
            }

            // save ipaddrs
            PIP_ADDR_STRING ipAddress = &adapter->IpAddressList;
            while (ipAddress && (interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR) != TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR)
            {
                // done
                tb_ipaddr_t ipaddr;
                if (    ipAddress->IpAddress.String
                    &&  tb_ipaddr_ip_cstr_set(&ipaddr, ipAddress->IpAddress.String, TB_IPADDR_FAMILY_NONE))
                {
                    if (ipaddr.family == TB_IPADDR_FAMILY_IPV4)
                    {
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR4;
                        interface->ipaddr4 = ipaddr.u.ipv4;
                    }
                    else if (ipaddr.family == TB_IPADDR_FAMILY_IPV6)
                    {
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR6;
                        interface->ipaddr6 = ipaddr.u.ipv6;
                    }
                }

                // the next
                ipAddress = ipAddress->Next;
            }

            // new interface? save it
            if (    interface == &interface_new
                &&  interface->flags)
            {
                // save interface name
                interface->name = tb_strdup(adapter->AdapterName);
                tb_assert(interface->name);

                // save interface
                tb_list_insert_tail(interfaces, interface);
            }

            // the next adapter
            adapter = adapter->Next;
        }

    } while (0);

    // exit the adapter info
    if (adapter_info) tb_free(adapter_info);
    adapter_info = tb_null;
}
Пример #30
0
static tb_static_large_data_head_t* tb_static_large_allocator_malloc_find(tb_static_large_allocator_ref_t allocator, tb_static_large_data_head_t* data_head, tb_size_t walk_size, tb_size_t space)
{
    // check
    tb_assert_and_check_return_val(allocator && data_head && space, tb_null);

    // the data tail
    tb_static_large_data_head_t* data_tail = allocator->data_tail;
    tb_check_return_val(data_head < data_tail, tb_null);

    // find the free data 
    while ((data_head + 1) <= data_tail && walk_size)
    {
        // the data space size
        tb_size_t data_space = data_head->space;

        // check the space size
        tb_assert(!((sizeof(tb_static_large_data_head_t) + data_space) & (allocator->page_size - 1)));
            
#ifdef __tb_debug__
        // check the data
        if (!data_head->bfree) tb_static_large_allocator_check_data(allocator, data_head);
#endif

        // allocate if the data is free
        if (data_head->bfree)
        {
            // is enough?           
            if (data_space >= space)
            {
                // remove this free data from the pred cache
                tb_static_large_allocator_pred_remove(allocator, data_head);

                // split it if this free data is too large
                if (data_space > sizeof(tb_static_large_data_head_t) + space)
                {
                    // split this free data 
                    tb_static_large_data_head_t* next_head = (tb_static_large_data_head_t*)((tb_byte_t*)(data_head + 1) + space);
                    next_head->space = data_space - space - sizeof(tb_static_large_data_head_t);
                    next_head->bfree = 1;
                    data_head->space = space;
 
                    // add next free data to the pred cache
                    tb_static_large_allocator_pred_update(allocator, next_head);
                }
                else
                {
                    // the next data head
                    tb_static_large_data_head_t* next_head = (tb_static_large_data_head_t*)((tb_byte_t*)(data_head + 1) + data_space);
            
                    // the next data is free?
                    if (next_head + 1 < data_tail && next_head->bfree)
                    {
                        // add next free data to the pred cache
                        tb_static_large_allocator_pred_update(allocator, next_head);
                    }
                }

                // allocate the data 
                data_head->bfree = 0;

                // return the data head
                return data_head;
            }
            else // attempt to merge next free data if this free data is too small
            {
                // the next data head
                tb_static_large_data_head_t* next_head = (tb_static_large_data_head_t*)((tb_byte_t*)(data_head + 1) + data_space);
            
                // break if doesn't exist next data
                tb_check_break(next_head + 1 < data_tail);

                // the next data is free?
                if (next_head->bfree)
                {
                    // remove next free data from the pred cache
                    tb_static_large_allocator_pred_remove(allocator, next_head);

                    // remove this free data from the pred cache
                    tb_static_large_allocator_pred_remove(allocator, data_head);

                    // trace
                    tb_trace_d("malloc: find: merge: %lu", next_head->space);

                    // merge next data
                    data_head->space += sizeof(tb_static_large_data_head_t) + next_head->space;

                    // add this free data to the pred cache
                    tb_static_large_allocator_pred_update(allocator, data_head);

                    // continue handle this data 
                    continue ;
                }
            }
        }

        // walk_size--
        walk_size--;
    
        // skip it if the data is non-free or too small
        data_head = (tb_static_large_data_head_t*)((tb_byte_t*)(data_head + 1) + data_space);
    }

    // failed
    return tb_null;
}