-void xbt_queue_shift_timed(xbt_queue_t queue, void* const dst,double delay) {
- xbt_mutex_lock(queue->mutex);
- if (xbt_dynar_length(queue->data) == 0) {
- DEBUG1("Queue %p empty. Waiting",queue);
- xbt_cond_timedwait(queue->not_empty,queue->mutex,delay);
- }
- /* check if a timeout occurs */
- if (xbt_dynar_length(queue->data) == 0) {
- xbt_mutex_unlock(queue->mutex);
- THROW0(timeout_error,0,"Timeout");
- }
- else {
- xbt_dynar_shift(queue->data,dst);
- xbt_cond_signal(queue->not_full);
- xbt_mutex_unlock(queue->mutex);
- }
+void xbt_queue_shift_timed(xbt_queue_t queue, void *const dst,
+ double delay)
+{
+ double begin = xbt_time();
+
+ xbt_mutex_acquire(queue->mutex);
+
+ if (delay == 0) {
+ if (xbt_dynar_is_empty(queue->data)) {
+ xbt_mutex_release(queue->mutex);
+ THROWF(timeout_error, 0, "Delay = 0, and queue is empty");
+ }
+ } else {
+ while ((xbt_dynar_is_empty(queue->data)) &&
+ (delay < 0 || (xbt_time() - begin) <= delay)) {
+ XBT_DEBUG("Queue %p empty. Waiting", queue);
+ TRY {
+ xbt_cond_timedwait(queue->not_empty, queue->mutex,
+ delay < 0 ? -1 : delay - (xbt_time() - begin));
+ }
+ CATCH_ANONYMOUS {
+ xbt_mutex_release(queue->mutex);
+ RETHROW;
+ }
+ }
+ }
+
+ if (xbt_dynar_is_empty(queue->data)) {
+ xbt_mutex_release(queue->mutex);
+ THROWF(timeout_error, 0, "Timeout (%f) elapsed, but queue still empty",
+ delay);
+ }
+
+ xbt_dynar_shift(queue->data, dst);
+ xbt_cond_signal(queue->not_full);
+ xbt_mutex_release(queue->mutex);