mirror of
https://github.com/espressif/openthread.git
synced 2026-08-22 02:19:52 +00:00
[message-queue] enable adding a message to head of queue (#2246)
This commit updates the `MessageQueue` implementation to allow messages to be added to head/front of the queue. It adds new methods to the `MessageQueue` class and a corresponding one in public OpenThread APIs (`otMessageQueueEnqueueAtHead()`). This commit also updates the `test_message_queue` unit test to add cases/scenarios for testing the new methods and public APIs.
This commit is contained in:
committed by
Jonathan Hui
parent
95f744fbb4
commit
2578a7bf8c
@@ -238,7 +238,6 @@ typedef struct
|
||||
} otMessageQueue;
|
||||
|
||||
/**
|
||||
*
|
||||
* Initialize the message queue.
|
||||
*
|
||||
* This function MUST be called once and only once for a `otMessageQueue` instance before any other `otMessageQueue`
|
||||
@@ -262,6 +261,18 @@ void otMessageQueueInit(otMessageQueue *aQueue);
|
||||
*/
|
||||
otError otMessageQueueEnqueue(otMessageQueue *aQueue, otMessage *aMessage);
|
||||
|
||||
/**
|
||||
* This function adds a message at the head/front of the given message queue.
|
||||
*
|
||||
* @param[in] aQueue A pointer to the message queue.
|
||||
* @param[in] aMessage The message to add.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully added the message to the queue.
|
||||
* @retval OT_ERROR_ALREADY The message is already enqueued in a queue.
|
||||
*
|
||||
*/
|
||||
otError otMessageQueueEnqueueAtHead(otMessageQueue *aQueue, otMessage *aMessage);
|
||||
|
||||
/**
|
||||
* This function removes a message from the given message queue.
|
||||
*
|
||||
|
||||
@@ -123,6 +123,13 @@ otError otMessageQueueEnqueue(otMessageQueue *aQueue, otMessage *aMessage)
|
||||
return queue->Enqueue(*message);
|
||||
}
|
||||
|
||||
otError otMessageQueueEnqueueAtHead(otMessageQueue *aQueue, otMessage *aMessage)
|
||||
{
|
||||
Message *message = static_cast<Message *>(aMessage);
|
||||
MessageQueue *queue = static_cast<MessageQueue *>(aQueue);
|
||||
return queue->Enqueue(*message, MessageQueue::kQueuePositionHead);
|
||||
}
|
||||
|
||||
otError otMessageQueueDequeue(otMessageQueue *aQueue, otMessage *aMessage)
|
||||
{
|
||||
Message *message = static_cast<Message *>(aMessage);
|
||||
|
||||
@@ -811,29 +811,32 @@ MessageQueue::MessageQueue(void)
|
||||
SetTail(NULL);
|
||||
}
|
||||
|
||||
void MessageQueue::AddToList(uint8_t aList, Message &aMessage)
|
||||
void MessageQueue::AddToList(uint8_t aList, Message &aMessage, QueuePosition aPosition)
|
||||
{
|
||||
Message *head;
|
||||
|
||||
assert((aMessage.Next(aList) == NULL) && (aMessage.Prev(aList) == NULL));
|
||||
|
||||
if (GetTail() == NULL)
|
||||
{
|
||||
aMessage.Next(aList) = &aMessage;
|
||||
aMessage.Prev(aList) = &aMessage;
|
||||
|
||||
SetTail(&aMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
head = GetTail()->Next(aList);
|
||||
Message *head = GetTail()->Next(aList);
|
||||
|
||||
aMessage.Next(aList) = head;
|
||||
aMessage.Prev(aList) = GetTail();
|
||||
|
||||
head->Prev(aList) = &aMessage;
|
||||
GetTail()->Next(aList) = &aMessage;
|
||||
}
|
||||
|
||||
SetTail(&aMessage);
|
||||
if (aPosition == kQueuePositionTail)
|
||||
{
|
||||
SetTail(&aMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessageQueue::RemoveFromList(uint8_t aList, Message &aMessage)
|
||||
@@ -862,7 +865,7 @@ Message *MessageQueue::GetHead(void) const
|
||||
return (GetTail() == NULL) ? NULL : GetTail()->Next(MessageInfo::kListInterface);
|
||||
}
|
||||
|
||||
otError MessageQueue::Enqueue(Message &aMessage)
|
||||
otError MessageQueue::Enqueue(Message &aMessage, QueuePosition aPosition)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
@@ -870,7 +873,9 @@ otError MessageQueue::Enqueue(Message &aMessage)
|
||||
|
||||
aMessage.SetMessageQueue(this);
|
||||
|
||||
AddToList(MessageInfo::kListInterface, aMessage);
|
||||
AddToList(MessageInfo::kListInterface, aMessage, aPosition);
|
||||
|
||||
// Any new message is always added to the end of the `AllMessageQueue` list.
|
||||
aMessage.GetMessagePool()->GetAllMessagesQueue()->AddToList(MessageInfo::kListAll, aMessage);
|
||||
|
||||
exit:
|
||||
|
||||
@@ -810,6 +810,18 @@ class MessageQueue : public otMessageQueue
|
||||
friend class PriorityQueue;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* This enumeration represents a position (head or tail) in the queue. This is used to specify where a new message
|
||||
* should be added in the queue.
|
||||
*
|
||||
*/
|
||||
enum QueuePosition
|
||||
{
|
||||
kQueuePositionHead, ///< Indicates the head (front) of the list.
|
||||
kQueuePositionTail, ///< Indicates the tail (end) of the list.
|
||||
};
|
||||
|
||||
/**
|
||||
* This constructor initializes the message queue.
|
||||
*
|
||||
@@ -833,7 +845,19 @@ public:
|
||||
* @retval OT_ERROR_ALREADY The message is already enqueued in a list.
|
||||
*
|
||||
*/
|
||||
otError Enqueue(Message &aMessage);
|
||||
otError Enqueue(Message &aMessage) { return Enqueue(aMessage, kQueuePositionTail); }
|
||||
|
||||
/**
|
||||
* This method adds a message at a given position (head/tail) of the list.
|
||||
*
|
||||
* @param[in] aMessage The message to add.
|
||||
* @param[in] aPosition The position (head or tail) where to add the message.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully added the message to the list.
|
||||
* @retval OT_ERROR_ALREADY The message is already enqueued in a list.
|
||||
*
|
||||
*/
|
||||
otError Enqueue(Message &aMessage, QueuePosition aPosition);
|
||||
|
||||
/**
|
||||
* This method removes a message from the list.
|
||||
@@ -874,13 +898,23 @@ private:
|
||||
void SetTail(Message *aMessage) { mData = aMessage; }
|
||||
|
||||
/**
|
||||
* This method adds a message to a list.
|
||||
* This method adds a message to the end of the list.
|
||||
*
|
||||
* @param[in] aListId The list to add @p aMessage to.
|
||||
* @param[in] aMessage The message to add to @p aListId.
|
||||
*
|
||||
*/
|
||||
void AddToList(uint8_t aListId, Message &aMessage);
|
||||
void AddToList(uint8_t aListId, Message &aMessage) { AddToList(aListId, aMessage, kQueuePositionTail); }
|
||||
|
||||
/**
|
||||
* This method adds a message at a give position (head or tail) of the list.
|
||||
*
|
||||
* @param[in] aListId The list to add @p aMessage to.
|
||||
* @param[in] aMessage The message to add to @p aListId.
|
||||
* @param[in] aPosition The position where to add the message.
|
||||
*
|
||||
*/
|
||||
void AddToList(uint8_t aListId, Message &aMessage, QueuePosition aPosition);
|
||||
|
||||
/**
|
||||
* This method removes a message from a list.
|
||||
|
||||
@@ -103,6 +103,13 @@ void TestMessageQueue(void)
|
||||
SuccessOrQuit(messageQueue.Dequeue(*msg[0]), "MessageQueue::Dequeue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 0);
|
||||
|
||||
// Enqueue 1 message at head and remove it
|
||||
SuccessOrQuit(messageQueue.Enqueue(*msg[0], ot::MessageQueue::kQueuePositionHead),
|
||||
"MessageQueue::Enqueue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 1, msg[0]);
|
||||
SuccessOrQuit(messageQueue.Dequeue(*msg[0]), "MessageQueue::Dequeue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 0);
|
||||
|
||||
// Enqueue 5 messages
|
||||
SuccessOrQuit(messageQueue.Enqueue(*msg[0]), "MessageQueue::Enqueue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 1, msg[0]);
|
||||
@@ -131,18 +138,45 @@ void TestMessageQueue(void)
|
||||
SuccessOrQuit(messageQueue.Dequeue(*msg[4]), "MessageQueue::Dequeue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 2, msg[1], msg[2]);
|
||||
|
||||
// Add after removes
|
||||
// Add after remove
|
||||
SuccessOrQuit(messageQueue.Enqueue(*msg[0]), "MessageQueue::Enqueue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 3, msg[1], msg[2], msg[0]);
|
||||
SuccessOrQuit(messageQueue.Enqueue(*msg[3]), "MessageQueue::Enqueue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 4, msg[1], msg[2], msg[0], msg[3]);
|
||||
|
||||
// Remove all messages
|
||||
// Remove from middle
|
||||
SuccessOrQuit(messageQueue.Dequeue(*msg[2]), "MessageQueue::Dequeue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 3, msg[1], msg[0], msg[3]);
|
||||
|
||||
// Add to head
|
||||
SuccessOrQuit(messageQueue.Enqueue(*msg[2], ot::MessageQueue::kQueuePositionHead),
|
||||
"MessageQueue::Enqueue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 4, msg[2], msg[1], msg[0], msg[3]);
|
||||
|
||||
// Remove from head
|
||||
SuccessOrQuit(messageQueue.Dequeue(*msg[2]), "MessageQueue::Dequeue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 3, msg[1], msg[0], msg[3]);
|
||||
|
||||
// Remove from head
|
||||
SuccessOrQuit(messageQueue.Dequeue(*msg[1]), "MessageQueue::Dequeue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 2, msg[0], msg[3]);
|
||||
|
||||
// Add to head
|
||||
SuccessOrQuit(messageQueue.Enqueue(*msg[1], ot::MessageQueue::kQueuePositionHead),
|
||||
"MessageQueue::Enqueue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 3, msg[1], msg[0], msg[3]);
|
||||
|
||||
// Add to tail
|
||||
SuccessOrQuit(messageQueue.Enqueue(*msg[2], ot::MessageQueue::kQueuePositionTail),
|
||||
"MessageQueue::Enqueue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 4, msg[1], msg[0], msg[3], msg[2]);
|
||||
|
||||
// Remove all messages.
|
||||
SuccessOrQuit(messageQueue.Dequeue(*msg[3]), "MessageQueue::Dequeue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 3, msg[1], msg[0], msg[2]);
|
||||
SuccessOrQuit(messageQueue.Dequeue(*msg[1]), "MessageQueue::Dequeue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 2, msg[0], msg[2]);
|
||||
SuccessOrQuit(messageQueue.Dequeue(*msg[2]), "MessageQueue::Dequeue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 1, msg[0]);
|
||||
SuccessOrQuit(messageQueue.Dequeue(*msg[0]), "MessageQueue::Dequeue() failed.\n");
|
||||
VerifyMessageQueueContent(messageQueue, 0);
|
||||
@@ -222,14 +256,14 @@ void TestMessageQueueOtApis(void)
|
||||
VerifyMessageQueueContentUsingOtApi(&queue, 1, msg[0]);
|
||||
SuccessOrQuit(otMessageQueueEnqueue(&queue, msg[1]), "Failed to enqueue a message to otMessageQueue.\n");
|
||||
VerifyMessageQueueContentUsingOtApi(&queue, 2, msg[0], msg[1]);
|
||||
SuccessOrQuit(otMessageQueueEnqueue(&queue, msg[2]), "Failed to enqueue a message to otMessageQueue.\n");
|
||||
VerifyMessageQueueContentUsingOtApi(&queue, 3, msg[0], msg[1], msg[2]);
|
||||
SuccessOrQuit(otMessageQueueEnqueueAtHead(&queue, msg[2]), "Failed to enqueue a message to otMessageQueue.\n");
|
||||
VerifyMessageQueueContentUsingOtApi(&queue, 3, msg[2], msg[0], msg[1]);
|
||||
SuccessOrQuit(otMessageQueueEnqueue(&queue, msg[3]), "Failed to enqueue a message to otMessageQueue.\n");
|
||||
VerifyMessageQueueContentUsingOtApi(&queue, 4, msg[0], msg[1], msg[2], msg[3]);
|
||||
VerifyMessageQueueContentUsingOtApi(&queue, 4, msg[2], msg[0], msg[1], msg[3]);
|
||||
|
||||
// Remove elements and check the content
|
||||
SuccessOrQuit(otMessageQueueDequeue(&queue, msg[1]), "Failed to dequeue a message from otMessageQueue.\n");
|
||||
VerifyMessageQueueContentUsingOtApi(&queue, 3, msg[0], msg[2], msg[3]);
|
||||
VerifyMessageQueueContentUsingOtApi(&queue, 3, msg[2], msg[0], msg[3]);
|
||||
SuccessOrQuit(otMessageQueueDequeue(&queue, msg[0]), "Failed to dequeue a message from otMessageQueue.\n");
|
||||
VerifyMessageQueueContentUsingOtApi(&queue, 2, msg[2], msg[3]);
|
||||
SuccessOrQuit(otMessageQueueDequeue(&queue, msg[3]), "Failed to dequeue a message from otMessageQueue.\n");
|
||||
|
||||
Reference in New Issue
Block a user