/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_bool_t tb_native_memory_init() { // enter tb_spinlock_enter_without_profiler(&g_lock); // done tb_bool_t ok = tb_false; do { // have been inited? tb_check_break_state(!g_heap, ok, tb_true); // make heap g_heap = (tb_handle_t)HeapCreate(0, 0, 0); tb_check_break(g_heap); // ok ok = tb_true; } while (0); // leave tb_spinlock_leave(&g_lock); // ok? return ok; }
static tb_long_t tb_ifaddrs_interface_done(tb_list_ref_t interfaces, tb_hash_map_ref_t names, tb_long_t sock, tb_long_t request) { // check tb_assert_and_check_return_val(interfaces && names && sock >= 0, -1); // done tb_size_t size = 4096; tb_pointer_t data = tb_null; tb_long_t ok = -1; pid_t pid = getpid(); while (ok < 0) { // make data data = tb_ralloc(data, size); tb_assert_and_check_break(data); // trace tb_trace_d("netlink: recv: .."); // recv response tb_long_t recv = tb_ifaddrs_netlink_socket_recv(sock, data, size); // trace tb_trace_d("netlink: recv: %ld", recv); // space not enough? if (recv == -1) { // grow space and continue it size <<= 1; continue ; } // check tb_assert_and_check_break(recv > 0); // done tb_bool_t failed = tb_false; struct nlmsghdr* response = tb_null; for (response = (struct nlmsghdr *)data; NLMSG_OK(response, (tb_uint_t)recv); response = (struct nlmsghdr *)NLMSG_NEXT(response, recv)) { // trace tb_trace_d("type: %d, pid: %ld ?= %ld, sock: %ld ?= %ld", response->nlmsg_type, (tb_long_t)response->nlmsg_pid, (tb_long_t)pid, (tb_long_t)response->nlmsg_seq, (tb_long_t)sock); // failed? tb_check_break_state(response->nlmsg_type != NLMSG_ERROR, failed, tb_true); // invalid pid? tb_assert_and_check_break_state((tb_long_t)response->nlmsg_pid > 0, failed, tb_true); // isn't it? if ((pid_t)response->nlmsg_pid != pid || (tb_long_t)response->nlmsg_seq != sock) continue; // done? if (response->nlmsg_type == NLMSG_DONE) { // trace tb_trace_d("done"); // ok ok = 1; break; } // get hwaddr? if (request == RTM_GETLINK && response->nlmsg_type == RTM_NEWLINK) { // done hwaddr tb_ifaddrs_interface_done_hwaddr(interfaces, names, response); } // get ipaddr? else if (request == RTM_GETADDR && response->nlmsg_type == RTM_NEWADDR) { // done ipaddr tb_ifaddrs_interface_done_ipaddr(interfaces, names, response); } } // failed? tb_check_break(!failed); // continue if empty? if (ok < 0) ok = 0; break; } // exit data if (data) tb_free(data); data = tb_null; // ok? return ok; }