/** * Waits on a conditional, handling interruptions and thread state. */ IDATA condvar_wait_impl(hycond_t *cond, osmutex_t *mutex, I_64 ms, IDATA nano, IDATA interruptable) { int r; int disable_count; hythread_t self; self = tm_self_tls; // check interrupted flag if (interruptable && self->interrupted) { // clean interrupted flag IDATA status = hythread_clear_interrupted_other(self); assert(status == TM_ERROR_INTERRUPT); return TM_ERROR_INTERRUPT; } // Store provided cond into current thread cond self->current_condition = interruptable ? cond : NULL; disable_count = hythread_reset_suspend_disable(); r = os_cond_timedwait(cond, mutex, ms, nano); hythread_set_suspend_disable(disable_count); self->current_condition = NULL; // check interrupted flag if (interruptable && self->interrupted) { // clean interrupted flag IDATA status = hythread_clear_interrupted_other(self); assert(status == TM_ERROR_INTERRUPT); return TM_ERROR_INTERRUPT; } return r; }
/** * Instructs the current thread to wait until signaled to wake up or timeout. * Directly using OS interfaces. * This function does not implement interruptability and thread state functionality. */ IDATA VMCALL hycond_wait_timed_raw(hycond_t *cond, osmutex_t *mutex, I_64 ms, IDATA nano) { return os_cond_timedwait(cond, mutex, ms, nano); }
/****************************************************************************** * Function: jpeg_queue_dequeue * Description: Dequeue a entry from the queue. It returns the double pointer * to the entry to be denqueued from the head of queue, * and accepts the number of time in mini-seconds that it conditional . * waits if the queue if empty. * Input parameters: * queue - The queue object. * pp_dequeue_buffer - The double pointer to dequeued entry. * ms - The time out in minisecond * Return values: * JPEGERR_SUCCESS * JPEGERR_EFAILED * JPEGERR_ENULLPTR * JPEGERR_ETIMEDOUT * Notes: none *****************************************************************************/ int jpeg_queue_dequeue( jpeg_queue_t queue, void **pp_dequeue_entry, uint32_t time_out_ms) { uint32_t q_index; jpeg_q_t *p_q; int rc; // Input parameter validation if (!pp_dequeue_entry) { JPEG_DBG_ERROR("jpeg_queue_dequeue: failed with input parameter check\n"); return JPEGERR_EBADPARM; } p_q = (jpeg_q_t *)queue; if (!p_q) { JPEG_DBG_ERROR("jpeg_queue_dequeue: failed with empty queue pointer\n"); return JPEGERR_ENULLPTR; } os_mutex_lock(&(p_q->mutex)); if (p_q->state == QUEUE_STATE_ABORTED) { os_mutex_unlock(&(p_q->mutex)); JPEG_DBG_ERROR("jpeg_queue_dequeue: Aborted \n"); return JPEGERR_EFAILED; } // Check if queue is empty: // queue_cnt is current number of entries in queue. while (p_q->queue_cnt <= 0 && QUEUE_STATE_ABORT != p_q->state) { p_q->state = QUEUE_STATE_TIMEWAIT; // fails after conditional waiting time_out_ms in milli-seconds rc = os_cond_timedwait(&(p_q->get_cond), &(p_q->mutex), time_out_ms); if (JPEG_FAILED(rc)) { JPEG_DBG_ERROR("jpeg_queue_dequeue: failed with empty queue\n"); if (QUEUE_STATE_ABORT == p_q->state) { p_q->state = QUEUE_STATE_ABORTED; os_cond_signal(&(p_q->abort_cond)); } p_q->state = QUEUE_STATE_IDLE; os_mutex_unlock(&(p_q->mutex)); return rc; } } if (QUEUE_STATE_ABORT == p_q->state) { p_q->state = QUEUE_STATE_IDLE; // signal abort cond os_cond_signal(&(p_q->abort_cond)); os_mutex_unlock(&(p_q->mutex)); JPEG_DBG_ERROR("jpeg_queue_dequeue: failed with abort\n"); return JPEGERR_EFAILED; } // Dequeue an entry from queue q_index = p_q->queue_head; // Dequeue the entry from the head of queue *pp_dequeue_entry = p_q->queue_pool[q_index].p_data; // Update the head of queue and entries number p_q->queue_head = QUEUE_MOD(p_q->queue_head + 1); p_q->queue_cnt -= 1; p_q->state = QUEUE_STATE_IDLE; os_mutex_unlock(&(p_q->mutex)); return JPEGERR_SUCCESS; }