/** Initiate recognition based on specified grammar and input file */ ASR_CLIENT_DECLARE(apt_bool_t) asr_session_file_recognize( asr_session_t *asr_session, const char *grammar_file, const char *input_file) { const mrcp_app_message_t *app_message; mrcp_message_t *mrcp_message; app_message = NULL; mrcp_message = define_grammar_message_create(asr_session,grammar_file); if(!mrcp_message) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create DEFINE-GRAMMAR Request"); return FALSE; } /* Send DEFINE-GRAMMAR request and wait for the response */ apr_thread_mutex_lock(asr_session->mutex); if(mrcp_application_message_send(asr_session->mrcp_session,asr_session->mrcp_channel,mrcp_message) == 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(mrcp_response_check(app_message,MRCP_REQUEST_STATE_COMPLETE) == FALSE) { return FALSE; } /* Reset prev recog result (if any) */ asr_session->recog_complete = NULL; app_message = NULL; mrcp_message = recognize_message_create(asr_session); if(!mrcp_message) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Create RECOGNIZE Request"); return FALSE; } /* Send RECOGNIZE request and wait for the response */ apr_thread_mutex_lock(asr_session->mutex); if(mrcp_application_message_send(asr_session->mrcp_session,asr_session->mrcp_channel,mrcp_message) == 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(mrcp_response_check(app_message,MRCP_REQUEST_STATE_INPROGRESS) == FALSE) { return FALSE; } /* Open input file and start streaming */ asr_session->input_mode = INPUT_MODE_FILE; if(asr_input_file_open(asr_session,input_file) == FALSE) { return FALSE; } asr_session->streaming = TRUE; return TRUE; }
void LLCondition::wait() { if (AIThreadID::in_main_thread_inline()) { LLFastTimer ft1(FT_WAIT_FOR_CONDITION); apr_thread_cond_wait(mAPRCondp, mAPRMutexp); } else { apr_thread_cond_wait(mAPRCondp, mAPRMutexp); } }
op_generic_t *gop_waitany(op_generic_t *g) { op_generic_t *gop = g; callback_t *cb; lock_gop(g); if (gop_get_type(g) == Q_TYPE_QUE) { log_printf(15, "sync_exec_que_check gid=%d stack_size=%d started_exec=%d\n", gop_id(g), stack_size(g->q->opque->qd.list), g->base.started_execution); if ((stack_size(g->q->opque->qd.list) == 1) && (g->base.started_execution == 0)) { //** See if we can directly exec g->base.started_execution = 1; cb = (callback_t *)pop(g->q->opque->qd.list); gop = (op_generic_t *)cb->priv; log_printf(15, "sync_exec_que -- waiting for pgid=%d cgid=%d to complete\n", gop_id(g), gop_id(gop)); unlock_gop(g); gop_waitany(gop); pop(g->q->finished); //** Remove it from the finished list. return(gop); } else { _gop_start_execution(g); //** Make sure things have been submitted while (((gop = (op_generic_t *)pop(g->q->finished)) == NULL) && (g->q->nleft > 0)) { apr_thread_cond_wait(g->base.ctl->cond, g->base.ctl->lock); //** Sleep until something completes } } if (gop != NULL) log_printf(15, "POP finished qid=%d gid=%d\n", gop_id(g), gop_id(gop)); //log_printf(15, "Printing qid=%d finished stack\n", gop_id(g)); //_opque_print_stack(g->q->finished); } else { log_printf(15, "gop_waitany: BEFORE (type=op) While gid=%d state=%d\n", gop_id(g), g->base.state); flush_log(); if ((g->base.pc->fn->sync_exec != NULL) && (g->base.started_execution == 0)) { //** See if we can directly exec unlock_gop(g); //** Don't need this for a direct exec log_printf(15, "sync_exec -- waiting for gid=%d to complete\n", gop_id(g)); g->base.pc->fn->sync_exec(g->base.pc, g); log_printf(15, "sync_exec -- gid=%d completed with err=%d\n", gop_id(g), g->base.state); return(g); } else { //** Got to submit it normally unlock_gop(g); //** It's a single task so no need to hold the lock. Otherwise we can deadlock _gop_start_execution(g); //** Make sure things have been submitted lock_gop(g); //** but we do need it for detecting when we're finished. while (g->base.state == 0) { apr_thread_cond_wait(g->base.ctl->cond, g->base.ctl->lock); //** Sleep until something completes } } log_printf(15, "gop_waitany: AFTER (type=op) While gid=%d state=%d\n", gop_id(g), g->base.state); flush_log(); } unlock_gop(g); return(gop); }
int gop_waitall(op_generic_t *g) { int status; op_generic_t *g2; callback_t *cb; //log_printf(15, "START gid=%d type=%d\n", gop_id(g), gop_get_type(g)); log_printf(5, "START gid=%d type=%d\n", gop_id(g), gop_get_type(g)); lock_gop(g); if (gop_get_type(g) == Q_TYPE_QUE) { log_printf(15, "sync_exec_que_check gid=%d stack_size=%d started_exec=%d\n", gop_id(g), stack_size(g->q->opque->qd.list), g->base.started_execution); if ((stack_size(g->q->opque->qd.list) == 1) && (g->base.started_execution == 0)) { //** See if we can directly exec log_printf(15, "sync_exec_que -- waiting for gid=%d to complete\n", gop_id(g)); cb = (callback_t *)pop(g->q->opque->qd.list); g2 = (op_generic_t *)cb->priv; unlock_gop(g); //** Don't need this for a direct exec status = gop_waitall(g2); log_printf(15, "sync_exec -- gid=%d completed with err=%d\n", gop_id(g), status); return(status); } else { //** Got to submit it normally _gop_start_execution(g); //** Make sure things have been submitted while (g->q->nleft > 0) { apr_thread_cond_wait(g->base.ctl->cond, g->base.ctl->lock); //** Sleep until something completes } } } else { //** Got a single task if ((g->base.pc->fn->sync_exec != NULL) && (g->base.started_execution == 0)) { //** See if we can directly exec unlock_gop(g); //** Don't need this for a direct exec log_printf(15, "sync_exec -- waiting for gid=%d to complete\n", gop_id(g)); g->base.pc->fn->sync_exec(g->base.pc, g); status = _gop_completed_successfully(g); log_printf(15, "sync_exec -- gid=%d completed with err=%d\n", gop_id(g), status); return(status); } else { //** Got to submit it the normal way _gop_start_execution(g); //** Make sure things have been submitted while (g->base.state == 0) { log_printf(15, "gop_waitall: WHILE gid=%d state=%d\n", gop_id(g), g->base.state); apr_thread_cond_wait(g->base.ctl->cond, g->base.ctl->lock); //** Sleep until something completes } } } status = _gop_completed_successfully(g); log_printf(15, "END gid=%d type=%d\n", gop_id(g), gop_get_type(g)); unlock_gop(g); return(status); }
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); } }
apr_status_t h2_mplx_in_read(h2_mplx *m, apr_read_type_e block, int stream_id, apr_bucket_brigade *bb, struct apr_thread_cond_t *iowait) { apr_status_t status; AP_DEBUG_ASSERT(m); if (m->aborted) { return APR_ECONNABORTED; } status = apr_thread_mutex_lock(m->lock); if (APR_SUCCESS == status) { h2_io *io = h2_io_set_get(m->stream_ios, stream_id); if (io && !io->orphaned) { io->input_arrived = iowait; H2_MPLX_IO_IN(APLOG_TRACE2, m, io, "h2_mplx_in_read_pre"); status = h2_io_in_read(io, bb, -1); while (APR_STATUS_IS_EAGAIN(status) && !is_aborted(m, &status) && block == APR_BLOCK_READ) { apr_thread_cond_wait(io->input_arrived, m->lock); status = h2_io_in_read(io, bb, -1); } H2_MPLX_IO_IN(APLOG_TRACE2, m, io, "h2_mplx_in_read_post"); io->input_arrived = NULL; } else { status = APR_EOF; } apr_thread_mutex_unlock(m->lock); } return status; }
/** Destroy ASR session */ static apt_bool_t asr_session_destroy_ex(asr_session_t *asr_session, apt_bool_t terminate) { if(terminate == TRUE) { apr_thread_mutex_lock(asr_session->mutex); if(mrcp_application_session_terminate(asr_session->mrcp_session) == TRUE) { apr_thread_cond_wait(asr_session->wait_object,asr_session->mutex); /* the response must be checked to be the valid one */ } apr_thread_mutex_unlock(asr_session->mutex); } if(asr_session->audio_in) { fclose(asr_session->audio_in); asr_session->audio_in = NULL; } if(asr_session->mutex) { apr_thread_mutex_destroy(asr_session->mutex); asr_session->mutex = NULL; } if(asr_session->wait_object) { apr_thread_cond_destroy(asr_session->wait_object); asr_session->wait_object = NULL; } if(asr_session->media_buffer) { mpf_frame_buffer_destroy(asr_session->media_buffer); asr_session->media_buffer = NULL; } return mrcp_application_session_destroy(asr_session->mrcp_session); }
static void pong(toolbox_t *box) { apr_status_t rv; abts_case *tc = box->tc; rv = apr_thread_mutex_lock(box->mutex); ABTS_SUCCESS(rv); if (state == TOSS) state = PONG; do { rv = apr_thread_cond_signal(box->cond); ABTS_SUCCESS(rv); state = PING; rv = apr_thread_cond_wait(box->cond, box->mutex); ABTS_SUCCESS(rv); ABTS_TRUE(tc, state == PONG || state == OVER); } while (state != OVER); rv = apr_thread_mutex_unlock(box->mutex); ABTS_SUCCESS(rv); rv = apr_thread_cond_broadcast(box->cond); ABTS_SUCCESS(rv); }
ZEKE_HIDDEN apr_uint32_t zktool_vxid_get(struct zktool_vxid_pool *vp) { assert(vp != NULL && vp->magic == ZKTOOL_VXID_MAGIC); do { if(vp->count == 0) { #ifdef ZEKE_USE_THREADS assert(apr_thread_mutex_lock(vp->mutex) == APR_SUCCESS); while(vp->busy > 0) { vp->waiter++; assert(apr_thread_cond_wait(vp-cond,vp->mutex) == APR_SUCCESS); vp->waiter--; } vp->busy++; #endif vp->next = *VXID(vp).base; vp->count = *VXID(vp).chunk; *VXID(vp).chunk += vp->count; #ifdef ZEKE_USE_THREADS vp->busy-- assert(apr_thread_mutex_lock(vp->mutex) == APR_SUCCESS); if(vp->waiter) assert(apr_thread_cond_signal(vp->cond) == APR_SUCCESS); assert(apr_thread_mutex_unlock(vp->mutex) == APR_SUCCESS); #endif } vp->count--; vp->next++; } while(vp->next == 0); return vp->next; }
apr_status_t h2_mplx_in_read(h2_mplx *m, apr_read_type_e block, int stream_id, apr_bucket_brigade *bb, struct apr_thread_cond_t *iowait) { apr_status_t status; AP_DEBUG_ASSERT(m); if (m->aborted) { return APR_ECONNABORTED; } status = apr_thread_mutex_lock(m->lock); if (APR_SUCCESS == status) { h2_io *io = h2_io_set_get(m->stream_ios, stream_id); if (io) { io->input_arrived = iowait; status = h2_io_in_read(io, bb, 0); while (status == APR_EAGAIN && !is_aborted(m, &status) && block == APR_BLOCK_READ) { apr_thread_cond_wait(io->input_arrived, m->lock); status = h2_io_in_read(io, bb, 0); } io->input_arrived = NULL; } else { status = APR_EOF; } apr_thread_mutex_unlock(m->lock); } return status; }
apr_status_t h2_mplx_release_and_join(h2_mplx *m, apr_thread_cond_t *wait) { apr_status_t status; workers_unregister(m); status = apr_thread_mutex_lock(m->lock); if (APR_SUCCESS == status) { while (!h2_io_set_iter(m->stream_ios, stream_done_iter, m)) { /* iterator until all h2_io have been orphaned or destroyed */ } release(m, 0); while (m->refs > 0) { m->join_wait = wait; ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c, "h2_mplx(%ld): release_join, refs=%d, waiting...", m->id, m->refs); apr_thread_cond_wait(wait, m->lock); } ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, m->c, "h2_mplx(%ld): release_join -> destroy, (#ios=%ld)", m->id, (long)h2_io_set_size(m->stream_ios)); h2_mplx_destroy(m); /* all gone */ /*apr_thread_mutex_unlock(m->lock);*/ } return status; }
void *monitor_thread(apr_thread_t *th, void *data) { tbx_ns_monitor_t *nm = (tbx_ns_monitor_t *)data; tbx_ns_t *ns = nm->ns; int i; log_printf(15, "monitor_thread: Monitoring port %d\n", nm->port); apr_thread_mutex_lock(nm->lock); while (nm->shutdown_request == 0) { apr_thread_mutex_unlock(nm->lock); i = ns->connection_request(ns->sock, 1); if (i == 1) { //** Got a request log_printf(15, "monitor_thread: port=%d ns=%d Got a connection request time=" TT "\n", nm->port, tbx_ns_getid(ns), apr_time_now()); //** Mark that I have a connection pending apr_thread_mutex_lock(nm->lock); nm->is_pending = 1; apr_thread_mutex_unlock(nm->lock); //** Wake up the calling thread apr_thread_mutex_lock(nm->trigger_lock); (*(nm->trigger_count))++; apr_thread_cond_signal(nm->trigger_cond); apr_thread_mutex_unlock(nm->trigger_lock); log_printf(15, "monitor_thread: port=%d ns=%d waiting for accept\n", nm->port, tbx_ns_getid(ns)); //** Sleep until my connection is accepted apr_thread_mutex_lock(nm->lock); while ((nm->is_pending == 1) && (nm->shutdown_request == 0)) { apr_thread_cond_wait(nm->cond, nm->lock); log_printf(15, "monitor_thread: port=%d ns=%d Cond triggered=" TT " trigger_count=%d\n", nm->port, tbx_ns_getid(ns), apr_time_now(), *(nm->trigger_count)); } apr_thread_mutex_unlock(nm->lock); log_printf(15, "monitor_thread: port=%d ns=%d Connection accepted time=" TT "\n", nm->port, tbx_ns_getid(ns), apr_time_now()); //** Update pending count // apr_thread_mutex_lock(nm->trigger_lock); // *(nm->trigger_count)--; // apr_thread_mutex_unlock(nm->trigger_lock); } apr_thread_mutex_lock(nm->lock); } apr_thread_mutex_unlock(nm->lock); //** Lastly shutdown my socket tbx_ns_close(ns); log_printf(15, "monitor_thread: Closing port %d\n", nm->port); apr_thread_exit(th, 0); return(NULL); }
/** * Push new data onto the queue. Blocks if the queue is full. Once * the push operation has completed, it signals other threads waiting * in apr_queue_pop() that they may continue consuming sockets. * @param timeout added by Cisco. now uses apr_thread_cond_timewait(). * interval of time to wait. zero means forever, negative indicates no wait, * otherwise wait time in *microseconds*. * @return APR_SUCCESS, APR_EAGAIN, APR_EOF, APR_EINTR, APR_TIMEUP, * or some APR error */ apr_status_t etch_apr_queue_push(etch_apr_queue_t *queue, apr_interval_time_t timeout, void *data) { apr_status_t rv; if (queue->terminated) rv = APR_EOF; /* no more elements ever again */ else if (APR_SUCCESS == (rv = apr_thread_mutex_lock(queue->one_big_mutex))) { do { if (etch_apr_queue_full(queue)) { if (!queue->terminated) { if (-1 == timeout) { rv = APR_EAGAIN; /* asked to not wait */ break; } queue->full_waiters++; if (0 == timeout) rv = apr_thread_cond_wait(queue->not_full, queue->one_big_mutex); else rv = apr_thread_cond_timedwait(queue->not_full, queue->one_big_mutex, timeout); queue->full_waiters--; if (rv != APR_SUCCESS) break; } /* If we wake up and it's still empty, then we were interrupted */ if (etch_apr_queue_full(queue)) { Q_DBG("queue full (intr)", queue); rv = queue->terminated? APR_EOF: APR_EINTR; break; } } queue->data[queue->in] = data; queue->in = (queue->in + 1) % queue->bounds; queue->nelts++; if (queue->empty_waiters) { Q_DBG("sig !empty", queue); rv = apr_thread_cond_signal(queue->not_empty); } } while(0); apr_thread_mutex_unlock(queue->one_big_mutex); } return rv; }
op_status_t mqs_response_client_more(void *task_arg, int tid) { mq_task_t *task = (mq_task_t *)task_arg; mq_stream_t *mqs = (mq_stream_t *)task->arg; op_status_t status = op_success_status; log_printf(5, "START msid=%d\n", mqs->msid); //** Parse the response mq_remove_header(task->response, 1); //** Wait for a notification that the data can be processed apr_thread_mutex_lock(mqs->lock); log_printf(5, "INIT STATUS msid=%d waiting=%d processed=%d\n", mqs->msid, mqs->waiting, mqs->processed); mqs->transfer_packets++; mqs->waiting = 0; apr_thread_cond_broadcast(mqs->cond); //** Now wait until the application is ready while (mqs->waiting == 0) { apr_thread_cond_wait(mqs->cond, mqs->lock); } //** Can accept the data mq_get_frame(mq_msg_first(task->response), (void **)&(mqs->data), &(mqs->len)); pack_read_new_data(mqs->pack, &(mqs->data[MQS_HEADER]), mqs->len-MQS_HEADER); //** Notify the consumer it's available mqs->waiting = -2; apr_thread_cond_broadcast(mqs->cond); //** Wait until it's consumed while (mqs->processed == 0) { apr_thread_cond_wait(mqs->cond, mqs->lock); } mqs->data = NULL; //** Nullify the data so it's not accidentally accessed mqs->processed = 0; //** and reset the processed flag back to 0 apr_thread_mutex_unlock(mqs->lock); log_printf(5, "END msid=%d status=%d %d\n", mqs->msid, status.op_status, status.error_code); return(status); }
static apr_status_t wait_cond(h2_bucket_beam *beam, apr_thread_mutex_t *lock) { if (beam->timeout > 0) { return apr_thread_cond_timedwait(beam->m_cond, lock, beam->timeout); } else { return apr_thread_cond_wait(beam->m_cond, lock); } }
/** * Retrieves the next item from the queue. If there are no * items available, it will block until one becomes available. * Once retrieved, the item is placed into the address specified by * 'data'. */ APU_DECLARE(apr_status_t) apr_queue_pop(apr_queue_t *queue, void **data) { apr_status_t rv; if (queue->terminated) { return APR_EOF; /* no more elements ever again */ } rv = apr_thread_mutex_lock(queue->one_big_mutex); if (rv != APR_SUCCESS) { return rv; } /* Keep waiting until we wake up and find that the queue is not empty. */ if (apr_queue_empty(queue)) { if (!queue->terminated) { queue->empty_waiters++; rv = apr_thread_cond_wait(queue->not_empty, queue->one_big_mutex); queue->empty_waiters--; if (rv != APR_SUCCESS) { apr_thread_mutex_unlock(queue->one_big_mutex); return rv; } } /* If we wake up and it's still empty, then we were interrupted */ if (apr_queue_empty(queue)) { Q_DBG("queue empty (intr)", queue); rv = apr_thread_mutex_unlock(queue->one_big_mutex); if (rv != APR_SUCCESS) { return rv; } if (queue->terminated) { return APR_EOF; /* no more elements ever again */ } else { return APR_EINTR; } } } *data = queue->data[queue->out]; queue->nelts--; queue->out = (queue->out + 1) % queue->bounds; if (queue->full_waiters) { Q_DBG("signal !full", queue); rv = apr_thread_cond_signal(queue->not_full); if (rv != APR_SUCCESS) { apr_thread_mutex_unlock(queue->one_big_mutex); return rv; } } rv = apr_thread_mutex_unlock(queue->one_big_mutex); return rv; }
/** * Push new data onto the queue. Blocks if the queue is full. Once * the push operation has completed, it signals other threads waiting * in apr_queue_pop() that they may continue consuming sockets. */ APU_DECLARE(apr_status_t) apr_queue_push(apr_queue_t *queue, void *data) { apr_status_t rv; if (queue->terminated) { return APR_EOF; /* no more elements ever again */ } rv = apr_thread_mutex_lock(queue->one_big_mutex); if (rv != APR_SUCCESS) { return rv; } if (apr_queue_full(queue)) { if (!queue->terminated) { queue->full_waiters++; rv = apr_thread_cond_wait(queue->not_full, queue->one_big_mutex); queue->full_waiters--; if (rv != APR_SUCCESS) { apr_thread_mutex_unlock(queue->one_big_mutex); return rv; } } /* If we wake up and it's still empty, then we were interrupted */ if (apr_queue_full(queue)) { Q_DBG("queue full (intr)", queue); rv = apr_thread_mutex_unlock(queue->one_big_mutex); if (rv != APR_SUCCESS) { return rv; } if (queue->terminated) { return APR_EOF; /* no more elements ever again */ } else { return APR_EINTR; } } } queue->data[queue->in] = data; queue->in = (queue->in + 1) % queue->bounds; queue->nelts++; if (queue->empty_waiters) { Q_DBG("sig !empty", queue); rv = apr_thread_cond_signal(queue->not_empty); if (rv != APR_SUCCESS) { apr_thread_mutex_unlock(queue->one_big_mutex); return rv; } } rv = apr_thread_mutex_unlock(queue->one_big_mutex); return rv; }
/** * Retrieves the next available socket from the queue. If there are no * sockets available, it will block until one becomes available. * Once retrieved, the socket is placed into the address specified by * 'sd'. */ apr_status_t ap_queue_pop_something(fd_queue_t * queue, apr_socket_t ** sd, event_conn_state_t ** ecs, apr_pool_t ** p, timer_event_t ** te_out) { fd_queue_elem_t *elem; apr_status_t rv; if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) { return rv; } /* Keep waiting until we wake up and find that the queue is not empty. */ if (ap_queue_empty(queue)) { if (!queue->terminated) { apr_thread_cond_wait(queue->not_empty, queue->one_big_mutex); } /* If we wake up and it's still empty, then we were interrupted */ if (ap_queue_empty(queue)) { rv = apr_thread_mutex_unlock(queue->one_big_mutex); if (rv != APR_SUCCESS) { return rv; } if (queue->terminated) { return APR_EOF; /* no more elements ever again */ } else { return APR_EINTR; } } } *te_out = NULL; if (!APR_RING_EMPTY(&queue->timers, timer_event_t, link)) { *te_out = APR_RING_FIRST(&queue->timers); APR_RING_REMOVE(*te_out, link); } else { elem = &queue->data[queue->out]; queue->out++; if (queue->out >= queue->bounds) queue->out -= queue->bounds; queue->nelts--; *sd = elem->sd; *ecs = elem->ecs; *p = elem->p; #ifdef AP_DEBUG elem->sd = NULL; elem->p = NULL; #endif /* AP_DEBUG */ } rv = apr_thread_mutex_unlock(queue->one_big_mutex); return rv; }
APU_DECLARE(apr_status_t) apr_reslist_acquire(apr_reslist_t *reslist, void **resource) { apr_status_t rv; apr_res_t *res; apr_thread_mutex_lock(reslist->listlock); /* If there are idle resources on the available list, use * them right away. */ if (reslist->nidle > 0) { /* Pop off the first resource */ res = pop_resource(reslist); *resource = res->opaque; free_container(reslist, res); apr_thread_mutex_unlock(reslist->listlock); return APR_SUCCESS; } /* If we've hit our max, block until we're allowed to create * a new one, or something becomes free. */ else while (reslist->ntotal >= reslist->hmax && reslist->nidle <= 0) { if (reslist->timeout) { if ((rv = apr_thread_cond_timedwait(reslist->avail, reslist->listlock, reslist->timeout)) != APR_SUCCESS) { apr_thread_mutex_unlock(reslist->listlock); return rv; } } else apr_thread_cond_wait(reslist->avail, reslist->listlock); } /* If we popped out of the loop, first try to see if there * are new resources available for immediate use. */ if (reslist->nidle > 0) { res = pop_resource(reslist); *resource = res->opaque; free_container(reslist, res); apr_thread_mutex_unlock(reslist->listlock); return APR_SUCCESS; } /* Otherwise the reason we dropped out of the loop * was because there is a new slot available, so create * a resource to fill the slot and use it. */ else { rv = create_resource(reslist, &res); if (rv == APR_SUCCESS) { reslist->ntotal++; *resource = res->opaque; } free_container(reslist, res); apr_thread_mutex_unlock(reslist->listlock); return rv; } }
ex_off_t _lru_force_free_mem(cache_t *c, segment_t *page_seg, ex_off_t bytes_to_free, int check_waiters) { cache_segment_t *s = (cache_segment_t *)page_seg->priv; cache_lru_t *cp = (cache_lru_t *)c->fn.priv; ex_off_t freed_bytes, bytes_left; int top, finished; pigeon_coop_hole_t pch; cache_cond_t *cache_cond; //** I'm holding this coming in but don't need it cause I can touch all segs segment_unlock(page_seg); top = 0; bytes_left = bytes_to_free; freed_bytes = _lru_attempt_free_mem(c, page_seg, bytes_left); finished = 0; while ((freed_bytes < bytes_to_free) && (finished == 0)) { //** Keep trying to mark space as free until I get enough if (top == 0) { top = 1; pch = reserve_pigeon_coop_hole(s->c->cond_coop); cache_cond = (cache_cond_t *)pigeon_coop_hole_data(&pch); cache_cond->count = 0; move_to_bottom(cp->pending_free_tasks); insert_below(cp->pending_free_tasks, cache_cond); //** Add myself to the bottom } else { push(cp->pending_free_tasks, cache_cond); //** I go on the top } log_printf(15, "not enough space so waiting cache_cond=%p freed_bytes=" XOT " bytes_to_free=" XOT "\n", cache_cond, freed_bytes, bytes_to_free); //** Now wait until it's my turn apr_thread_cond_wait(cache_cond->cond, c->lock); bytes_left -= freed_bytes; freed_bytes = _lru_attempt_free_mem(c, page_seg, bytes_left); finished = 1; } //** Now check if we can handle some waiters if (check_waiters == 1) _lru_process_waiters(c); cache_unlock(c); //** Reacquire the lock in the proper order segment_lock(page_seg); //** Reacquire the lock cause I had it coming in cache_lock(c); if (top == 1) release_pigeon_coop_hole(s->c->cond_coop, &pch); freed_bytes = bytes_to_free - bytes_left; //NEW freed_bytes = bytes_left - freed_bytes; return(freed_bytes); }
static void * APR_THREAD_FUNC parser_thread(apr_thread_t *thread, void *data) { apr_status_t status; apr_pool_t *pool, *subpool; parser_baton_t *ctx; ctx = (parser_baton_t*)data; pool = apr_thread_pool_get(thread); apr_pool_create(&subpool, pool); while (1) { doc_path_t *dup; apr_pool_clear(subpool); /* Grab it. */ apr_thread_mutex_lock(ctx->mutex); /* Sleep. */ apr_thread_cond_wait(ctx->condvar, ctx->mutex); /* Fetch the doc off the list. */ if (ctx->doc_queue->nelts) { dup = *(doc_path_t**)(apr_array_pop(ctx->doc_queue)); /* dup = (ctx->doc_queue->conns->elts)[0]; */ } else { dup = NULL; } /* Don't need the mutex now. */ apr_thread_mutex_unlock(ctx->mutex); /* Parse the doc/url pair. */ if (dup) { status = find_href_doc(dup->doc, dup->path, ctx, subpool); if (status) { printf("Error finding hrefs: %d %s\n", status, dup->path); } /* Free the doc pair and its pool. */ apr_pool_destroy(dup->pool); serf_bucket_mem_free(ctx->doc_queue_alloc, dup->path); serf_bucket_mem_free(ctx->doc_queue_alloc, dup); } /* Hey are we done? */ if (!apr_atomic_read32(ctx->requests_outstanding)) { break; } } return NULL; }
void LLCondition::wait() { if (!isLocked()) { //mAPRMutexp MUST be locked before calling apr_thread_cond_wait apr_thread_mutex_lock(mAPRMutexp); #if MUTEX_DEBUG // avoid asserts on destruction in non-release builds U32 id = LLThread::currentID(); mIsLocked[id] = TRUE; #endif } apr_thread_cond_wait(mAPRCondp, mAPRMutexp); }
void _lru_wait_for_page(cache_t *c, segment_t *seg, int ontop) { cache_lru_t *cp = (cache_lru_t *)c->fn.priv; cache_segment_t *s = (cache_segment_t *)seg->priv; lru_page_wait_t pw; pigeon_coop_hole_t pch; cache_cond_t *cc; ex_off_t bytes_free, bytes_needed, n; int check_waiters_first; check_waiters_first = (ontop == 0) ? 1 : 0; pch = reserve_pigeon_coop_hole(c->cond_coop); cc = (cache_cond_t *)pigeon_coop_hole_data(&pch); pw.cond = cc->cond; pw.bytes_needed = s->page_size; bytes_free = _lru_max_bytes(c) - cp->bytes_used; while (s->page_size > bytes_free) { //** Attempt to free pages bytes_needed = s->page_size - bytes_free; n = _lru_force_free_mem(c, seg, bytes_needed, check_waiters_first); if (n > 0) { //** Didn't make it so wait if (ontop == 0) { move_to_bottom(cp->waiting_stack); insert_below(cp->waiting_stack, &pw); } else { push(cp->waiting_stack, &pw); } segment_unlock(seg); //** Unlock the segment to prevent deadlocks apr_thread_cond_wait(pw.cond, c->lock); //** Wait for the space to become available //** Have to reaquire both locks in the correct order cache_unlock(c); segment_lock(seg); cache_lock(c); ontop = 1; //** 2nd time we are always placed on the top of the stack check_waiters_first = 0; //** And don't check on waiters } bytes_free = _lru_max_bytes(c) - cp->bytes_used; } release_pigeon_coop_hole(c->cond_coop, &pch); return; }
static void *APR_THREAD_FUNC thread_cond_consumer(apr_thread_t *thd, void *data) { int i; for (i = 0; i < MAX_COUNTER; i++) { apr_thread_mutex_lock(nready.mutex); while (nready.nready == 0) apr_thread_cond_wait(nready.cond, nready.mutex); nready.nready--; apr_thread_mutex_unlock(nready.mutex); if (buff[i] != i) printf("buff[%d] = %d\n", i, buff[i]); } return NULL; }
static void nested_lock_and_wait(toolbox_t *box) { apr_status_t rv; abts_case *tc = box->tc; rv = apr_thread_mutex_lock(box->mutex); ABTS_SUCCESS(rv); rv = apr_thread_mutex_lock(box->mutex); ABTS_SUCCESS(rv); rv = apr_thread_mutex_lock(box->mutex); ABTS_SUCCESS(rv); rv = apr_thread_cond_wait(box->cond, box->mutex); ABTS_SUCCESS(rv); }
extern apr_status_t napr_threadpool_wait(napr_threadpool_t *threadpool) { char errbuf[128]; apr_status_t status; int list_size = 0; /* DEBUG_DBG("Called"); */ if (APR_SUCCESS != (status = apr_thread_mutex_lock(threadpool->threadpool_mutex))) { DEBUG_ERR("error calling apr_thread_mutex_lock: %s", apr_strerror(status, errbuf, 128)); return status; } list_size = napr_list_size(threadpool->list); if ((0 != list_size) || (threadpool->nb_waiting != threadpool->nb_thread)) { /* DEBUG_DBG("After lock before wait"); */ /* * Because the caller of this function has added all data we are now * running, the line after, (cond_wait), make us wait to the end of * processing. */ threadpool->run |= 0x1; if (APR_SUCCESS != (status = apr_thread_cond_wait(threadpool->threadpool_update, threadpool->threadpool_mutex))) { DEBUG_ERR("error calling apr_thread_cond_wait: %s", apr_strerror(status, errbuf, 128)); return status; } /* DEBUG_DBG("Awake"); */ /* Because all data have been processed, we are no more running */ threadpool->run &= 0x0; } /* * garbage collecting under lock protection to avoid list manipulation * during this freeing. * We are doing this garbage collecting because if not, we will re-using * the same pool to very-often alloc cell_t structures in list. * This could lead to a memory leak if not regularly cleaned. */ napr_list_delete(threadpool->list); threadpool->list = napr_list_make(threadpool->pool); if (APR_SUCCESS != (status = apr_thread_mutex_unlock(threadpool->threadpool_mutex))) { DEBUG_ERR("error calling apr_thread_mutex_unlock: %s", apr_strerror(status, errbuf, 128)); return status; } return APR_SUCCESS; }
/** * Retrieves the next available socket from the queue. If there are no * sockets available, it will block until one becomes available. * Once retrieved, the socket is placed into the address specified by * 'sd'. */ apr_status_t ap_queue_pop(fd_queue_t *queue, apr_socket_t **sd, apr_pool_t **p) { fd_queue_elem_t *elem; apr_status_t rv; if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) { return rv; } /* Keep waiting until we wake up and find that the queue is not empty. */ if (ap_queue_empty(queue)) { if (!queue->terminated) { apr_thread_cond_wait(queue->not_empty, queue->one_big_mutex); } /* If we wake up and it's still empty, then we were interrupted */ if (ap_queue_empty(queue)) { rv = apr_thread_mutex_unlock(queue->one_big_mutex); if (rv != APR_SUCCESS) { return rv; } if (queue->terminated) { return APR_EOF; /* no more elements ever again */ } else { return APR_EINTR; } } } elem = &queue->data[queue->out]; queue->out++; if (queue->out >= queue->bounds) queue->out -= queue->bounds; queue->nelts--; *sd = elem->sd; *p = elem->p; #ifdef AP_DEBUG elem->sd = NULL; elem->p = NULL; #endif /* AP_DEBUG */ rv = apr_thread_mutex_unlock(queue->one_big_mutex); return rv; }
static void lock_and_wait(toolbox_t *box) { apr_status_t rv; abts_case *tc = box->tc; apr_uint32_t *count = box->data; rv = apr_thread_mutex_lock(box->mutex); ABTS_SUCCESS(rv); apr_atomic_inc32(count); rv = apr_thread_cond_wait(box->cond, box->mutex); ABTS_SUCCESS(rv); apr_atomic_dec32(count); rv = apr_thread_mutex_unlock(box->mutex); ABTS_SUCCESS(rv); }
static void pipe_consumer(toolbox_t *box) { char ch; apr_status_t rv; apr_size_t nbytes; abts_case *tc = box->tc; apr_file_t *out = box->data; apr_uint32_t consumed = 0; do { rv = apr_thread_mutex_lock(box->mutex); ABTS_SUCCESS(rv); while (!pipe_count && !exiting) { rv = apr_thread_cond_wait(box->cond, box->mutex); ABTS_SUCCESS(rv); } if (!pipe_count && exiting) { rv = apr_thread_mutex_unlock(box->mutex); ABTS_SUCCESS(rv); break; } pipe_count--; consumed++; rv = apr_thread_mutex_unlock(box->mutex); ABTS_SUCCESS(rv); rv = apr_file_read_full(out, &ch, 1, &nbytes); ABTS_SUCCESS(rv); ABTS_SIZE_EQUAL(tc, 1, nbytes); ABTS_TRUE(tc, ch == '.'); } while (1); /* naive fairness test - it would be good to introduce or solidify * a solid test to ensure one thread is not starved. * ABTS_INT_EQUAL(tc, 1, !!consumed); */ }
void *gd_thread_func(apr_thread_t *th, void *data) { op_generic_t *gop; apr_thread_mutex_lock(gd_lock); while (gd_shutdown == 0) { //** Execute everything on the stack while ((gop = (op_generic_t *)pop(gd_stack)) != NULL) { log_printf(15, "DUMMY gid=%d status=%d\n", gop_id(gop), gop->base.status.op_status); apr_thread_mutex_unlock(gd_lock); gop_mark_completed(gop, gop->base.status); apr_thread_mutex_lock(gd_lock); } //** Wait for more work apr_thread_cond_wait(gd_cond, gd_lock); } apr_thread_mutex_unlock(gd_lock); return(NULL); }