diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 48ba29e8..d12fa720 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -1,14 +1,14 @@ #include +#include #include /* For O_* constants */ #include /* For mode constants */ -#include #include #include -#include -MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): - id(0), lastPartner(0), defaultDestination(NO_QUEUE) { + +MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): id(0), + lastPartner(0), defaultDestination(NO_QUEUE) { //debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl; mq_attr attributes; this->id = 0; @@ -17,40 +17,17 @@ MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): attributes.mq_maxmsg = messageDepth; attributes.mq_msgsize = maxMessageSize; attributes.mq_flags = 0; //Flags are ignored on Linux during mq_open - //Set the name of the queue + //Set the name of the queue. The slash is mandatory! sprintf(name, "/Q%u\n", queueCounter++); - //Create a nonblocking queue if the name is available (the queue is Read and - // writable for the owner as well as the group) + // Create a nonblocking queue if the name is available (the queue is read + // and writable for the owner as well as the group) mqd_t tempId = mq_open(name, O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH, &attributes); if (tempId == -1) { - //An error occured during open - //We need to distinguish if it is caused by an already created queue - if (errno == EEXIST) { - //There's another queue with the same name - //We unlink the other queue - int status = mq_unlink(name); - if (status != 0) { - sif::error << "mq_unlink Failed with status: " << strerror(errno) - << std::endl; - } else { - //Successful unlinking, try to open again - mqd_t tempId = mq_open(name, - O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, - S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, &attributes); - if (tempId != -1) { - //Successful mq_open - this->id = tempId; - return; - } - } - } - //Failed either the first time or the second time - sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex - << name << std::dec << " failed with status: " - << strerror(errno) << std::endl; - } else { + ReturnValue_t result = handleError(&attributes); + } + else { //Successful mq_open call this->id = tempId; } @@ -69,6 +46,37 @@ MessageQueue::~MessageQueue() { } } +ReturnValue_t MessageQueue::handleError(mq_attr* attributes) { + // An error occured during open + // We need to distinguish if it is caused by an already created queue + if (errno == EEXIST) { + //There's another queue with the same name + //We unlink the other queue + int status = mq_unlink(name); + if (status != 0) { + sif::error << "mq_unlink Failed with status: " << strerror(errno) + << std::endl; + } + else { + // Successful unlinking, try to open again + mqd_t tempId = mq_open(name, + O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, + S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes); + if (tempId != -1) { + //Successful mq_open + this->id = tempId; + return HasReturnvaluesIF::RETURN_OK; + } + } + // Failed either the first time or the second time + sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex + << name << std::dec << " failed with status: " + << strerror(errno) << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + +} + ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, MessageQueueMessage* message, bool ignoreFault) { return sendMessageFrom(sendTo, message, this->getId(), false); diff --git a/osal/linux/MessageQueue.h b/osal/linux/MessageQueue.h index fdc8dab1..b44ed5c7 100644 --- a/osal/linux/MessageQueue.h +++ b/osal/linux/MessageQueue.h @@ -4,6 +4,8 @@ #include #include #include + +#include /** * @brief This class manages sending and receiving of message queue messages. * @@ -172,6 +174,8 @@ private: char name[5]; static uint16_t queueCounter; + + ReturnValue_t handleError(mq_attr* attributes); }; #endif /* MESSAGEQUEUE_H_ */