static struct msg_t* queue_recv(struct queue_t* q, double timeout) { struct msg_t* msg = NULL; struct timespec ts; queue_lock(q); if (q->limit >= 0) { q->limit ++; pthread_cond_signal(&q->send_sig); } if (timeout > 0 && q->count <= 0) timeout_to_timespec(timeout, &ts); while (timeout != 0 && q->count <= 0) { if (timeout > 0) { if (pthread_cond_timedwait(&q->recv_sig, &q->lock, &ts) != 0) break; } else pthread_cond_wait(&q->recv_sig, &q->lock); } if (q->count > 0) { msg = q->msg_head; if (msg) { q->msg_head = msg->next; if (q->msg_head == NULL) q->msg_tail = NULL; msg->next = NULL; } q->count --; pthread_cond_signal(&q->send_sig); } if (q->limit > 0) q->limit --; queue_unlock(q); return msg; }
static int queue_send(struct queue_t* q, struct msg_t* msg, double timeout) { struct timespec ts; queue_lock(q); if (timeout > 0 && q->limit >= 0 && q->count + 1 > q->limit) timeout_to_timespec(timeout, &ts); while (timeout != 0 && q->limit >= 0 && q->count + 1 > q->limit) { if (timeout > 0) { if (pthread_cond_timedwait(&q->send_sig, &q->lock, &ts) != 0) break; } else pthread_cond_wait(&q->send_sig, &q->lock); } if (q->limit < 0 || q->count + 1 <= q->limit) { msg->next = NULL; if (q->msg_tail) q->msg_tail->next = msg; q->msg_tail = msg; if (q->msg_head == NULL) q->msg_head = msg; q->count ++; pthread_cond_signal(&q->recv_sig); } else { msg = NULL; } queue_unlock(q); return msg ? 1 : 0; }
int pthread_cond_timedwait_timeout(pthread_cond_t *cond, pthread_mutex_t *mutex, int timeout){ struct timespec ts; timeout_to_timespec(timeout, &ts); return pthread_cond_timedwait(cond, mutex, &ts); }