static tb_void_t tb_demo_spider_exit(tb_demo_spider_t* spider) { // check tb_assert_and_check_return(spider); // trace tb_trace_d("exit: .."); // kill it tb_atomic_set(&spider->state, TB_STATE_KILLING); // kill all transfer tasks tb_transfer_pool_kill_all(tb_transfer_pool()); // kill all parser tasks tb_thread_pool_task_kill_all(tb_thread_pool()); // wait all transfer tasks exiting tb_transfer_pool_wait_all(tb_transfer_pool(), -1); // wait all parser tasks exiting tb_thread_pool_task_wait_all(tb_thread_pool(), -1); // enter tb_spinlock_enter(&spider->lock); // exit filter if (spider->filter) tb_bloom_filter_exit(spider->filter); spider->filter = tb_null; // exit pool if (spider->pool) tb_fixed_pool_exit(spider->pool); spider->pool = tb_null; // leave tb_spinlock_leave(&spider->lock); // exit lock tb_spinlock_exit(&spider->lock); // exit home tb_url_exit(&spider->home); // exit option #ifdef TB_CONFIG_MODULE_HAVE_OBJECT if (spider->option) tb_option_exit(spider->option); spider->option = tb_null; #endif // trace tb_trace_d("exit: ok"); }
static tb_void_t tb_database_sqlite3_exit(tb_database_sql_impl_t* database) { // check tb_database_sqlite3_t* sqlite = tb_database_sqlite3_cast(database); tb_assert_and_check_return(sqlite); // close it first tb_database_sqlite3_clos(database); // exit url tb_url_exit(&database->url); // exit it tb_free(sqlite); }
static tb_void_t tb_demo_spider_parser_exit(tb_thread_pool_worker_ref_t worker, tb_cpointer_t priv) { // check tb_demo_spider_parser_t* parser = (tb_demo_spider_parser_t*)priv; tb_assert_and_check_return(parser); // exit stream if (parser->stream) tb_stream_exit(parser->stream); parser->stream = tb_null; // exit reader if (parser->reader) tb_xml_reader_exit(parser->reader); parser->reader = tb_null; // exit cache if (parser->cache) tb_circle_queue_exit(parser->cache); parser->cache = tb_null; // exit iurl tb_url_exit(&parser->iurl); // exit it tb_free(parser); }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_database_sql_ref_t tb_database_sql_init(tb_char_t const* url) { // check tb_assert_and_check_return_val(url, tb_null); // done tb_bool_t ok = tb_false; tb_database_sql_ref_t database = tb_null; tb_url_t database_url; do { // trace tb_trace_d("init: %s: ..", url); // init url if (!tb_url_init(&database_url)) break; // make url if (!tb_url_cstr_set(&database_url, url)) break; // check protocol tb_size_t protocol = tb_url_protocol(&database_url); tb_assert_and_check_break(protocol == TB_URL_PROTOCOL_SQL || protocol == TB_URL_PROTOCOL_FILE); // the probe func static tb_size_t (*s_probe[])(tb_url_ref_t) = { tb_null #ifdef TB_CONFIG_PACKAGE_HAVE_MYSQL , tb_database_mysql_probe #endif #ifdef TB_CONFIG_PACKAGE_HAVE_SQLITE3 , tb_database_sqlite3_probe #endif }; // the init func static tb_database_sql_ref_t (*s_init[])(tb_url_ref_t) = { tb_null #ifdef TB_CONFIG_PACKAGE_HAVE_MYSQL , tb_database_mysql_init #endif #ifdef TB_CONFIG_PACKAGE_HAVE_SQLITE3 , tb_database_sqlite3_init #endif }; // probe the database type tb_size_t i = 1; tb_size_t n = tb_arrayn(s_probe); tb_size_t s = 0; tb_size_t m = 0; for (; i < n; i++) { if (s_probe[i]) { // probe it tb_size_t score = s_probe[i](&database_url); if (score > s) { // save the max score s = score; m = i; // ok? if (score == 100) break; } } } tb_check_break(m < n && s_init[m]); // init it database = s_init[m](&database_url); tb_assert_and_check_break(database); // trace tb_trace_d("init: %s: ok", url); // ok ok = tb_true; } while (0); // exit url tb_url_exit(&database_url); // failed? if (!ok) { // trace tb_trace_d("init: %s: no", url); // exit database if (database) tb_database_sql_exit(database); database = tb_null; } // ok? return database; }