apr_status_t ap_queue_info_create(fd_queue_info_t **queue_info, apr_pool_t *pool, int max_idlers) { apr_status_t rv; fd_queue_info_t *qi; qi = apr_pcalloc(pool, sizeof(*qi)); rv = apr_thread_mutex_create(&qi->idlers_mutex, APR_THREAD_MUTEX_DEFAULT, pool); if (rv != APR_SUCCESS) { return rv; } rv = apr_thread_cond_create(&qi->wait_for_idler, pool); if (rv != APR_SUCCESS) { return rv; } qi->recycled_pools = NULL; qi->max_idlers = max_idlers; apr_pool_cleanup_register(pool, qi, queue_info_cleanup, apr_pool_cleanup_null); *queue_info = qi; return APR_SUCCESS; }
ZEKE_HIDDEN struct zktool_vxid_pool *zktool_vxid_factory(apr_pool_t *pool) { struct zktool_vxid_pool *vp = NULL; apr_status_t st; st = apr_pool_userdata_get((void**)&vp,"LIBZEKE:zktool_vxid",pool); if(st != APR_SUCCESS || !vp) { vp = apr_palloc(pool,VXID_SIZEOF(*vp)); assert(vp != NULL); vp->magic = ZKTOOL_VXID_MAGIC; vp->p = pool; VXID(vp).base = &vxid_base; VXID(vp).chunk = &vxid_chunk; #ifdef ZEKE_USE_THREADS vp->busy = 0; vp->waiter = 0; assert(apr_thread_mutex_create(&vp->mutex,APR_THREAD_MUTEX_DEFAULT,pool) == APR_SUCCESS); assert(apr_thread_cond_create(&vp->cond,pool) == APR_SUCCESS); #endif assert(apr_pool_userdata_setn(vp,"LIBZEKE:zktool_vxid",NULL,pool) == APR_SUCCESS); } zktool_vxid_get(vp); return vp; }
/** * Initialize the fd_queue_t. */ apr_status_t ap_queue_init(fd_queue_t *queue, int queue_capacity, apr_pool_t *a) { int i; apr_status_t rv; if ((rv = apr_thread_mutex_create(&queue->one_big_mutex, APR_THREAD_MUTEX_DEFAULT, a)) != APR_SUCCESS) { return rv; } if ((rv = apr_thread_cond_create(&queue->not_empty, a)) != APR_SUCCESS) { return rv; } queue->data = apr_palloc(a, queue_capacity * sizeof(fd_queue_elem_t)); queue->bounds = queue_capacity; queue->nelts = 0; queue->in = 0; queue->out = 0; /* Set all the sockets in the queue to NULL */ for (i = 0; i < queue_capacity; ++i) queue->data[i].sd = NULL; apr_pool_cleanup_register(a, queue, ap_queue_destroy, apr_pool_cleanup_null); return APR_SUCCESS; }
void mq_stream_read_request(mq_stream_t *mqs) { mq_msg_t *msg; //** If 1st time make all the variables if (mqs->mpool == NULL) { apr_pool_create(&mqs->mpool, NULL); apr_thread_mutex_create(&(mqs->lock), APR_THREAD_MUTEX_DEFAULT, mqs->mpool); apr_thread_cond_create(&(mqs->cond), mqs->mpool); } log_printf(5, "msid=%d want_more=%c\n", mqs->msid, mqs->want_more); //** Form the message msg = mq_make_exec_core_msg(mqs->remote_host, 1); mq_msg_append_mem(msg, MQS_MORE_DATA_KEY, MQS_MORE_DATA_SIZE, MQF_MSG_KEEP_DATA); mq_msg_append_mem(msg, mqs->host_id, mqs->hid_len, MQF_MSG_KEEP_DATA); mq_msg_append_mem(msg, mqs->stream_id, mqs->sid_len, MQF_MSG_KEEP_DATA); mq_msg_append_mem(msg, &(mqs->want_more), 1, MQF_MSG_KEEP_DATA); //** Want more data mq_msg_append_mem(msg, NULL, 0, MQF_MSG_KEEP_DATA); //DELETE??? mq_apply_return_address_msg(msg, mqs->remote_host, 0); //** Make the gop mqs->gop_waiting = new_mq_op(mqs->mqc, msg, mqs_response_client_more, mqs, NULL, mqs->timeout); //** Start executing it apr_thread_mutex_lock(mqs->lock); mqs->waiting = 1; apr_thread_mutex_unlock(mqs->lock); gop_start_execution(mqs->gop_waiting); }
static void broadcast_threads(abts_case *tc, void *data) { toolbox_t box; unsigned int i; apr_status_t rv; apr_uint32_t count = 0; apr_thread_cond_t *cond = NULL; apr_thread_mutex_t *mutex = NULL; apr_thread_t *thread[NTHREADS]; rv = apr_thread_cond_create(&cond, p); ABTS_SUCCESS(rv); ABTS_PTR_NOTNULL(tc, cond); rv = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, p); ABTS_SUCCESS(rv); ABTS_PTR_NOTNULL(tc, mutex); rv = apr_thread_mutex_lock(mutex); ABTS_SUCCESS(rv); box.tc = tc; box.data = &count; box.mutex = mutex; box.cond = cond; box.func = lock_and_wait; for (i = 0; i < NTHREADS; i++) { rv = apr_thread_create(&thread[i], NULL, thread_routine, &box, p); ABTS_SUCCESS(rv); } do { rv = apr_thread_mutex_unlock(mutex); ABTS_SUCCESS(rv); apr_sleep(100000); rv = apr_thread_mutex_lock(mutex); ABTS_SUCCESS(rv); } while (apr_atomic_read32(&count) != NTHREADS); rv = apr_thread_cond_broadcast(cond); ABTS_SUCCESS(rv); rv = apr_thread_mutex_unlock(mutex); ABTS_SUCCESS(rv); for (i = 0; i < NTHREADS; i++) { apr_status_t retval; rv = apr_thread_join(&retval, thread[i]); ABTS_SUCCESS(rv); } ABTS_INT_EQUAL(tc, 0, count); rv = apr_thread_cond_destroy(cond); ABTS_SUCCESS(rv); rv = apr_thread_mutex_destroy(mutex); ABTS_SUCCESS(rv); }
LLCondition::LLCondition(apr_pool_t *poolp) : LLMutex(poolp) { // base class (LLMutex) has already ensured that mAPRPoolp is set up. apr_thread_cond_create(&mAPRCondp, mAPRPoolp); }
static void dynamic_binding(abts_case *tc, void *data) { unsigned int i; apr_status_t rv; toolbox_t box[NTHREADS]; apr_thread_t *thread[NTHREADS]; apr_thread_mutex_t *mutex[NTHREADS]; apr_thread_cond_t *cond = NULL; rv = apr_thread_cond_create(&cond, p); ABTS_SUCCESS(rv); ABTS_PTR_NOTNULL(tc, cond); for (i = 0; i < NTHREADS; i++) { rv = apr_thread_mutex_create(&mutex[i], APR_THREAD_MUTEX_DEFAULT, p); ABTS_SUCCESS(rv); rv = apr_thread_mutex_lock(mutex[i]); ABTS_SUCCESS(rv); box[i].tc = tc; box[i].cond = cond; box[i].mutex = mutex[i]; box[i].func = lock_and_signal; rv = apr_thread_create(&thread[i], NULL, thread_routine, &box[i], p); ABTS_SUCCESS(rv); } /* * The dynamic binding should be preserved because we use only one waiter */ for (i = 0; i < NTHREADS; i++) { rv = apr_thread_cond_wait(cond, mutex[i]); ABTS_SUCCESS(rv); } for (i = 0; i < NTHREADS; i++) { rv = apr_thread_cond_timedwait(cond, mutex[i], 10000); ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv)); rv = apr_thread_mutex_unlock(mutex[i]); ABTS_SUCCESS(rv); } for (i = 0; i < NTHREADS; i++) { apr_status_t retval; rv = apr_thread_join(&retval, thread[i]); ABTS_SUCCESS(rv); } rv = apr_thread_cond_destroy(cond); ABTS_SUCCESS(rv); for (i = 0; i < NTHREADS; i++) { rv = apr_thread_mutex_destroy(mutex[i]); ABTS_SUCCESS(rv); } }
resource_service_fn_t *rs_simple_create(void *arg, tbx_inip_file_t *kf, char *section) { service_manager_t *ess = (service_manager_t *)arg; rs_simple_priv_t *rss; resource_service_fn_t *rs; //** Create the new RS list tbx_type_malloc_clear(rss, rs_simple_priv_t, 1); assert_result(apr_pool_create(&(rss->mpool), NULL), APR_SUCCESS); apr_thread_mutex_create(&(rss->lock), APR_THREAD_MUTEX_DEFAULT, rss->mpool); apr_thread_mutex_create(&(rss->update_lock), APR_THREAD_MUTEX_DEFAULT, rss->mpool); apr_thread_cond_create(&(rss->cond), rss->mpool); rss->rid_mapping = apr_hash_make(rss->mpool); rss->mapping_updates = apr_hash_make(rss->mpool); rss->ds = lookup_service(ess, ESS_RUNNING, ESS_DS); rss->da = lookup_service(ess, ESS_RUNNING, ESS_DA); //** Set the resource service fn ptrs tbx_type_malloc_clear(rs, resource_service_fn_t, 1); rs->priv = rss; rs->get_rid_config = rss_get_rid_config; rs->register_mapping_updates = rss_mapping_register; rs->unregister_mapping_updates = rss_mapping_unregister; rs->translate_cap_set = rss_translate_cap_set; rs->query_new = rs_query_base_new; rs->query_dup = rs_query_base_dup; rs->query_add = rs_query_base_add; rs->query_append = rs_query_base_append; rs->query_destroy = rs_query_base_destroy; rs->query_print = rs_query_base_print; rs->query_parse = rs_query_base_parse; rs->get_rid_value = rs_simple_get_rid_value; rs->data_request = rs_simple_request; rs->destroy_service = rs_simple_destroy; rs->type = RS_TYPE_SIMPLE; //** This is the file to use for loading the RID table rss->fname = tbx_inip_get_string(kf, section, "fname", NULL); rss->dynamic_mapping = tbx_inip_get_integer(kf, section, "dynamic_mapping", 0); rss->check_interval = tbx_inip_get_integer(kf, section, "check_interval", 300); rss->check_timeout = tbx_inip_get_integer(kf, section, "check_timeout", 60); rss->min_free = tbx_inip_get_integer(kf, section, "min_free", 100*1024*1024); //** Set the modify time to force a change rss->modify_time = 0; //** Load the RID table assert_result(_rs_simple_refresh(rs), 0); //** Launch the check thread tbx_thread_create_assert(&(rss->check_thread), NULL, rss_check_thread, (void *)rs, rss->mpool); return(rs); }
/* Create the audio queue. */ int audio_queue_create(audio_queue_t **audio_queue, const char *name) { int status = 0; audio_queue_t *laudio_queue = NULL; char *lname = ""; apr_pool_t *pool; if (audio_queue == NULL) return -1; else *audio_queue = NULL; if ((pool = apt_pool_create()) == NULL) return -1; if ((name == NULL) || (strlen(name) == 0)) lname = ""; else lname = apr_pstrdup(pool, name); if (lname == NULL) lname = ""; if ((laudio_queue = (audio_queue_t *)apr_palloc(pool, sizeof(audio_queue_t))) == NULL) { ast_log(LOG_ERROR, "(%s) Unable to create audio queue\n", lname); return -1; } else { laudio_queue->buffer = NULL; laudio_queue->cond = NULL; laudio_queue->mutex = NULL; laudio_queue->name = lname; laudio_queue->pool = pool; laudio_queue->read_bytes = 0; laudio_queue->waiting = 0; laudio_queue->write_bytes = 0; if (audio_buffer_create(&laudio_queue->buffer, AUDIO_QUEUE_SIZE) != 0) { ast_log(LOG_ERROR, "(%s) Unable to create audio queue buffer\n", laudio_queue->name); status = -1; } else if (apr_thread_mutex_create(&laudio_queue->mutex, APR_THREAD_MUTEX_UNNESTED, pool) != APR_SUCCESS) { ast_log(LOG_ERROR, "(%s) Unable to create audio queue mutex\n", laudio_queue->name); status = -1; } else if (apr_thread_cond_create(&laudio_queue->cond, pool) != APR_SUCCESS) { ast_log(LOG_ERROR, "(%s) Unable to create audio queue condition variable\n", laudio_queue->name); status = -1; } else { *audio_queue = laudio_queue; ast_log(LOG_DEBUG, "(%s) Audio queue created\n", laudio_queue->name); } } if (status != 0) audio_queue_destroy(laudio_queue); return status; }
void gop_dummy_init() { //** Make the variables assert_result(apr_pool_create(&gd_pool, NULL), APR_SUCCESS); assert_result(apr_thread_mutex_create(&gd_lock, APR_THREAD_MUTEX_DEFAULT, gd_pool), APR_SUCCESS); assert_result(apr_thread_cond_create(&gd_cond, gd_pool), APR_SUCCESS); gd_stack = new_stack(); //** and launch the thread thread_create_assert(&gd_thread, NULL, gd_thread_func, NULL, gd_pool); }
static void test_cond(abts_case *tc, void *data) { apr_thread_t *p1, *p2, *p3, *p4, *c1; apr_status_t s0, s1, s2, s3, s4; int count1, count2, count3, count4; int sum; APR_ASSERT_SUCCESS(tc, "create put mutex", apr_thread_mutex_create(&put.mutex, APR_THREAD_MUTEX_DEFAULT, p)); ABTS_PTR_NOTNULL(tc, put.mutex); APR_ASSERT_SUCCESS(tc, "create nready mutex", apr_thread_mutex_create(&nready.mutex, APR_THREAD_MUTEX_DEFAULT, p)); ABTS_PTR_NOTNULL(tc, nready.mutex); APR_ASSERT_SUCCESS(tc, "create condvar", apr_thread_cond_create(&nready.cond, p)); ABTS_PTR_NOTNULL(tc, nready.cond); count1 = count2 = count3 = count4 = 0; put.nput = put.nval = 0; nready.nready = 0; i = 0; x = 0; s0 = apr_thread_create(&p1, NULL, thread_cond_producer, &count1, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, s0); s1 = apr_thread_create(&p2, NULL, thread_cond_producer, &count2, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, s1); s2 = apr_thread_create(&p3, NULL, thread_cond_producer, &count3, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, s2); s3 = apr_thread_create(&p4, NULL, thread_cond_producer, &count4, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, s3); s4 = apr_thread_create(&c1, NULL, thread_cond_consumer, NULL, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, s4); apr_thread_join(&s0, p1); apr_thread_join(&s1, p2); apr_thread_join(&s2, p3); apr_thread_join(&s3, p4); apr_thread_join(&s4, c1); APR_ASSERT_SUCCESS(tc, "destroy condvar", apr_thread_cond_destroy(nready.cond)); sum = count1 + count2 + count3 + count4; /* printf("count1 = %d count2 = %d count3 = %d count4 = %d\n", count1, count2, count3, count4); */ ABTS_INT_EQUAL(tc, MAX_COUNTER, sum); }
/** * Initialize the apr_queue_t. */ APU_DECLARE(apr_status_t) apr_queue_create(apr_queue_t **q, unsigned int queue_capacity, apr_pool_t *a) { apr_status_t rv; apr_queue_t *queue; queue = apr_palloc(a, sizeof(apr_queue_t)); *q = queue; /* nested doesn't work ;( */ rv = apr_thread_mutex_create(&queue->one_big_mutex, APR_THREAD_MUTEX_UNNESTED, a); if (rv != APR_SUCCESS) { return rv; } rv = apr_thread_cond_create(&queue->not_empty, a); if (rv != APR_SUCCESS) { return rv; } rv = apr_thread_cond_create(&queue->not_full, a); if (rv != APR_SUCCESS) { return rv; } /* Set all the data in the queue to NULL */ queue->data = apr_pcalloc(a, queue_capacity * sizeof(void*)); queue->bounds = queue_capacity; queue->nelts = 0; queue->in = 0; queue->out = 0; queue->terminated = 0; queue->full_waiters = 0; queue->empty_waiters = 0; apr_pool_cleanup_register(a, queue, queue_destroy, apr_pool_cleanup_null); return APR_SUCCESS; }
APU_DECLARE(apr_status_t) apr_reslist_create(apr_reslist_t **reslist, int min, int smax, int hmax, apr_interval_time_t ttl, apr_reslist_constructor con, apr_reslist_destructor de, void *params, apr_pool_t *pool) { apr_status_t rv; apr_reslist_t *rl; /* Do some sanity checks so we don't thrash around in the * maintenance routine later. */ if (min > smax || min > hmax || smax > hmax || ttl < 0) { return APR_EINVAL; } rl = apr_pcalloc(pool, sizeof(*rl)); rl->pool = pool; rl->min = min; rl->smax = smax; rl->hmax = hmax; rl->ttl = ttl; rl->constructor = con; rl->destructor = de; rl->params = params; APR_RING_INIT(&rl->avail_list, apr_res_t, link); APR_RING_INIT(&rl->free_list, apr_res_t, link); rv = apr_thread_mutex_create(&rl->listlock, APR_THREAD_MUTEX_DEFAULT, pool); if (rv != APR_SUCCESS) { return rv; } rv = apr_thread_cond_create(&rl->avail, pool); if (rv != APR_SUCCESS) { return rv; } rv = reslist_maint(rl); if (rv != APR_SUCCESS) { return rv; } apr_pool_cleanup_register(rl->pool, rl, reslist_cleanup, apr_pool_cleanup_null); *reslist = rl; return APR_SUCCESS; }
void *gop_control_new(void *arg, int size) { gop_control_t *shelf; int i; type_malloc_clear(shelf, gop_control_t, size); for (i=0; i<size; i++) { { int result = apr_thread_mutex_create(&(shelf[i].lock), APR_THREAD_MUTEX_DEFAULT,_opque_pool); assert(result == APR_SUCCESS); } { int result = apr_thread_cond_create(&(shelf[i].cond), _opque_pool); assert(result == APR_SUCCESS); } } return((void *)shelf); }
cache_t *lru_cache_create(void *arg, data_attr_t *da, int timeout) { cache_t *cache; cache_lru_t *c; type_malloc_clear(cache, cache_t, 1); type_malloc_clear(c, cache_lru_t, 1); cache->fn.priv = c; cache_base_create(cache, da, timeout); cache->shutdown_request = 0; c->stack = new_stack(); c->waiting_stack = new_stack(); c->pending_free_tasks = new_stack(); c->max_bytes = 100*1024*1024; c->bytes_used = 0; c->dirty_fraction = 0.1; cache->n_ppages = 0; cache->max_fetch_fraction = 0.1; cache->max_fetch_size = cache->max_fetch_fraction * c->max_bytes; cache->write_temp_overflow_used = 0; cache->write_temp_overflow_fraction = 0.01; cache->write_temp_overflow_size = cache->write_temp_overflow_fraction * c->max_bytes; c->dirty_bytes_trigger = c->dirty_fraction * c->max_bytes; c->dirty_max_wait = apr_time_make(1, 0); c->flush_in_progress = 0; c->limbo_pages = 0; c->free_pending_tables = new_pigeon_coop("free_pending_tables", 50, sizeof(list_t *), cache->mpool, free_pending_table_new, free_pending_table_free); c->free_page_tables = new_pigeon_coop("free_page_tables", 50, sizeof(page_table_t), cache->mpool, free_page_tables_new, free_page_tables_free); cache->fn.create_empty_page = lru_create_empty_page; cache->fn.adjust_dirty = lru_adjust_dirty; cache->fn.destroy_pages = lru_pages_destroy; cache->fn.cache_update = lru_update; cache->fn.cache_miss_tag = lru_miss_tag; cache->fn.s_page_access = lru_page_access; cache->fn.s_pages_release = lru_pages_release; cache->fn.destroy = lru_cache_destroy; cache->fn.adding_segment = lru_adding_segment; cache->fn.removing_segment = lru_removing_segment; cache->fn.get_handle = cache_base_handle; apr_thread_cond_create(&(c->dirty_trigger), cache->mpool); thread_create_assert(&(c->dirty_thread), NULL, lru_dirty_thread, (void *)cache, cache->mpool); return(cache); }
int bind_server_port(Network_t *net, NetStream_t *ns, char *address, int port, int max_pending) { int err, slot; ns_monitor_t *nm; apr_thread_mutex_lock(net->ns_lock); slot = net->used_ports; nm = &(net->nm[slot]); log_printf(15, "bind_server_port: connection=%s:%d being stored in slot=%d\n", address, port, slot); err = ns->bind(ns->sock, address, port); if (err != 0) { log_printf(0, "bind_server_port: Error with bind address=%s port=%d err=%d\n", address, port, err); return(err); } err = ns->listen(ns->sock, max_pending); if (err != 0) { log_printf(0, "bind_server_port: Error with listen address=%s port=%d err=%d\n", address, port, err); return(err); } apr_pool_create(&(nm->mpool), NULL); apr_thread_mutex_create(&(nm->lock), APR_THREAD_MUTEX_DEFAULT, nm->mpool); apr_thread_cond_create(&(nm->cond), nm->mpool); nm->shutdown_request = 0; nm->is_pending = 0; nm->ns = ns; nm->address = strdup(address); nm->port = port; nm->trigger_cond = net->cond; nm->trigger_lock = net->ns_lock; nm->trigger_count = &(net->accept_pending); ns->id = ns_generate_id(); apr_pool_create(&(nm->mpool), NULL); apr_thread_create(&(nm->thread), NULL, monitor_thread, (void *)nm, nm->mpool); net->used_ports++; apr_thread_mutex_unlock(net->ns_lock); return(0); }
static void nested_wait(abts_case *tc, void *data) { toolbox_fnptr_t *fnptr = data; toolbox_t box; apr_status_t rv, retval; apr_thread_cond_t *cond = NULL; apr_thread_t *thread = NULL; apr_thread_mutex_t *mutex = NULL; rv = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_NESTED, p); ABTS_SUCCESS(rv); ABTS_PTR_NOTNULL(tc, mutex); rv = apr_thread_cond_create(&cond, p); ABTS_SUCCESS(rv); ABTS_PTR_NOTNULL(tc, cond); rv = apr_thread_mutex_lock(mutex); ABTS_SUCCESS(rv); box.tc = tc; box.cond = cond; box.mutex = mutex; box.func = fnptr->func; rv = apr_thread_create(&thread, NULL, thread_routine, &box, p); ABTS_SUCCESS(rv); rv = apr_thread_mutex_unlock(mutex); ABTS_SUCCESS(rv); /* yield the processor */ apr_sleep(500000); rv = apr_thread_cond_signal(cond); ABTS_SUCCESS(rv); rv = apr_thread_join(&retval, thread); ABTS_SUCCESS(rv); rv = apr_thread_mutex_trylock(mutex); ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_EBUSY(rv)); rv = apr_thread_mutex_trylock(mutex); ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_EBUSY(rv)); }
static void lost_signal(abts_case *tc, void *data) { apr_status_t rv; apr_thread_cond_t *cond = NULL; apr_thread_mutex_t *mutex = NULL; rv = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT, p); ABTS_SUCCESS(rv); ABTS_PTR_NOTNULL(tc, mutex); rv = apr_thread_cond_create(&cond, p); ABTS_SUCCESS(rv); ABTS_PTR_NOTNULL(tc, cond); rv = apr_thread_cond_signal(cond); ABTS_SUCCESS(rv); rv = apr_thread_mutex_lock(mutex); ABTS_SUCCESS(rv); rv = apr_thread_cond_timedwait(cond, mutex, 10000); ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv)); rv = apr_thread_mutex_unlock(mutex); ABTS_SUCCESS(rv); rv = apr_thread_cond_broadcast(cond); ABTS_SUCCESS(rv); rv = apr_thread_mutex_lock(mutex); ABTS_SUCCESS(rv); rv = apr_thread_cond_timedwait(cond, mutex, 10000); ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv)); rv = apr_thread_mutex_unlock(mutex); ABTS_SUCCESS(rv); rv = apr_thread_cond_destroy(cond); ABTS_SUCCESS(rv); rv = apr_thread_mutex_destroy(mutex); ABTS_SUCCESS(rv); }
extern apr_status_t napr_threadpool_init(napr_threadpool_t **threadpool, void *ctx, unsigned long nb_thread, threadpool_process_data_callback_fn_t *process_data, apr_pool_t *pool) { char errbuf[128]; apr_pool_t *local_pool; unsigned long l; apr_status_t status; apr_pool_create(&local_pool, pool); (*threadpool) = apr_palloc(local_pool, sizeof(struct napr_threadpool_t)); (*threadpool)->pool = local_pool; if (APR_SUCCESS != (status = apr_thread_mutex_create(&((*threadpool)->threadpool_mutex), APR_THREAD_MUTEX_DEFAULT, (*threadpool)->pool))) { DEBUG_ERR("error calling apr_thread_mutex_create: %s", apr_strerror(status, errbuf, 128)); return status; } if (APR_SUCCESS != (status = apr_thread_cond_create(&((*threadpool)->threadpool_update), (*threadpool)->pool))) { DEBUG_ERR("error calling apr_thread_cond_create: %s", apr_strerror(status, errbuf, 128)); return status; } (*threadpool)->thread = apr_palloc((*threadpool)->pool, nb_thread * sizeof(apr_thread_mutex_t *)); (*threadpool)->ctx = ctx; (*threadpool)->nb_thread = nb_thread; (*threadpool)->nb_waiting = 0UL; (*threadpool)->list = napr_list_make((*threadpool)->pool); (*threadpool)->process_data = process_data; (*threadpool)->run &= 0x0; (*threadpool)->ended &= 0x0; for (l = 0; l < nb_thread; l++) { if (APR_SUCCESS != (status = apr_thread_create(&((*threadpool)->thread[l]), NULL, napr_threadpool_loop, (*threadpool), (*threadpool)->pool))) { DEBUG_ERR("error calling apr_thread_create: %s", apr_strerror(status, errbuf, 128)); return status; } } return APR_SUCCESS; }
//======================================== // Falcon module registration // void falcon_register_hook( apr_pool_t *mp ) { apr_status_t rv; fprintf( stderr, "Falcon " VERSION " -- WOPI module for Apache2 startup."); // Inititialize watchdog data falconWatchdogData.terminate = 0; falconWatchdogData.incomingVM = 0; falconWatchdogData.lastIncomingVM = 0; apr_thread_mutex_create(&falconWatchdogData.mutex, APR_THREAD_MUTEX_UNNESTED, mp); apr_thread_cond_create(&falconWatchdogData.cond, mp); // Launch the watchdog thread // create falcon standard modules. ap_hook_handler(falcon_handler, NULL, NULL, APR_HOOK_MIDDLE); }
/** Start message processing loop */ MRCP_DECLARE(apt_bool_t) mrcp_client_start(mrcp_client_t *client) { apt_bool_t sync_start = TRUE; apt_task_t *task; if(!client || !client->task) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Invalid Client"); return FALSE; } task = apt_consumer_task_base_get(client->task); if(client->on_start_complete) { sync_start = FALSE; } if(sync_start == TRUE) { /* get prepared to start stack synchronously */ apr_thread_mutex_create(&client->sync_start_mutex,APR_THREAD_MUTEX_DEFAULT,client->pool); apr_thread_cond_create(&client->sync_start_object,client->pool); apr_thread_mutex_lock(client->sync_start_mutex); } if(apt_task_start(task) == FALSE) { if(sync_start == TRUE) { apr_thread_mutex_unlock(client->sync_start_mutex); } apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Start Client Task"); return FALSE; } if(sync_start == TRUE) { /* wait for start complete */ apr_thread_cond_wait(client->sync_start_object,client->sync_start_mutex); apr_thread_mutex_unlock(client->sync_start_mutex); } return TRUE; }
tbx_network_t *network_init() { int i; tbx_network_t *net; //**** Allocate space for the data structures *** net = (tbx_network_t *)malloc(sizeof(tbx_network_t));FATAL_UNLESS(net != NULL); net->used_ports = 0; net->accept_pending = 0; net->monitor_index = 0; assert_result(apr_pool_create(&(net->mpool), NULL), APR_SUCCESS); apr_thread_mutex_create(&(net->ns_lock), APR_THREAD_MUTEX_DEFAULT,net->mpool); apr_thread_cond_create(&(net->cond), net->mpool); net->used_ports = 0; for (i=0; i<NETWORK_MON_MAX; i++) { net->nm[i].port = -1; } return(net); }
static void test_timeoutcond(abts_case *tc, void *data) { apr_status_t s; apr_interval_time_t timeout; apr_time_t begin, end; int i; s = apr_thread_mutex_create(&timeout_mutex, APR_THREAD_MUTEX_DEFAULT, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, s); ABTS_PTR_NOTNULL(tc, timeout_mutex); s = apr_thread_cond_create(&timeout_cond, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, s); ABTS_PTR_NOTNULL(tc, timeout_cond); timeout = apr_time_from_sec(5); for (i = 0; i < MAX_RETRY; i++) { apr_thread_mutex_lock(timeout_mutex); begin = apr_time_now(); s = apr_thread_cond_timedwait(timeout_cond, timeout_mutex, timeout); end = apr_time_now(); apr_thread_mutex_unlock(timeout_mutex); if (s != APR_SUCCESS && !APR_STATUS_IS_TIMEUP(s)) { continue; } ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(s)); ABTS_ASSERT(tc, "Timer returned too late", end - begin - timeout < 500000); break; } ABTS_ASSERT(tc, "Too many retries", i < MAX_RETRY); APR_ASSERT_SUCCESS(tc, "Unable to destroy the conditional", apr_thread_cond_destroy(timeout_cond)); }
static apr_status_t thread_pool_construct(apr_thread_pool_t * me, apr_size_t init_threads, apr_size_t max_threads) { apr_status_t rv; int i; me->thd_max = max_threads; me->idle_max = init_threads; me->threshold = init_threads / 2; rv = apr_thread_mutex_create(&me->lock, APR_THREAD_MUTEX_NESTED, me->pool); if (APR_SUCCESS != rv) { return rv; } rv = apr_thread_cond_create(&me->cond, me->pool); if (APR_SUCCESS != rv) { apr_thread_mutex_destroy(me->lock); return rv; } me->tasks = apr_palloc(me->pool, sizeof(*me->tasks)); if (!me->tasks) { goto CATCH_ENOMEM; } APR_RING_INIT(me->tasks, apr_thread_pool_task, link); me->scheduled_tasks = apr_palloc(me->pool, sizeof(*me->scheduled_tasks)); if (!me->scheduled_tasks) { goto CATCH_ENOMEM; } APR_RING_INIT(me->scheduled_tasks, apr_thread_pool_task, link); me->recycled_tasks = apr_palloc(me->pool, sizeof(*me->recycled_tasks)); if (!me->recycled_tasks) { goto CATCH_ENOMEM; } APR_RING_INIT(me->recycled_tasks, apr_thread_pool_task, link); me->busy_thds = apr_palloc(me->pool, sizeof(*me->busy_thds)); if (!me->busy_thds) { goto CATCH_ENOMEM; } APR_RING_INIT(me->busy_thds, apr_thread_list_elt, link); me->idle_thds = apr_palloc(me->pool, sizeof(*me->idle_thds)); if (!me->idle_thds) { goto CATCH_ENOMEM; } APR_RING_INIT(me->idle_thds, apr_thread_list_elt, link); me->recycled_thds = apr_palloc(me->pool, sizeof(*me->recycled_thds)); if (!me->recycled_thds) { goto CATCH_ENOMEM; } APR_RING_INIT(me->recycled_thds, apr_thread_list_elt, link); me->thd_cnt = me->idle_cnt = me->task_cnt = me->scheduled_task_cnt = 0; me->tasks_run = me->tasks_high = me->thd_high = me->thd_timed_out = 0; me->spawning_cnt = 0; me->idle_wait = 0; me->terminated = 0; for (i = 0; i < TASK_PRIORITY_SEGS; i++) { me->task_idx[i] = NULL; } goto FINAL_EXIT; CATCH_ENOMEM: rv = APR_ENOMEM; apr_thread_mutex_destroy(me->lock); apr_thread_cond_destroy(me->cond); FINAL_EXIT: return rv; }
int main(int argc, const char **argv) { apr_status_t status; apr_pool_t *pool; apr_sockaddr_t *address; serf_context_t *context; serf_connection_t *connection; app_baton_t app_ctx; handler_baton_t *handler_ctx; apr_uri_t url; const char *raw_url, *method; int count; apr_getopt_t *opt; char opt_c; char *authn = NULL; const char *opt_arg; /* For the parser threads */ apr_thread_t *thread[3]; apr_threadattr_t *tattr; apr_status_t parser_status; parser_baton_t *parser_ctx; apr_initialize(); atexit(apr_terminate); apr_pool_create(&pool, NULL); apr_atomic_init(pool); /* serf_initialize(); */ /* Default to one round of fetching. */ count = 1; /* Default to GET. */ method = "GET"; apr_getopt_init(&opt, pool, argc, argv); while ((status = apr_getopt(opt, "a:hv", &opt_c, &opt_arg)) == APR_SUCCESS) { int srclen, enclen; switch (opt_c) { case 'a': srclen = strlen(opt_arg); enclen = apr_base64_encode_len(srclen); authn = apr_palloc(pool, enclen + 6); strcpy(authn, "Basic "); (void) apr_base64_encode(&authn[6], opt_arg, srclen); break; case 'h': print_usage(pool); exit(0); break; case 'v': puts("Serf version: " SERF_VERSION_STRING); exit(0); default: break; } } if (opt->ind != opt->argc - 1) { print_usage(pool); exit(-1); } raw_url = argv[opt->ind]; apr_uri_parse(pool, raw_url, &url); if (!url.port) { url.port = apr_uri_port_of_scheme(url.scheme); } if (!url.path) { url.path = "/"; } if (strcasecmp(url.scheme, "https") == 0) { app_ctx.using_ssl = 1; } else { app_ctx.using_ssl = 0; } status = apr_sockaddr_info_get(&address, url.hostname, APR_UNSPEC, url.port, 0, pool); if (status) { printf("Error creating address: %d\n", status); exit(1); } context = serf_context_create(pool); /* ### Connection or Context should have an allocator? */ app_ctx.bkt_alloc = serf_bucket_allocator_create(pool, NULL, NULL); app_ctx.ssl_ctx = NULL; app_ctx.authn = authn; connection = serf_connection_create(context, address, conn_setup, &app_ctx, closed_connection, &app_ctx, pool); handler_ctx = (handler_baton_t*)serf_bucket_mem_alloc(app_ctx.bkt_alloc, sizeof(handler_baton_t)); handler_ctx->allocator = app_ctx.bkt_alloc; handler_ctx->doc_queue = apr_array_make(pool, 1, sizeof(doc_path_t*)); handler_ctx->doc_queue_alloc = app_ctx.bkt_alloc; handler_ctx->requests_outstanding = (apr_uint32_t*)serf_bucket_mem_alloc(app_ctx.bkt_alloc, sizeof(apr_uint32_t)); apr_atomic_set32(handler_ctx->requests_outstanding, 0); handler_ctx->hdr_read = 0; parser_ctx = (void*)serf_bucket_mem_alloc(app_ctx.bkt_alloc, sizeof(parser_baton_t)); parser_ctx->requests_outstanding = handler_ctx->requests_outstanding; parser_ctx->connection = connection; parser_ctx->app_ctx = &app_ctx; parser_ctx->doc_queue = handler_ctx->doc_queue; parser_ctx->doc_queue_alloc = handler_ctx->doc_queue_alloc; /* Restrict ourselves to this host. */ parser_ctx->hostinfo = url.hostinfo; status = apr_thread_mutex_create(&parser_ctx->mutex, APR_THREAD_MUTEX_DEFAULT, pool); if (status) { printf("Couldn't create mutex %d\n", status); return status; } status = apr_thread_cond_create(&parser_ctx->condvar, pool); if (status) { printf("Couldn't create condvar: %d\n", status); return status; } /* Let the handler now which condvar to use. */ handler_ctx->doc_queue_condvar = parser_ctx->condvar; apr_threadattr_create(&tattr, pool); /* Start the parser thread. */ apr_thread_create(&thread[0], tattr, parser_thread, parser_ctx, pool); /* Deliver the first request. */ create_request(url.hostinfo, url.path, NULL, NULL, parser_ctx, pool); /* Go run our normal thread. */ while (1) { int tries = 0; status = serf_context_run(context, SERF_DURATION_FOREVER, pool); if (APR_STATUS_IS_TIMEUP(status)) continue; if (status) { char buf[200]; printf("Error running context: (%d) %s\n", status, apr_strerror(status, buf, sizeof(buf))); exit(1); } /* We run this check to allow our parser threads to add more * requests to our queue. */ for (tries = 0; tries < 3; tries++) { if (!apr_atomic_read32(handler_ctx->requests_outstanding)) { #ifdef SERF_VERBOSE printf("Waiting..."); #endif apr_sleep(100000); #ifdef SERF_VERBOSE printf("Done\n"); #endif } else { break; } } if (tries >= 3) { break; } /* Debugging purposes only! */ serf_debug__closed_conn(app_ctx.bkt_alloc); } printf("Quitting...\n"); serf_connection_close(connection); /* wake up the parser via condvar signal */ apr_thread_cond_signal(parser_ctx->condvar); status = apr_thread_join(&parser_status, thread[0]); if (status) { printf("Error joining thread: %d\n", status); return status; } serf_bucket_mem_free(app_ctx.bkt_alloc, handler_ctx->requests_outstanding); serf_bucket_mem_free(app_ctx.bkt_alloc, parser_ctx); apr_pool_destroy(pool); return 0; }
/* * Program entry point. */ int main(int argc, char** argv) { /* * Standard command-line parsing. */ const HASH_T *options = parse_cmdline(argc, argv, arg_opts); if(options == NULL || hash_get(options, "help") != NULL) { show_usage(argc, argv, arg_opts); return EXIT_FAILURE; } const char *url = hash_get(options, "url"); const char *principal = hash_get(options, "principal"); CREDENTIALS_T *credentials = NULL; const char *password = hash_get(options, "credentials"); if(password != NULL) { credentials = credentials_create_password(password); } const char *topic_name = hash_get(options, "topic"); const long seconds = atol(hash_get(options, "seconds")); /* * Setup for condition variable. */ apr_initialize(); apr_pool_create(&pool, NULL); apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_UNNESTED, pool); apr_thread_cond_create(&cond, pool); /* * Create a session with the Diffusion server. */ SESSION_T *session; DIFFUSION_ERROR_T error = { 0 }; session = session_create(url, principal, credentials, NULL, NULL, &error); if(session == NULL) { fprintf(stderr, "TEST: Failed to create session\n"); fprintf(stderr, "ERR : %s\n", error.message); return EXIT_FAILURE; } /* * Create a topic holding simple string content. */ TOPIC_DETAILS_T *string_topic_details = create_topic_details_single_value(M_DATA_TYPE_STRING); const ADD_TOPIC_PARAMS_T add_topic_params = { .topic_path = topic_name, .details = string_topic_details, .on_topic_added = on_topic_added, .on_topic_add_failed = on_topic_add_failed, .on_discard = on_topic_add_discard, }; apr_thread_mutex_lock(mutex); add_topic(session, add_topic_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); topic_details_free(string_topic_details); /* * Define the handlers for add_update_source() */ const UPDATE_SOURCE_REGISTRATION_PARAMS_T update_reg_params = { .topic_path = topic_name, .on_init = on_update_source_init, .on_registered = on_update_source_registered, .on_active = on_update_source_active, .on_standby = on_update_source_standby, .on_close = on_update_source_closed }; /* * Register an updater. */ apr_thread_mutex_lock(mutex); CONVERSATION_ID_T *updater_id = register_update_source(session, update_reg_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); /* * Define default parameters for an update source. */ UPDATE_SOURCE_PARAMS_T update_source_params_base = { .updater_id = updater_id, .topic_path = topic_name, .on_success = on_update_success, .on_failure = on_update_failure }; time_t end_time = time(NULL) + seconds; while(time(NULL) < end_time) { if(active) { /* * Create an update structure containing the current time. */ BUF_T *buf = buf_create(); const time_t time_now = time(NULL); buf_write_string(buf, ctime(&time_now)); CONTENT_T *content = content_create(CONTENT_ENCODING_NONE, buf); UPDATE_T *upd = update_create(UPDATE_ACTION_REFRESH, UPDATE_TYPE_CONTENT, content); UPDATE_SOURCE_PARAMS_T update_source_params = update_source_params_base; update_source_params.update = upd; /* * Update the topic. */ update(session, update_source_params); content_free(content); update_free(upd); buf_free(buf); } sleep(1); } if(active) { UPDATE_SOURCE_DEREGISTRATION_PARAMS_T update_dereg_params = { .updater_id = updater_id, .on_deregistered = on_update_source_deregistered }; apr_thread_mutex_lock(mutex); deregister_update_source(session, update_dereg_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); } /* * Close session and free resources. */ session_close(session, NULL); session_free(session); conversation_id_free(updater_id); credentials_free(credentials); apr_thread_mutex_destroy(mutex); apr_thread_cond_destroy(cond); apr_pool_destroy(pool); apr_terminate(); return EXIT_SUCCESS; }
int main(int argc, char **argv) { // for (int i=1; i<NSIG; i++) { // //if (signal(SIGINT, sig_handler) == SIG_ERR) printf("\ncan't catch SIGINT\n"); // if (signal(i, sig_handler) == SIG_ERR) printf("\ncan't catch %s\n", strsignal(i)); // } signal(SIGPIPE, SIG_IGN); apr_initialize(); apr_pool_create(&mp_rpc_, NULL); apr_thread_cond_create(&cd_rpc_, mp_rpc_); apr_thread_mutex_create(&mx_rpc_, APR_THREAD_MUTEX_UNNESTED, mp_rpc_); rpc_init(); arg_parse(argc, argv); bool exit = false; exit |= !(is_server_ || is_client_); exit |= (addr_ == NULL); exit |= (port_ == 0); if (exit) { fprintf(stderr, "wrong arguments.\n"); usage(argv[0]); return 0; } if (is_server_) { server_t *server = NULL; server_create(&server, NULL); strcpy(server->comm->ip, addr_); server->comm->port = port_; server_reg(server, ADD, add); server_start(server); LOG_INFO("server started start on %s, port %d.", addr_, port_); } if (is_client_) { LOG_INFO("client to %s:%d, test for %d rpc in total, outstanding rpc: %d", addr_, port_, max_rpc_, max_outst_); apr_thread_mutex_lock(mx_rpc_); for (int i = 0; i < n_client_; i++) { apr_thread_t *th; apr_thread_create(&th, NULL, client_thread, NULL, mp_rpc_); } LOG_INFO("rpc triggered for %d adds on %d threads.", max_rpc_ * n_client_, n_client_); apr_thread_cond_wait(cd_rpc_, mx_rpc_); apr_thread_mutex_unlock(mx_rpc_); int period = (tm_end_ - tm_begin_); //micro seconds LOG_INFO("finish %d rpc in %d ms.", max_rpc_ * n_client_, period/1000); float rate = (float) max_rpc_ * n_client_ / period; LOG_INFO("rpc rate %f million per sec.", rate); } fflush(stdout); fflush(stderr); while(is_server_) { apr_sleep(1000000); } rpc_destroy(); atexit(apr_terminate); }
SWITCH_DECLARE(switch_status_t) switch_thread_cond_create(switch_thread_cond_t ** cond, switch_memory_pool_t *pool) { return apr_thread_cond_create(cond, pool); }
/** Create ASR session */ ASR_CLIENT_DECLARE(asr_session_t*) asr_session_create(asr_engine_t *engine, const char *profile) { mpf_termination_t *termination; mrcp_channel_t *channel; mrcp_session_t *session; const mrcp_app_message_t *app_message; apr_pool_t *pool; asr_session_t *asr_session; mpf_stream_capabilities_t *capabilities; /* create session */ session = mrcp_application_session_create(engine->mrcp_app,profile,NULL); if(!session) { return NULL; } pool = mrcp_application_session_pool_get(session); asr_session = apr_palloc(pool,sizeof(asr_session_t)); mrcp_application_session_object_set(session,asr_session); /* create source stream capabilities */ capabilities = mpf_source_stream_capabilities_create(pool); /* add codec capabilities (Linear PCM) */ mpf_codec_capabilities_add( &capabilities->codecs, MPF_SAMPLE_RATE_8000, "LPCM"); termination = mrcp_application_audio_termination_create( session, /* session, termination belongs to */ &audio_stream_vtable, /* virtual methods table of audio stream */ capabilities, /* capabilities of audio stream */ asr_session); /* object to associate */ channel = mrcp_application_channel_create( session, /* session, channel belongs to */ MRCP_RECOGNIZER_RESOURCE, /* MRCP resource identifier */ termination, /* media termination, used to terminate audio stream */ NULL, /* RTP descriptor, used to create RTP termination (NULL by default) */ asr_session); /* object to associate */ if(!channel) { mrcp_application_session_destroy(session); return NULL; } asr_session->engine = engine; asr_session->mrcp_session = session; asr_session->mrcp_channel = channel; asr_session->recog_complete = NULL; asr_session->input_mode = INPUT_MODE_NONE; asr_session->streaming = FALSE; asr_session->audio_in = NULL; asr_session->media_buffer = NULL; asr_session->mutex = NULL; asr_session->wait_object = NULL; asr_session->app_message = NULL; /* Create cond wait object and mutex */ apr_thread_mutex_create(&asr_session->mutex,APR_THREAD_MUTEX_DEFAULT,pool); apr_thread_cond_create(&asr_session->wait_object,pool); /* Create media buffer */ asr_session->media_buffer = mpf_frame_buffer_create(160,20,pool); /* Send add channel request and wait for the response */ apr_thread_mutex_lock(asr_session->mutex); app_message = NULL; if(mrcp_application_channel_add(asr_session->mrcp_session,asr_session->mrcp_channel) == TRUE) { apr_thread_cond_wait(asr_session->wait_object,asr_session->mutex); app_message = asr_session->app_message; asr_session->app_message = NULL; } apr_thread_mutex_unlock(asr_session->mutex); if(sig_response_check(app_message) == FALSE) { asr_session_destroy_ex(asr_session,TRUE); return NULL; } return asr_session; }
int main(int argc, char **argv) { // for (int i=1; i<NSIG; i++) { // //if (signal(SIGINT, sig_handler) == SIG_ERR) printf("\ncan't catch SIGINT\n"); // if (signal(i, sig_handler) == SIG_ERR) printf("\ncan't catch %s\n", strsignal(i)); // } signal(SIGPIPE, SIG_IGN); apr_initialize(); apr_pool_create(&mp_rpc_, NULL); apr_thread_cond_create(&cd_rpc_, mp_rpc_); apr_thread_mutex_create(&mx_rpc_, APR_THREAD_MUTEX_UNNESTED, mp_rpc_); rpc_init(); arg_parse(argc, argv); ADD = is_fast_ ? FAST_ADD : SLOW_ADD; bool exit = false; exit |= !(is_server_ || is_client_); exit |= (addr_ == NULL); exit |= (port_ == 0); if (exit) { fprintf(stderr, "wrong arguments.\n"); usage(argv[0]); return 0; } if (is_server_) { server_t *server = NULL; poll_mgr_t *mgr_server = NULL; poll_mgr_create(&mgr_server, n_server_thread_); server_create(&server, mgr_server); strcpy(server->comm->ip, addr_); server->comm->port = port_; server_reg(server, ADD, add); server_start(server); LOG_INFO("server started start on %s, port %d.", addr_, port_); } if (is_client_) { LOG_INFO("client to %s:%d, test for %d rpc in total, outstanding rpc: %d", addr_, port_, max_rpc_, max_outst_); mgrs_ = (poll_mgr_t **) malloc(n_client_ * sizeof(poll_mgr_t*)); clis_ = (client_t **) malloc(n_client_ * sizeof(client_t *)); n_issues_ = (uint64_t*) malloc(n_client_ * sizeof(uint64_t)); n_callbacks_ = (uint64_t*) malloc(n_client_ * sizeof(uint64_t)); n_active_cli_ = n_client_; apr_thread_mutex_lock(mx_rpc_); for (int i = 0; i < n_client_; i++) { apr_thread_t *th; apr_thread_create(&th, NULL, client_thread, (intptr_t) i, mp_rpc_); } if (max_rpc_ < 0) { LOG_INFO("infinite rpc on %d threads (clients)", n_client_); } else { LOG_INFO("%d threads (clients), each client run for %d rpc.", n_client_, max_rpc_ * n_client_); } apr_thread_cond_wait(cd_rpc_, mx_rpc_); apr_thread_mutex_unlock(mx_rpc_); int period = (tm_end_ - tm_begin_); //micro seconds LOG_INFO("finish %d rpc in %d ms.", max_rpc_ * n_client_, period/1000); float rate = (float) max_rpc_ * n_client_ / period; LOG_INFO("rpc rate %f million per sec.", rate); for (int i = 0; i < n_client_; i++) { client_destroy(clis_[i]); poll_mgr_destroy(mgrs_[i]); } free (clis_); free (n_issues_); } fflush(stdout); fflush(stderr); while(is_server_) { apr_sleep(1000000); } rpc_destroy(); atexit(apr_terminate); }