int test_is_empty() { message_queue* mq = NULL; mq_allocate(&mq); MessageEnvelope* env = (MessageEnvelope*)malloc(sizeof(MessageEnvelope)); mq_enqueue(env, mq); if (mq_is_empty(mq)) { return 0; } mq_free(&mq); return 1; }
//Queue deallocators //called at cleanup void mq_free(message_queue* mq) { assert(mq != NULL); MessageEnvelope* env = NULL; while (!mq_is_empty(mq)) { env = mq_dequeue(mq); assert(env != NULL); free(env); } free(mq); }
MessageEnvelope* mq_dequeue(message_queue* mq) { assert(mq != NULL); if (mq_is_empty(mq)) return NULL; MessageEnvelope* deq = mq->head; mq->head = (mq->head)->next; if (mq->head == NULL) mq->tail = NULL; deq->next = NULL; return deq; }
void mq_enqueue(MessageEnvelope* env, message_queue* mq) { assert(env != NULL && mq != NULL); env->next = NULL; if (mq_is_empty(mq)) { mq->head = env; mq->tail = mq->head; } else { (mq->tail)->next = env; mq->tail = env; } }
/** * Retrieve CAN message from RX queue. * * @frame: CAN message about to fill-in . * * @return: On success, return frame address. * Return NULL if the queue is empty. * * NOTE: Pushing to the queue will block this function. */ struct can_frame *rx_queue_pop(struct can_frame *frame) { struct can_frame *frm = NULL; if (!mq_is_empty(rxq)) { sync_spinlock_lock(&rxq->lock); mq_remove_msg(rxq, frame); sync_spinlock_unlock(&rxq->lock); frm = frame; } return frm; }
MessageEnvelope* mq_remove(MessageEnvelope* target, message_queue* mq) { assert(target != NULL && mq != NULL); MessageEnvelope* next = mq->head; if (mq_is_empty(mq)) return NULL; if (target == mq->head) { mq->head = (mq->head)->next; return target; } while (next->next != target && next->next != NULL) { next = next->next; } if (next->next == target) { if (next->next == mq->tail) { mq->tail = next; next->next = NULL; return target; } next->next = (next->next)->next; return target; } else { return NULL; } }