/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ static tb_size_t tb_item_func_size_hash(tb_item_func_t* func, tb_cpointer_t data, tb_size_t mask, tb_size_t index) { #if TB_CPU_BIT64 tb_assert_static(sizeof(tb_size_t) == sizeof(tb_uint64_t)); return tb_item_func_hash_uint64((tb_uint64_t)data, mask, index); #else tb_assert_static(sizeof(tb_size_t) == sizeof(tb_uint32_t)); return tb_item_func_hash_uint32((tb_uint32_t)data, mask, index); #endif }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ static tb_size_t tb_element_size_hash(tb_element_ref_t element, tb_cpointer_t data, tb_size_t mask, tb_size_t index) { #if TB_CPU_BIT64 tb_assert_static(sizeof(tb_size_t) == sizeof(tb_uint64_t)); return tb_element_hash_uint64((tb_uint64_t)data, mask, index); #else tb_assert_static(sizeof(tb_size_t) == sizeof(tb_uint32_t)); return tb_element_hash_uint32((tb_uint32_t)data, mask, index); #endif }
tb_bool_t tb_async_transfer_init_istream_from_url(tb_async_transfer_ref_t transfer, tb_char_t const* url) { // check tb_async_transfer_impl_t* impl = (tb_async_transfer_impl_t*)transfer; tb_assert_and_check_return_val(impl && impl->aicp && url, tb_false); // muse be closed tb_assert_and_check_return_val(TB_STATE_CLOSED == tb_atomic_get(&impl->state), tb_false); // check stream type if (impl->istream) { // probe protocol tb_size_t protocol = tb_url_protocol_probe(url); tb_assert_static((tb_size_t)TB_URL_PROTOCOL_FILE == (tb_size_t)TB_STREAM_TYPE_FILE); tb_assert_static((tb_size_t)TB_URL_PROTOCOL_HTTP == (tb_size_t)TB_STREAM_TYPE_HTTP); tb_assert_static((tb_size_t)TB_URL_PROTOCOL_SOCK == (tb_size_t)TB_STREAM_TYPE_SOCK); tb_assert_static((tb_size_t)TB_URL_PROTOCOL_DATA == (tb_size_t)TB_STREAM_TYPE_DATA); // protocol => type tb_size_t type = protocol; if (!type || type > TB_STREAM_TYPE_DATA) { tb_trace_e("unknown stream for url: %s", url); return tb_false; } // exit the previous stream first if be different stream type if (tb_async_stream_type(impl->istream) != type) { if (impl->iowner) tb_async_stream_exit(impl->istream); impl->istream = tb_null; } } // using the previous stream? if (impl->istream) { // ctrl stream if (!tb_async_stream_ctrl(impl->istream, TB_STREAM_CTRL_SET_URL, url)) return tb_false; } else { // init stream impl->istream = tb_async_stream_init_from_url(impl->aicp, url); tb_assert_and_check_return_val(impl->istream, tb_false); // init owner impl->iowner = 1; } // ok return tb_true; }
tb_long_t tb_file_pwritv(tb_file_ref_t file, tb_iovec_t const* list, tb_size_t size, tb_hize_t offset) { // check tb_assert_and_check_return_val(file && list && size, -1); // check iovec tb_assert_static(sizeof(tb_iovec_t) == sizeof(struct iovec)); tb_assert(tb_memberof_eq(tb_iovec_t, data, struct iovec, iov_base)); tb_assert(tb_memberof_eq(tb_iovec_t, size, struct iovec, iov_len)); // writ it #ifdef TB_CONFIG_POSIX_HAVE_PWRITEV return pwritev(tb_file2fd(file), (struct iovec const*)list, size, offset); #else // FIXME: lock it // save offset tb_hong_t current = tb_file_offset(file); tb_assert_and_check_return_val(current >= 0, -1); // seek it if (current != offset && tb_file_seek(file, offset, TB_FILE_SEEK_BEG) != offset) return -1; // writ it tb_long_t real = tb_file_writv(file, list, size); // restore offset if (current != offset && tb_file_seek(file, current, TB_FILE_SEEK_BEG) != current) return -1; // ok return real; #endif }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_void_t gb_round_rect_make(gb_round_rect_ref_t rect, gb_rect_ref_t bounds, gb_vector_t radius[]) { // check tb_assert(rect && bounds && radius); tb_assert_static(GB_RECT_CORNER_MAXN == 4); // make it rect->radius[0] = radius[0]; rect->radius[1] = radius[1]; rect->radius[2] = radius[2]; rect->radius[3] = radius[3]; }
tb_long_t tb_file_writv(tb_file_ref_t file, tb_iovec_t const* list, tb_size_t size) { // check tb_assert_and_check_return_val(file && list && size, -1); // check iovec tb_assert_static(sizeof(tb_iovec_t) == sizeof(struct iovec)); tb_assert(tb_memberof_eq(tb_iovec_t, data, struct iovec, iov_base)); tb_assert(tb_memberof_eq(tb_iovec_t, size, struct iovec, iov_len)); // writ it return writev(tb_file2fd(file), (struct iovec const*)list, size); }
tb_void_t gb_round_rect_make_same(gb_round_rect_ref_t rect, gb_rect_ref_t bounds, gb_float_t rx, gb_float_t ry) { // check tb_assert(rect && bounds); tb_assert_static(GB_RECT_CORNER_MAXN == 4); // the radius gb_vector_t radius; gb_vector_make(&radius, rx, ry); // make it rect->radius[0] = radius; rect->radius[1] = radius; rect->radius[2] = radius; rect->radius[3] = radius; rect->bounds = *bounds; }
// the once function static tb_bool_t tb_thread_local_once(tb_cpointer_t priv) { // check tb_value_ref_t tuple = (tb_value_ref_t)priv; tb_check_return_val(tuple, tb_false); // the thread local tb_thread_local_ref_t local = (tb_thread_local_ref_t)tuple[0].ptr; tb_check_return_val(local, tb_false); // save the free function local->free = (tb_thread_local_free_t)tuple[1].ptr; // check the pthread key space size tb_assert_static(sizeof(pthread_key_t) * 2 <= sizeof(local->priv)); // create the pthread key for data tb_bool_t ok = pthread_key_create(&((pthread_key_t*)local->priv)[0], tb_null) == 0; if (ok) { // create the pthread key for mark ok = pthread_key_create(&((pthread_key_t*)local->priv)[1], tb_null) == 0; // failed? remove the data key if (!ok) pthread_key_delete(((pthread_key_t*)local->priv)[0]); } // save this thread local to list if ok if (ok) { tb_spinlock_enter(&g_thread_local_lock); tb_single_list_entry_insert_tail(&g_thread_local_list, &local->entry); tb_spinlock_leave(&g_thread_local_lock); } // init ok local->inited = tb_true; // ok? return ok; }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_bool_t tb_init_(tb_handle_t priv, tb_allocator_ref_t allocator, tb_size_t mode, tb_hize_t build) { // have been inited? if (TB_STATE_OK == tb_atomic_fetch_and_pset(&g_state, TB_STATE_END, TB_STATE_OK)) return tb_true; // init trace if (!tb_trace_init()) return tb_false; // trace tb_trace_d("init: .."); // check mode if (!tb_check_mode(mode)) return tb_false; // check types tb_assert_static(sizeof(tb_byte_t) == 1); tb_assert_static(sizeof(tb_uint_t) == 4); tb_assert_static(sizeof(tb_uint8_t) == 1); tb_assert_static(sizeof(tb_uint16_t) == 2); tb_assert_static(sizeof(tb_uint32_t) == 4); tb_assert_static(sizeof(tb_hize_t) == 8); tb_assert_static(sizeof(tb_wchar_t) == sizeof(L'w')); tb_assert_static(TB_CPU_BITSIZE == (sizeof(tb_size_t) << 3)); tb_assert_static(TB_CPU_BITSIZE == (sizeof(tb_long_t) << 3)); tb_assert_static(TB_CPU_BITSIZE == (sizeof(tb_pointer_t) << 3)); tb_assert_static(TB_CPU_BITSIZE == (sizeof(tb_handle_t) << 3)); // check byteorder tb_assert_and_check_return_val(tb_check_order_word(), tb_false); tb_assert_and_check_return_val(tb_check_order_double(), tb_false); // init singleton if (!tb_singleton_init()) return tb_false; // init memory envirnoment if (!tb_memory_init_env(allocator)) return tb_false; // init platform envirnoment if (!tb_platform_init_env(priv)) return tb_false; // init libc envirnoment if (!tb_libc_init_env()) return tb_false; // init math envirnoment if (!tb_math_init_env()) return tb_false; // init libm envirnoment if (!tb_libm_init_env()) return tb_false; // init network envirnoment if (!tb_network_init_env()) return tb_false; // init object envirnoment #ifdef TB_CONFIG_MODULE_HAVE_OBJECT if (!tb_object_init_env()) return tb_false; #endif // check version tb_version_check(build); // trace tb_trace_d("init: ok"); // ok return tb_true; }
static tb_size_t tb_ifaddrs_netlink_ipaddr_save(tb_ipaddr_ref_t ipaddr, tb_size_t family, tb_size_t scope_id, tb_cpointer_t saddr) { // check tb_assert_and_check_return_val(ipaddr && saddr, 0); // clear address tb_ipaddr_clear(ipaddr); // done tb_size_t size = 0; switch (family) { case AF_INET: { // the ipv4 ipaddr struct in_addr* addr4 = (struct in_addr*)saddr; // save family tb_ipaddr_family_set(ipaddr, TB_IPADDR_FAMILY_IPV4); // make ipv4 tb_ipv4_t ipv4; ipv4.u32 = (tb_uint32_t)addr4->s_addr; // save ipv4 tb_ipaddr_ipv4_set(ipaddr, &ipv4); // save size size = sizeof(struct in_addr); } break; case AF_INET6: { // the ipv6 ipaddr struct in6_addr* addr6 = (struct in6_addr*)saddr; // check tb_assert_static(sizeof(ipaddr->u.ipv6.addr.u8) == sizeof(addr6->s6_addr)); tb_assert_static(tb_arrayn(ipaddr->u.ipv6.addr.u8) == tb_arrayn(addr6->s6_addr)); // save family tb_ipaddr_family_set(ipaddr, TB_IPADDR_FAMILY_IPV6); // make ipv6 tb_ipv6_t ipv6; tb_memcpy(ipv6.addr.u8, addr6->s6_addr, sizeof(ipv6.addr.u8)); // save scope id ipv6.scope_id = 0; if (IN6_IS_ADDR_LINKLOCAL(addr6) || IN6_IS_ADDR_MC_LINKLOCAL(addr6)) ipv6.scope_id = (tb_uint32_t)scope_id; // save ipv6 tb_ipaddr_ipv6_set(ipaddr, &ipv6); // save size size = sizeof(struct in6_addr); } break; default: tb_assert(0); break; } // ok? return size; }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_bool_t tb_init_(tb_handle_t priv, tb_allocator_ref_t allocator, tb_byte_t* data, tb_size_t size, tb_size_t mode, tb_hize_t build) { // is inited? if (tb_atomic_fetch_and_inc(&g_init)) return tb_true; // init trace if (!tb_trace_init()) return tb_false; // trace tb_trace_d("init: %p %lu", data, size); // check mode if (!tb_check_mode(mode)) return tb_false; // check types tb_assert_static(sizeof(tb_byte_t) == 1); tb_assert_static(sizeof(tb_uint_t) == 4); tb_assert_static(sizeof(tb_uint8_t) == 1); tb_assert_static(sizeof(tb_uint16_t) == 2); tb_assert_static(sizeof(tb_uint32_t) == 4); tb_assert_static(sizeof(tb_hize_t) == 8); tb_assert_static(sizeof(tb_wchar_t) == sizeof(L'w')); tb_assert_static(TB_CPU_BITSIZE == (sizeof(tb_size_t) << 3)); tb_assert_static(TB_CPU_BITSIZE == (sizeof(tb_long_t) << 3)); tb_assert_static(TB_CPU_BITSIZE == (sizeof(tb_pointer_t) << 3)); tb_assert_static(TB_CPU_BITSIZE == (sizeof(tb_handle_t) << 3)); // check byteorder tb_assert_and_check_return_val(tb_check_order_word(), tb_false); tb_assert_and_check_return_val(tb_check_order_double(), tb_false); // init singleton if (!tb_singleton_init()) return tb_false; // init memory if (!tb_memory_init(allocator, data, size)) return tb_false; // init platform if (!tb_platform_init(priv)) return tb_false; // init libc if (!tb_libc_init()) return tb_false; // init math if (!tb_math_init()) return tb_false; // init libm if (!tb_libm_init()) return tb_false; // init network if (!tb_network_init()) return tb_false; // init object #ifdef TB_CONFIG_MODULE_HAVE_OBJECT if (!tb_object_context_init()) return tb_false; #endif // check version tb_version_check(build); // trace tb_trace_d("init: ok"); // ok return tb_true; }