예제 #1
0
파일: tbox.c 프로젝트: waruqi/tbox
static __tb_inline__ tb_bool_t tb_check_mode(tb_size_t mode)
{
#ifdef __tb_debug__
    if (!(mode & TB_MODE_DEBUG))
    {
        tb_trace_e("libtbox.a has __tb_debug__ but tbox/tbox.h not");
        return tb_false;
    }
#else
    if (mode & TB_MODE_DEBUG)
    {
        tb_trace_e("tbox/tbox.h has __tb_debug__ but libtbox.a not");
        return tb_false;
    }
#endif

#ifdef __tb_small__
    if (!(mode & TB_MODE_SMALL))
    {
        tb_trace_e("libtbox.a has __tb_small__ but tbox/tbox.h not");
        return tb_false;
    }
#else
    if (mode & TB_MODE_SMALL)
    {
        tb_trace_e("tbox/tbox.h has __tb_small__ but libtbox.a not");
        return tb_false;
    }
#endif

    // ok
    return tb_true;
}
예제 #2
0
파일: semaphore.c 프로젝트: 1060460048/tbox
/* //////////////////////////////////////////////////////////////////////////////////////
 * thread
 */
static tb_char_t const* tb_demo_gets(tb_char_t* line, tb_size_t maxn)
{
    // check
    tb_assert_and_check_return_val(line && maxn, tb_null);

    // done
    tb_char_t* p = line;
    tb_char_t* e = line + maxn;
    while (p < e)
    {
        // get character
        tb_char_t ch = getchar(); if (ch == '\r') getchar();
        tb_check_break(ch != '\r' && ch != '\n');

        // append digit
        if (tb_isdigit(ch)) *p++ = ch;
        else
        {
            // trace
            tb_trace_e("invalid character: %x, please input digit!", ch);
        }
    }

    // end
    if (p < e) *p = '\0';

    // ok?
    return line;
}
예제 #3
0
파일: exception.c 프로젝트: waruqi/tbox
static tb_void_t tb_exception_signal_func(tb_int_t sig)
{
    tb_stack_ref_t stack = (tb_stack_ref_t)tb_thread_local_get(&g_exception_local);
    if (stack && tb_stack_size(stack)) 
    {
#if defined(tb_sigsetjmp) && defined(tb_siglongjmp)
        tb_sigjmpbuf_t* jmpbuf = (tb_sigjmpbuf_t*)tb_stack_top(stack);
        if (jmpbuf) tb_siglongjmp(*jmpbuf, 1);
#else
        tb_jmpbuf_t* jmpbuf = (tb_jmpbuf_t*)tb_stack_top(stack);
        if (jmpbuf) tb_longjmp(*jmpbuf, 1);
#endif
    }
    else 
    {
        // trace
        tb_trace_e("exception: no handler for signal: %d", sig);

        // ignore signal
        tb_signal(TB_SIGILL, TB_SIG_DFL);
        tb_signal(TB_SIGFPE, TB_SIG_DFL);
        tb_signal(TB_SIGBUS, TB_SIG_DFL);
        tb_signal(TB_SIGSEGV, TB_SIG_DFL);
        tb_signal(TB_SIGABRT, TB_SIG_DFL);

#ifdef TB_CONFIG_LIBC_HAVE_KILL
        // kill it
        kill(getpid(), sig);
#endif
    }
}
예제 #4
0
파일: aicp.c 프로젝트: DonkeyWs/tbox
/* //////////////////////////////////////////////////////////////////////////////////////
 * private implementation
 */
static tb_bool_t tb_aicp_walk_wait(tb_pointer_t item, tb_cpointer_t priv)
{
    // check
    tb_aico_impl_t* aico = (tb_aico_impl_t*)item;
    tb_assert_and_check_return_val(aico, tb_false);

    // trace
#ifdef __tb_debug__
    tb_trace_e("aico[%p]: wait exited failed, type: %lu, handle: %p, state: %s for func: %s, line: %lu, file: %s", aico, tb_aico_type((tb_aico_ref_t)aico), aico->handle, tb_state_cstr(tb_atomic_get(&aico->state)), aico->func, aico->line, aico->file);
#else
    tb_trace_e("aico[%p]: wait exited failed, type: %lu, handle: %p, state: %s", aico, tb_aico_type((tb_aico_ref_t)aico), aico->handle, tb_state_cstr(tb_atomic_get(&aico->state)));
#endif

    // ok
    return tb_true;
}
예제 #5
0
tb_pointer_t tb_static_pool_ralloc_(tb_static_pool_ref_t pool, tb_pointer_t data, tb_size_t size __tb_debug_decl__)
{
    // check
    tb_assert_and_check_return_val(pool && data && size, tb_null);
    tb_assert_and_check_return_val(size <= TB_POOL_DATA_SIZE_MAXN, tb_null);

    // ralloc data
    tb_pointer_t data_new = tb_static_large_pool_ralloc(pool, data, size, tb_null __tb_debug_args__);

    // failed? dump it
#ifdef __tb_debug__
    if (!data_new) 
    {
        // trace
        tb_trace_e("ralloc(%p, %lu) failed! at %s(): %lu, %s", data, size, func_, line_, file_);

        // dump data
        tb_pool_data_dump((tb_byte_t const*)data, tb_true, "[static_pool]: [error]: ");

        // abort
        tb_abort();
    }
#endif

    // check
    tb_assertf_abort(!(((tb_size_t)data_new) & (TB_POOL_DATA_ALIGN - 1)), "ralloc(%lu): unaligned data: %p", size, data);

    // ok
    return data_new;
}
예제 #6
0
tb_bool_t tb_static_pool_free_(tb_static_pool_ref_t pool, tb_pointer_t data __tb_debug_decl__)
{
    // check
    tb_assert_and_check_return_val(pool && data, tb_false);

    // free data
    tb_bool_t ok = tb_static_large_pool_free(pool, data __tb_debug_args__);

    // failed? dump it
#ifdef __tb_debug__
    if (!ok) 
    {
        // trace
        tb_trace_e("free(%p) failed! at %s(): %lu, %s", data, func_, line_, file_);

        // dump data
        tb_pool_data_dump((tb_byte_t const*)data, tb_true, "[static_pool]: [error]: ");

        // abort
        tb_abort();
    }
#endif

    // ok
    return ok;
}
예제 #7
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
static tb_bool_t tb_aiop_rtor_epoll_addo(tb_aiop_rtor_impl_t* rtor, tb_aioo_impl_t const* aioo)
{
    // 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 && aioo && aioo->sock, tb_false);

    // the code
    tb_size_t code = aioo->code;

    // init event
    struct epoll_event e = {0};
    if (code & TB_AIOE_CODE_RECV || code & TB_AIOE_CODE_ACPT) e.events |= EPOLLIN;
    if (code & TB_AIOE_CODE_SEND || code & TB_AIOE_CODE_CONN) e.events |= EPOLLOUT;
    if (code & TB_AIOE_CODE_CLEAR) e.events |= EPOLLET;
#ifdef EPOLLONESHOT 
    if (code & TB_AIOE_CODE_ONESHOT) e.events |= EPOLLONESHOT;
#endif
    e.data.u64 = tb_p2u64(aioo);

    // add aioo
    if (epoll_ctl(impl->epfd, EPOLL_CTL_ADD, tb_sock2fd(aioo->sock), &e) < 0)
    {
        // trace
        tb_trace_e("addo aioo[%p], code: %lu failed, errno: %d", aioo, code, errno);
        return tb_false;
    }

    // ok
    return tb_true;
}
예제 #8
0
파일: skia.cpp 프로젝트: AlexShiLucky/gbox
static tb_void_t gb_device_skia_draw_path(gb_device_impl_t* device, gb_path_ref_t path)
{
    // check
    gb_skia_device_ref_t impl = (gb_skia_device_ref_t)device;
    tb_assert_and_check_return(impl && impl->canvas && impl->path && path);

    // apply matrix
	gb_device_skia_apply_matrix(impl);

    // apply paint
    gb_device_skia_apply_paint(impl);

    // clear path
    impl->path->reset();

    // init the path fill type
    tb_size_t rule = gb_paint_fill_rule(impl->base.paint);
    switch (rule)
    {
    case GB_PAINT_FILL_RULE_ODD:
        impl->path->setFillType(SkPath::kEvenOdd_FillType);
        break;
    case GB_PAINT_FILL_RULE_NONZERO:
        impl->path->setFillType(SkPath::kWinding_FillType);
        break;
    default:
        break;
    }

    // done
    tb_for_all_if (gb_path_item_ref_t, item, path, item)
    {
        switch (item->code)
        {
        case GB_PATH_CODE_MOVE:
            impl->path->moveTo(gb_float_to_sk(item->points[0].x), gb_float_to_sk(item->points[0].y));
            break;
        case GB_PATH_CODE_LINE:
            impl->path->lineTo(gb_float_to_sk(item->points[1].x), gb_float_to_sk(item->points[1].y));
            break;
        case GB_PATH_CODE_QUAD:
            impl->path->quadTo(gb_float_to_sk(item->points[1].x), gb_float_to_sk(item->points[1].y), gb_float_to_sk(item->points[2].x), gb_float_to_sk(item->points[2].y));
            break;
        case GB_PATH_CODE_CUBIC:
            impl->path->cubicTo(gb_float_to_sk(item->points[1].x), gb_float_to_sk(item->points[1].y), gb_float_to_sk(item->points[2].x), gb_float_to_sk(item->points[2].y), gb_float_to_sk(item->points[3].x), gb_float_to_sk(item->points[3].y));
            break;
        case GB_PATH_CODE_CLOS:
            impl->path->close();
            break;
        default:
            // trace
            tb_trace_e("invalid code: %lu", item->code);
            break;
        }
    }

    // draw it
    impl->canvas->drawPath(*impl->path, *impl->paint);
}
예제 #9
0
파일: aicp_aiop.c 프로젝트: RockyShi/tbox
static tb_void_t tb_aiop_ptor_exit(tb_aicp_ptor_impl_t* ptor)
{
    // check
    tb_aiop_ptor_impl_t* impl = (tb_aiop_ptor_impl_t*)ptor;
    tb_assert_and_check_return(impl);

    // trace
    tb_trace_d("exit");

    // exit file
    tb_aicp_file_exit(impl);

    // exit loop
    if (impl->loop)
    {
        tb_long_t wait = 0;
        if ((wait = tb_thread_wait(impl->loop, 5000)) <= 0)
        {
            // trace
            tb_trace_e("loop[%p]: wait failed: %ld!", impl->loop, wait);
        }
        tb_thread_exit(impl->loop);
        impl->loop = tb_null;
    }

    // exit spak
    tb_spinlock_enter(&impl->lock);
    if (impl->spak[0]) tb_queue_exit(impl->spak[0]);
    if (impl->spak[1]) tb_queue_exit(impl->spak[1]);
    impl->spak[0] = tb_null;
    impl->spak[1] = tb_null;
    tb_spinlock_leave(&impl->lock);

    // exit aiop
    if (impl->aiop) tb_aiop_exit(impl->aiop);
    impl->aiop = tb_null;

    // exit list
    if (impl->list) tb_free(impl->list);
    impl->list = tb_null;

    // exit wait
    if (impl->wait) tb_semaphore_exit(impl->wait);
    impl->wait = tb_null;

    // exit timer
    if (impl->timer) tb_timer_exit(impl->timer);
    impl->timer = tb_null;

    // exit ltimer
    if (impl->ltimer) tb_ltimer_exit(impl->ltimer);
    impl->ltimer = tb_null;

    // exit lock
    tb_spinlock_exit(&impl->lock);

    // exit it
    tb_free(impl);
}
예제 #10
0
tb_bool_t tb_transfer_pool_exit(tb_transfer_pool_ref_t pool)
{
    // check
    tb_transfer_pool_impl_t* impl = (tb_transfer_pool_impl_t*)pool;
    tb_assert_and_check_return_val(impl, tb_false);

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

    // kill it first
    tb_transfer_pool_kill(pool);

    // wait all
    if (tb_transfer_pool_wait_all(pool, 5000) <= 0)
    {
        // trace
        tb_trace_e("exit: wait failed!");
        return tb_false;
    }

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

    // check
    tb_assert(!tb_list_entry_size(&impl->work));

    // exit the work list
    tb_list_entry_exit(&impl->work);

    // exit the idle list
    tb_list_entry_exit(&impl->idle);

    // exit pool
    if (impl->pool) 
    {
        // exit all task
        tb_fixed_pool_walk(impl->pool, tb_transfer_pool_walk_exit, tb_null);

        // exit it
        tb_fixed_pool_exit(impl->pool);
        impl->pool = tb_null;
    }

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

    // exit lock
    tb_spinlock_exit(&impl->lock);

    // exit it
    tb_free(pool);

    // trace
    tb_trace_d("exit: ok");
    
    // ok
    return tb_true;
}
예제 #11
0
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;
}
예제 #12
0
tb_bool_t tb_small_pool_free_(tb_small_pool_ref_t pool, tb_pointer_t data __tb_debug_decl__)
{
    // check
    tb_small_pool_impl_t* impl = (tb_small_pool_impl_t*)pool;
    tb_assert_and_check_return_val(impl && impl->large_pool && data, tb_false);

    // disable small pool for debug
#ifdef TB_SMALL_POOL_DISABLE
    return tb_large_pool_free(impl->large_pool, data);
#endif

    // done
    tb_bool_t ok = tb_false;
    do
    {
        // the data head
        tb_pool_data_head_t* data_head = &(((tb_pool_data_head_t*)data)[-1]);
        tb_assertf_break(data_head->debug.magic == TB_POOL_DATA_MAGIC, "free invalid data: %p", data);

        // the fixed pool
        tb_fixed_pool_ref_t fixed_pool = tb_small_pool_find_fixed(impl, data_head->size);
        tb_assert_and_check_break(fixed_pool);

        // the data space
        tb_size_t space = tb_fixed_pool_item_size(fixed_pool);
        tb_assert_and_check_break(space >= data_head->size);

        // check underflow
        tb_assertf_break(space == data_head->size || ((tb_byte_t*)data)[data_head->size] == TB_POOL_DATA_PATCH, "data underflow");

        // done
        ok = tb_fixed_pool_free_(fixed_pool, data __tb_debug_args__);

    } while (0);

    // failed? dump it
#ifdef __tb_debug__
    if (!ok) 
    {
        // trace
        tb_trace_e("free(%p) failed! at %s(): %lu, %s", data, func_, line_, file_);

        // dump data
        tb_pool_data_dump((tb_byte_t const*)data, tb_true, "[small_pool]: [error]: ");

        // abort
        tb_abort();
    }
#endif

    // ok?
    return ok;
}
예제 #13
0
tb_bool_t tb_aicp_post_(tb_aicp_ref_t aicp, tb_aice_ref_t aice __tb_debug_decl__)
{
    // check
    tb_aicp_impl_t* impl = (tb_aicp_impl_t*)aicp;
    tb_assert_and_check_return_val(impl && impl->ptor && impl->ptor->post, tb_false);
    tb_assert_and_check_return_val(aice && aice->aico, tb_false);

    // the aico
    tb_aico_impl_t* aico = (tb_aico_impl_t*)aice->aico;
    tb_assert_and_check_return_val(aico, tb_false);

    // opened or killed or closed? pending it
    tb_size_t state = tb_atomic_fetch_and_pset(&aico->state, TB_STATE_OPENED, TB_STATE_PENDING);
    if (state == TB_STATE_OPENED || state == TB_STATE_KILLED)
    {
        // save debug info
#ifdef __tb_debug__
        aico->func = func_;
        aico->file = file_;
        aico->line = line_;
#endif

        // post aice
        return impl->ptor->post(impl->ptor, aice);
    }

    // trace
#ifdef __tb_debug__
    tb_trace_e("post aice[%lu] failed, the aico[%p]: type: %lu, handle: %p, state: %s for func: %s, line: %lu, file: %s", aice->code, aico, tb_aico_type((tb_aico_ref_t)aico), aico->handle, tb_state_cstr(state), func_, line_, file_);
#else
    tb_trace_e("post aice[%lu] failed, the aico[%p]: type: %lu, handle: %p, state: %s", aice->code, aico, tb_aico_type((tb_aico_ref_t)aico), aico->handle, tb_state_cstr(state));
#endif

    // abort it
    tb_assert(0);

    // post failed
    return tb_false;
}
예제 #14
0
static tb_bool_t tb_aiop_rtor_epoll_post(tb_aiop_rtor_impl_t* rtor, tb_aioe_ref_t aioe)
{
    // 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 && aioe, tb_false);

    // the code
    tb_size_t       code = aioe->code;

    // the priv
    tb_cpointer_t   priv = aioe->priv;

    // the aioo
    tb_aioo_impl_t* aioo = (tb_aioo_impl_t*)aioe->aioo;
    tb_assert_and_check_return_val(aioo && aioo->sock, tb_false);

    // init event
    struct epoll_event e = {0};
    if (code & TB_AIOE_CODE_RECV || code & TB_AIOE_CODE_ACPT) e.events |= EPOLLIN;
    if (code & TB_AIOE_CODE_SEND || code & TB_AIOE_CODE_CONN) e.events |= EPOLLOUT;
    if (code & TB_AIOE_CODE_CLEAR) e.events |= EPOLLET;
#ifdef EPOLLONESHOT 
    if (code & TB_AIOE_CODE_ONESHOT) e.events |= EPOLLONESHOT;
#endif
    e.data.u64 = tb_p2u64(aioo);

    // save aioo
    tb_aioo_impl_t prev = *aioo;
    aioo->code = code;
    aioo->priv = priv;

    // sete
    if (epoll_ctl(impl->epfd, EPOLL_CTL_MOD, tb_sock2fd(aioo->sock), &e) < 0) 
    {
        // re-add it 
#ifndef EPOLLONESHOT 
        if (errno == ENOENT && epoll_ctl(impl->epfd, EPOLL_CTL_ADD, tb_sock2fd(aioo->sock), &e) >= 0) 
            return tb_true;
#endif

        // trace
        tb_trace_e("post aice code: %lu failed, errno: %d", code, errno);

        // restore aioo
        *aioo = prev;
        return tb_false;
    }

    // ok
    return tb_true;
}
예제 #15
0
파일: sqlite3.c 프로젝트: ljx0305/tbox
/* //////////////////////////////////////////////////////////////////////////////////////
 * library implementation
 */
static tb_handle_t tb_database_sqlite3_library_init(tb_cpointer_t* ppriv)
{
    // init it
    tb_int_t ok = SQLITE_OK;
    if ((ok = sqlite3_initialize()) != SQLITE_OK)
    {
        // trace
        tb_trace_e("init: sqlite3 library failed, error: %d", ok);
        return tb_null;
    }

    // ok
    return ppriv;
}
예제 #16
0
파일: pool.c 프로젝트: KeplerGods/tbox
tb_bool_t tb_pool_free_(tb_pool_ref_t pool, tb_pointer_t data __tb_debug_decl__)
{
    // check
    tb_pool_impl_t* impl = (tb_pool_impl_t*)pool;
    tb_assert_and_check_return_val(impl, tb_false);
 
    // uses allocator?
    if (impl->allocator) return tb_allocator_free_(impl->allocator, data __tb_debug_args__);

    // check
    tb_assert_and_check_return_val(impl->large_pool && impl->small_pool && data, tb_false);

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

    // done
    tb_bool_t ok = tb_false;
    do
    {
        // the data head
        tb_pool_data_head_t* data_head = &(((tb_pool_data_head_t*)data)[-1]);
        tb_assertf_break(data_head->debug.magic == TB_POOL_DATA_MAGIC, "free invalid data: %p", data);

        // free it
        ok = (data_head->size <= TB_SMALL_POOL_DATA_SIZE_MAXN)? tb_small_pool_free_(impl->small_pool, data __tb_debug_args__) : tb_large_pool_free_(impl->large_pool, data __tb_debug_args__);

    } while (0);

    // failed? dump it
#ifdef __tb_debug__
    if (!ok) 
    {
        // trace
        tb_trace_e("free(%p) failed! at %s(): %lu, %s", data, func_, line_, file_);

        // dump data
        tb_pool_data_dump((tb_byte_t const*)data, tb_true, "[pool]: [error]: ");

        // abort
        tb_abort();
    }
#endif

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

    // ok?
    return ok;
}
예제 #17
0
파일: aiop.c 프로젝트: AlexShiLucky/tbox
tb_void_t tb_aiop_delo(tb_aiop_ref_t aiop, tb_aioo_ref_t aioo)
{
    // check
    tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
    tb_assert_and_check_return(impl && impl->rtor && impl->rtor->delo && aioo);

    // delete aioo from aiop
    if (!impl->rtor->delo(impl->rtor, (tb_aioo_impl_t*)aioo))
    {
        // trace
        tb_trace_e("delo: aioo[%p] failed!", aioo);
    }
    
    // exit aioo
    tb_aiop_aioo_exit(impl, aioo);
}
예제 #18
0
tb_bool_t tb_async_transfer_exit(tb_async_transfer_ref_t transfer)
{
    // chec:w
    tb_async_transfer_impl_t* impl = (tb_async_transfer_impl_t*)transfer;
    tb_assert_and_check_return_val(impl, tb_false);

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

    // kill it first
    tb_async_transfer_kill(transfer);

    // try closing it
    tb_size_t tryn = 30;
    tb_bool_t ok = tb_false;
    while (!(ok = tb_async_transfer_clos_try(transfer)) && tryn--)
    {
        // wait some time
        tb_msleep(200);
    }

    // close failed?
    if (!ok)
    {
        // trace
        tb_trace_e("exit: failed!");
        return tb_false;
    }

    // exit istream
    if (impl->istream && impl->iowner) tb_async_stream_exit(impl->istream);
    impl->istream = tb_null;

    // exit ostream
    if (impl->ostream && impl->oowner) tb_async_stream_exit(impl->ostream);
    impl->ostream = tb_null;

    // exit impl
    tb_free(impl);

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

    // ok
    return tb_true;
}
예제 #19
0
파일: sqlite3.c 프로젝트: ljx0305/tbox
static tb_bool_t tb_database_sqlite3_open(tb_database_sql_impl_t* database)
{
    // check
    tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
    tb_assert_and_check_return_val(sqlite, tb_false);

    // done
    tb_bool_t           ok = tb_false;
    tb_char_t const*    path = tb_null;
    do
    {
        // the database path
        path = tb_url_cstr(&database->url);
        tb_assert_and_check_break(path);

        // load sqlite3 library
        if (!tb_database_sqlite3_library_load()) break;

        // open database
        if (SQLITE_OK != sqlite3_open_v2(path, &sqlite->database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, tb_null) || !sqlite->database) 
        {
            // error
            if (sqlite->database) 
            {
                // save state
                sqlite->base.state = tb_database_sqlite3_state_from_errno(sqlite3_errcode(sqlite->database));

                // trace
                tb_trace_e("open: %s failed, error[%d]: %s", path, sqlite3_errcode(sqlite->database), sqlite3_errmsg(sqlite->database));
            }
            break;
        }

        // ok
        ok = tb_true;

    } while (0);

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

    // ok?
    return ok;
}
예제 #20
0
파일: sqlite3.c 프로젝트: ljx0305/tbox
static tb_bool_t tb_database_sqlite3_rollback(tb_database_sql_impl_t* database)
{
    // check
    tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
    tb_assert_and_check_return_val(sqlite && sqlite->database, tb_false);

    // done rollback
    if (SQLITE_OK != sqlite3_exec(sqlite->database, "rollback;", tb_null, tb_null, tb_null))
    {
        // save state
        sqlite->base.state = tb_database_sqlite3_state_from_errno(sqlite3_errcode(sqlite->database));

        // trace
        tb_trace_e("rollback: failed, error[%d]: %s", sqlite3_errcode(sqlite->database), sqlite3_errmsg(sqlite->database));
        return tb_false;
    }

    // ok
    return tb_true;
}
예제 #21
0
파일: sqlite3.c 프로젝트: ljx0305/tbox
static tb_database_sql_statement_ref_t tb_database_sqlite3_statement_init(tb_database_sql_impl_t* database, tb_char_t const* sql)
{
    // check
    tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database);
    tb_assert_and_check_return_val(sqlite && sqlite->database && sql, tb_null);

    // init statement
    sqlite3_stmt* statement = tb_null;
    if (SQLITE_OK != sqlite3_prepare_v2(sqlite->database, sql, -1, &statement, 0))
    {
        // save state
        sqlite->base.state = tb_database_sqlite3_state_from_errno(sqlite3_errcode(sqlite->database));

        // trace
        tb_trace_e("statement: init %s failed, error[%d]: %s", sql, sqlite3_errcode(sqlite->database), sqlite3_errmsg(sqlite->database));
    }

    // ok?
    return (tb_database_sql_statement_ref_t)statement;
}
예제 #22
0
tb_void_t tb_static_fixed_pool_dump(tb_static_fixed_pool_ref_t self)
{
    // check
    tb_static_fixed_pool_t* pool = (tb_static_fixed_pool_t*)self;
    tb_assert_and_check_return(pool && pool->used_info);

    // dump 
    tb_size_t index = 0;
    for (index = 0; index < pool->item_maxn; ++index)
    {
        // leak?
        if (tb_static_fixed_pool_used_bset(pool->used_info, index)) 
        {
            // the data head
            tb_pool_data_empty_head_t* data_head = (tb_pool_data_empty_head_t*)(pool->data + index * pool->item_space);

            // check it
            tb_static_fixed_pool_check_data(pool, data_head);

            // the data
            tb_byte_t const* data = (tb_byte_t const*)data_head + pool->data_head_size;

            // trace
            tb_trace_e("leak: %p", data);

            // dump data
            tb_pool_data_dump(data, tb_false, "[static_fixed_pool]: [error]: ");
        }
    }

    // trace debug info
    tb_trace_i("[%lu]: peak_size: %lu, wast_rate: %llu/10000, pred_failed: %lu, item_maxn: %lu, free_count: %lu, malloc_count: %lu"
            ,   pool->item_size
            ,   pool->peak_size
            ,   pool->occupied_size? (((tb_hize_t)pool->occupied_size - pool->real_size) * 10000) / (tb_hize_t)pool->occupied_size : 0
            ,   pool->pred_failed
            ,   pool->item_maxn
            ,   pool->free_count
            ,   pool->malloc_count);

}
예제 #23
0
파일: sql.c 프로젝트: richwu/tbox
/* //////////////////////////////////////////////////////////////////////////////////////
 * test
 */
static tb_void_t tb_demo_database_sql_test_done(tb_database_sql_ref_t database, tb_char_t const* sql)
{
    // check
    tb_assert_and_check_return(database && sql);

    // done
    do
    {
        // done sql
        if (!tb_database_sql_done(database, sql))
        {
            // trace
            tb_trace_e("done %s failed, error: %s", sql, tb_state_cstr(tb_database_sql_state(database)));
            break ;
        }

        // load result
//      tb_iterator_ref_t result = tb_database_sql_result_load(database, tb_true);
        tb_iterator_ref_t result = tb_database_sql_result_load(database, tb_false);
        tb_check_break(result);

        // trace
        tb_trace_i("==============================================================================");
        tb_trace_i("row: size: %lu", tb_iterator_size(result));

        // walk result
        tb_for_all_if (tb_iterator_ref_t, row, result, row)
        {
            // trace
            tb_tracef_i("[row: %lu, col: size: %lu]: ", row_itor, tb_iterator_size(row));

            // walk items
            tb_for_all_if (tb_database_sql_value_t*, value, row, value)
            {
                // trace
                tb_tracet_i("[%s:%s] ", tb_database_sql_value_name(value), tb_database_sql_value_text(value));
            }

            // trace
            tb_tracet_i(__tb_newline__);
        }
예제 #24
0
파일: spider.c 프로젝트: ahnan4arch/tbox
static tb_bool_t tb_demo_spider_task_save(tb_size_t state, tb_hize_t offset, tb_hong_t size, tb_hize_t save, tb_size_t rate, tb_cpointer_t priv)
{
    // check
    tb_demo_spider_task_t* task = (tb_demo_spider_task_t*)priv;
    tb_assert_and_check_return_val(task && task->spider, tb_false);

    // percent
#ifdef TB_TRACE_DEBUG
    tb_size_t percent = 0;
    if (size > 0) percent = (tb_size_t)((offset * 100) / size);
    else if (state == TB_STATE_OK) percent = 100;

    // trace
    tb_trace_d("save[%s]: %llu, rate: %lu bytes/s, percent: %lu%%, state: %s", task->iurl, save, rate, percent, tb_state_cstr(state));
#endif

    // ok? continue it
    tb_bool_t ok = tb_false;
    if (state == TB_STATE_OK) ok = tb_true;
    // closed?
    else if (state == TB_STATE_CLOSED && TB_STATE_OK == tb_atomic_get(&task->spider->state))
    {
        // trace
        tb_trace_i("task: done: %s: ok", task->iurl);

        // post parser task
        tb_thread_pool_task_post(tb_thread_pool(), "parser_task", tb_demo_spider_parser_task_done, tb_demo_spider_parser_task_exit, task, tb_false);
    }
    // failed or killed?
    else 
    {
        // trace
        tb_trace_e("task: done: %s: %s", task->iurl, tb_state_cstr(state));

        // exit task
        tb_demo_spider_task_exit(task);
    }

    // break or continue?
    return ok;
}
예제 #25
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
static tb_bool_t tb_aiop_rtor_kqueue_sync(tb_aiop_rtor_impl_t* rtor, struct kevent* evts, tb_size_t evtn)
{
    // 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, tb_false);
    tb_assert_and_check_return_val(evts && evtn, tb_false);

    // change events
    struct timespec t = {0};
    if (kevent(impl->kqfd, evts, evtn, tb_null, 0, &t) < 0) 
    {
        // trace
        tb_trace_e("sync failed, errno: %d", errno);

        // failed
        return tb_false;
    }

    // ok
    return tb_true;
}
예제 #26
0
파일: file.c 프로젝트: ljx0305/tbox
tb_bool_t tb_file_exit(tb_file_ref_t file)
{
    // check
    tb_assert_and_check_return_val(file, tb_false);

    // trace
    tb_trace_d("clos: %p", file);

    // close it
    tb_bool_t ok = !close(tb_file2fd(file))? tb_true : tb_false;
    
    // failed?
    if (!ok)
    {
        // trace
        tb_trace_e("close: %p failed, errno: %d", file, errno);
    }

    // ok?
    return ok;
}
예제 #27
0
파일: aiop.c 프로젝트: cdrr/tbox
tb_void_t tb_aiop_spak(tb_aiop_ref_t aiop)
{
    // check
    tb_aiop_impl_t* impl = (tb_aiop_impl_t*)aiop;
    tb_assert_and_check_return(impl);

    // spak it
    if (impl->spak[0]) 
    {
        // post: 'p'
        tb_long_t ok = tb_socket_send(impl->spak[0], (tb_byte_t const*)"p", 1);
        if (ok != 1)
        {
            // trace
            tb_trace_e("spak: failed!");

            // abort it
            tb_assert(0);
        }
    }
}
예제 #28
0
파일: allocator.c 프로젝트: siwuxian/xmake
tb_pointer_t tb_allocator_ralloc_(tb_allocator_ref_t allocator, tb_pointer_t data, tb_size_t size __tb_debug_decl__)
{
    // check
    tb_assert_and_check_return_val(allocator, tb_null);

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

    // ralloc it
    tb_pointer_t data_new = tb_null;
    if (allocator->ralloc) data_new = allocator->ralloc(allocator, data, size __tb_debug_args__);
    else if (allocator->large_ralloc) data_new = allocator->large_ralloc(allocator, data, size, tb_null __tb_debug_args__);

    // trace
    tb_trace_d("ralloc(%p, %lu): %p at %s(): %d, %s", data, size, data_new __tb_debug_args__);

    // failed? dump it
#ifdef __tb_debug__
    if (!data_new) 
    {
        // trace
        tb_trace_e("ralloc(%p, %lu) failed! at %s(): %lu, %s", data, size, func_, line_, file_);

        // dump data
        tb_pool_data_dump((tb_byte_t const*)data, tb_true, "[large_allocator]: [error]: ");

        // abort
        tb_abort();
    }
#endif

    // check
    tb_assertf(!(((tb_size_t)data_new) & (TB_POOL_DATA_ALIGN - 1)), "ralloc(%lu): unaligned data: %p", size, data);

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

    // ok?
    return data_new;
}
예제 #29
0
파일: sqlite3.c 프로젝트: ljx0305/tbox
static tb_size_t tb_database_sqlite3_result_row_iterator_next(tb_iterator_ref_t iterator, tb_size_t itor)
{
    // check
    tb_database_sqlite3_result_t* result = (tb_database_sqlite3_result_t*)iterator;
    tb_assert(result);
    tb_assert_and_check_return_val(itor < result->count, result->count);

    // statement result?
    if (result->statement)
    {
        // step statement
        tb_int_t ok = sqlite3_step(result->statement);

        // end?
        if (ok != SQLITE_ROW) 
        {
            // reset it 
            if (SQLITE_OK != sqlite3_reset(result->statement))
            {
                // the sqlite
                tb_database_sqlite3_t* sqlite = (tb_database_sqlite3_t*)iterator->priv;
                if (sqlite)
                {
                    // save state
                    sqlite->base.state = tb_database_sqlite3_state_from_errno(sqlite3_errcode(sqlite->database));

                    // trace
                    tb_trace_e("statement: reset failed, error[%d]: %s", sqlite3_errcode(sqlite->database), sqlite3_errmsg(sqlite->database));
                }
            }

            // tail
            return result->count;
        }
    }

    // next
    return itor + 1;
}
예제 #30
0
파일: aicp_aiop.c 프로젝트: ZuckerB/tbox
static tb_bool_t tb_aiop_push_sock(tb_aiop_ptor_impl_t* impl, tb_aice_ref_t aice)
{
    // check
    tb_assert_and_check_return_val(impl && aice && aice->aico, tb_false);

    // the priority
    tb_size_t priority = tb_aice_impl_priority(aice);
    tb_assert_and_check_return_val(priority < tb_arrayn(impl->spak) && impl->spak[priority], tb_false);

    // this aico is killed? post to higher priority queue
    if (tb_aico_impl_is_killed((tb_aico_impl_t*)aice->aico)) priority = 0;

    // trace
    tb_trace_d("push: aico: %p, handle: %p, code: %lu, priority: %lu", aice->aico, tb_aico_sock(aice->aico), aice->code, priority);

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

    // not full?
    if (!tb_queue_full(impl->spak[priority]))
    {
        // push aice to the spak queue
        tb_queue_put(impl->spak[priority], aice);

        // wait ok if be not acpt aice
        if (aice->code != TB_AICE_CODE_ACPT) ((tb_aiop_aico_t*)aice->aico)->wait_ok = 1;
    }
    else
    {
        // trace
        tb_trace_e("push: failed, the spak queue is full!");
    }

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

    // ok
    return tb_true;
}