void server_destroy(server_t *svr) { rpc_common_destroy(svr->comm); // TODO maybe destroy all connections first? mpr_hash_destroy(svr->ht_conn); apr_thread_pool_destroy(svr->tp); free(svr); }
int main(int argc,char **argv) { apr_initialize(); apr_pool_t *pool; apr_pool_create(&pool,NULL); apr_status_t st; apr_thread_pool_t *tpl; st=apr_thread_pool_create(&tpl,8,128,pool); apr_size_t n; for(long i=0;i<30;i++) { apr_thread_pool_push(tpl,thread_func,(void *)i,APR_THREAD_TASK_PRIORITY_NORMAL,NULL); apr_sleep(50000); } for(long i=0;i<10;i++) { n=apr_thread_pool_idle_count(tpl); printf("idle thread: %d\n",n); apr_sleep(1000000); } for(long i=100;i<130;i++) { apr_thread_pool_push(tpl,thread_func,(void *)i,APR_THREAD_TASK_PRIORITY_NORMAL,NULL); apr_sleep(50000); } for(long i=0;i<10;i++) { n=apr_thread_pool_idle_count(tpl); printf("idle thread: %d\n",n); apr_sleep(1000000); } apr_thread_pool_destroy(tpl); apr_pool_destroy(pool); apr_terminate(); return 0; }
void gop_tp_context_destroy(gop_thread_pool_context_t *tpc) { int i; log_printf(15, "gop_tp_context_destroy: Shutting down! count=%d\n", _tp_context_count); log_printf(15, "tpc->name=%s high=%zu idle=%zu\n", tpc->name, apr_thread_pool_threads_high_count(tpc->tp), apr_thread_pool_threads_idle_timeout_count(tpc->tp)); gop_hp_context_destroy(tpc->pc); apr_thread_pool_destroy(tpc->tp); if (tbx_atomic_dec(_tp_context_count) == 0) { if (_tp_stats > 0) thread_pool_stats_print(); apr_thread_mutex_destroy(_tp_lock); apr_pool_destroy(_tp_pool); } if (tpc->name != NULL) free(tpc->name); for (i=0; i<tpc->recursion_depth; i++) { tbx_stack_free(tpc->reserve_stack[i], 0); } free(tpc->reserve_stack); free(tpc->overflow_running_depth); free(tpc); }
/* test for threadsafe crypt() */ static void test_threadsafe(abts_case *tc, void *data) { int i; apr_status_t rv; apr_thread_pool_t *thrp; rv = apr_thread_pool_create(&thrp, NUM_THR/2, NUM_THR, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); for (i = 0; i < NUM_THR; i++) { rv = apr_thread_pool_push(thrp, testing_thread, tc, 0, NULL); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } apr_thread_pool_destroy(thrp); }
static void test_reslist(abts_case *tc, void *data) { int i; apr_status_t rv; apr_reslist_t *rl; my_parameters_t *params; apr_thread_pool_t *thrp; my_thread_info_t thread_info[CONSUMER_THREADS]; rv = apr_thread_pool_create(&thrp, CONSUMER_THREADS/2, CONSUMER_THREADS, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); /* Create some parameters that will be passed into each * constructor and destructor call. */ params = apr_pcalloc(p, sizeof(*params)); params->sleep_upon_construct = CONSTRUCT_SLEEP_TIME; params->sleep_upon_destruct = DESTRUCT_SLEEP_TIME; /* We're going to want 10 blocks of data from our target rmm. */ rv = apr_reslist_create(&rl, RESLIST_MIN, RESLIST_SMAX, RESLIST_HMAX, RESLIST_TTL, my_constructor, my_destructor, params, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); for (i = 0; i < CONSUMER_THREADS; i++) { thread_info[i].tid = i; thread_info[i].tc = tc; thread_info[i].reslist = rl; thread_info[i].work_delay_sleep = WORK_DELAY_SLEEP_TIME; rv = apr_thread_pool_push(thrp, resource_consuming_thread, &thread_info[i], 0, NULL); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } rv = apr_thread_pool_destroy(thrp); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); test_timeout(tc, rl); test_shrinking(tc, rl); ABTS_INT_EQUAL(tc, RESLIST_SMAX, params->c_count - params->d_count); rv = apr_reslist_destroy(rl); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); }
//apr initialization and destroy. void deinitialize_apr(void) { apr_status_t rv; if(queue) { rv =apr_queue_term(queue); check_error(rv); } if(thrp) { apr_thread_pool_destroy(thrp); check_error(rv); } if(mem_pool) { apr_pool_destroy(mem_pool); check_error(rv); } apr_terminate(); queue = NULL; thrp = NULL; mem_pool = NULL; }
int main(int argc, const char *argv[]) { apr_pool_t *pool; int exit_code = EXIT_SUCCESS; svn_error_t *err; /* Initialize the app. */ if (svn_cmdline_init("svnserve", stderr) != EXIT_SUCCESS) return EXIT_FAILURE; /* Create our top-level pool. */ pool = apr_allocator_owner_get(svn_pool_create_allocator(TRUE)); err = sub_main(&exit_code, argc, argv, pool); /* Flush stdout and report if it fails. It would be flushed on exit anyway but this makes sure that output is not silently lost if it fails. */ err = svn_error_compose_create(err, svn_cmdline_fflush(stdout)); if (err) { exit_code = EXIT_FAILURE; svn_cmdline_handle_exit_error(err, NULL, "svnserve: "); } #if APR_HAS_THREADS /* Explicitly wait for all threads to exit. As we found out with similar code in our C test framework, the memory pool cleanup below cannot be trusted to do the right thing. */ if (threads) apr_thread_pool_destroy(threads); #endif /* this will also close the server's socket */ svn_pool_destroy(pool); return exit_code; }
void mapcache_prefetch_tiles(mapcache_context *ctx, mapcache_tile **tiles, int ntiles) { apr_thread_t **threads; apr_threadattr_t *thread_attrs; int nthreads; #if !APR_HAS_THREADS int i; for(i=0; i<ntiles; i++) { mapcache_tileset_tile_get(ctx, tiles[i]); GC_CHECK_ERROR(ctx); } #else int i,rv; _thread_tile* thread_tiles; if(ntiles==1 || ctx->config->threaded_fetching == 0) { /* if threads disabled, or only fetching a single tile, don't launch a thread for the operation */ for(i=0; i<ntiles; i++) { mapcache_tileset_tile_get(ctx, tiles[i]); GC_CHECK_ERROR(ctx); } return; } /* allocate a thread struct for each tile. Not all will be used */ thread_tiles = (_thread_tile*)apr_pcalloc(ctx->pool,ntiles*sizeof(_thread_tile)); #if 1 || !USE_THREADPOOL /* use multiple threads, to fetch from multiple metatiles and/or multiple tilesets */ apr_threadattr_create(&thread_attrs, ctx->pool); threads = (apr_thread_t**)apr_pcalloc(ctx->pool, ntiles*sizeof(apr_thread_t*)); nthreads = 0; for(i=0; i<ntiles; i++) { int j; thread_tiles[i].tile = tiles[i]; thread_tiles[i].launch = 1; j=i-1; /* * we only launch one thread per metatile as in the unseeded case the threads * for a same metatile will lock while only a single thread launches the actual * rendering request */ while(j>=0) { /* check that the given metatile hasn't been rendered yet */ if(thread_tiles[j].launch && (thread_tiles[i].tile->tileset == thread_tiles[j].tile->tileset) && (thread_tiles[i].tile->x / thread_tiles[i].tile->tileset->metasize_x == thread_tiles[j].tile->x / thread_tiles[j].tile->tileset->metasize_x)&& (thread_tiles[i].tile->y / thread_tiles[i].tile->tileset->metasize_y == thread_tiles[j].tile->y / thread_tiles[j].tile->tileset->metasize_y)) { thread_tiles[i].launch = 0; /* this tile will not have a thread spawned for it */ break; } j--; } if(thread_tiles[i].launch) thread_tiles[i].ctx = ctx->clone(ctx); } for(i=0; i<ntiles; i++) { if(!thread_tiles[i].launch) continue; /* skip tiles that have been marked */ rv = apr_thread_create(&threads[i], thread_attrs, _thread_get_tile, (void*)&(thread_tiles[i]), thread_tiles[i].ctx->pool); if(rv != APR_SUCCESS) { ctx->set_error(ctx,500, "failed to create thread %d of %d\n",i,ntiles); break; } nthreads++; } /* wait for launched threads to finish */ for(i=0; i<ntiles; i++) { if(!thread_tiles[i].launch) continue; apr_thread_join(&rv, threads[i]); if(rv != APR_SUCCESS) { ctx->set_error(ctx,500, "thread %d of %d failed on exit\n",i,ntiles); } if(GC_HAS_ERROR(thread_tiles[i].ctx)) { /* transfer error message from child thread to main context */ ctx->set_error(ctx,thread_tiles[i].ctx->get_error(thread_tiles[i].ctx), thread_tiles[i].ctx->get_error_message(thread_tiles[i].ctx)); } } for(i=0; i<ntiles; i++) { /* fetch the tiles that did not get a thread launched for them */ if(thread_tiles[i].launch) continue; mapcache_tileset_tile_get(ctx, tiles[i]); GC_CHECK_ERROR(ctx); } #else /* experimental version using a threadpool, disabled for stability reasons */ apr_thread_pool_t *thread_pool; apr_thread_pool_create(&thread_pool,2,ctx->config->download_threads,ctx->pool); for(i=0; i<ntiles; i++) { ctx->log(ctx,MAPCACHE_DEBUG,"starting thread for tile %s",tiles[i]->tileset->name); thread_tiles[i].tile = tiles[i]; thread_tiles[i].ctx = ctx->clone(ctx); rv = apr_thread_pool_push(thread_pool,_thread_get_tile,(void*)&(thread_tiles[i]), 0,NULL); if(rv != APR_SUCCESS) { ctx->set_error(ctx,500, "failed to push thread %d of %d in thread pool\n",i,ntiles); break; } } GC_CHECK_ERROR(ctx); while(apr_thread_pool_tasks_run_count(thread_pool) != ntiles || apr_thread_pool_busy_count(thread_pool)>0) apr_sleep(10000); apr_thread_pool_destroy(thread_pool); for(i=0; i<ntiles; i++) { if(GC_HAS_ERROR(thread_tiles[i].ctx)) { ctx->set_error(ctx,thread_tiles[i].ctx->get_error(thread_tiles[i].ctx), thread_tiles[i].ctx->get_error_message(thread_tiles[i].ctx)); } } #endif #endif }
void http_server_cleanup() { apr_thread_pool_destroy(thread_pool); RELEASE_POOL(global_pool); apr_terminate(); //refcounted, so ok if other places do it too }