linux mq update

This commit is contained in:
Robin Müller 2020-06-10 01:07:50 +02:00
parent b1f91439c6
commit 3277d199ac

View File

@ -56,16 +56,23 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes,
sif::error << "MessageQueue::MessageQueue: Invalid name or attributes" sif::error << "MessageQueue::MessageQueue: Invalid name or attributes"
" for message size" << std::endl; " for message size" << std::endl;
size_t defaultMqMaxMsg = 0; size_t defaultMqMaxMsg = 0;
// Not POSIX conformant, but should work for all UNIX systems.
// Just an additional helpful printout :-)
if(std::ifstream("/proc/sys/fs/mqueue/msg_max",std::ios::in) >> if(std::ifstream("/proc/sys/fs/mqueue/msg_max",std::ios::in) >>
defaultMqMaxMsg and defaultMqMaxMsg < messageDepth) { defaultMqMaxMsg and defaultMqMaxMsg < messageDepth) {
// See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html // See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html
// This happens if the msg_max value is not large enough // This happens if the msg_max value is not large enough
// It is ignored if the executable is run in privileged mode. // It is ignored if the executable is run in privileged mode.
// Run the unlockRealtime script or grant the mode manully by using: // Run the unlockRealtime script or grant the mode manually by using:
// sudo setcap 'CAP_SYS_RESOURCE=+ep' <pathToBinary> // sudo setcap 'CAP_SYS_RESOURCE=+ep' <pathToBinary>
// Permanent solution (EventManager has mq depth of 80): // Persistent solution for session:
// echo msg_max | sudo tee /proc/sys/fs/mqueue/msg_max // echo <newMsgMax> | sudo tee /proc/sys/fs/mqueue/msg_max
// Permanent solution:
// sudo nano /etc/sysctl.conf
// Append at end: fs/mqueue/msg_max = <newMsgMaxLen>
// Apply changes with: sudo sysctl -p
sif::error << "MessageQueue::MessageQueue: Default MQ size " sif::error << "MessageQueue::MessageQueue: Default MQ size "
<< defaultMqMaxMsg << " is too small for requested size " << defaultMqMaxMsg << " is too small for requested size "
<< messageDepth << std::endl; << messageDepth << std::endl;
@ -75,7 +82,6 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes,
case(EEXIST): { case(EEXIST): {
// An error occured during open // An error occured during open
// We need to distinguish if it is caused by an already created queue // We need to distinguish if it is caused by an already created queue
if (errno == EEXIST) {
//There's another queue with the same name //There's another queue with the same name
//We unlink the other queue //We unlink the other queue
int status = mq_unlink(name); int status = mq_unlink(name);
@ -94,7 +100,6 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes,
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
} }
}
break; break;
} }
@ -150,12 +155,13 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) {
//Success but no message received //Success but no message received
return MessageQueueIF::EMPTY; return MessageQueueIF::EMPTY;
} else { } else {
//No message was received. Keep lastPartner anyway, I might send something later. //No message was received. Keep lastPartner anyway, I might send
//But still, delete packet content. //something later. But still, delete packet content.
memset(message->getData(), 0, message->MAX_DATA_SIZE); memset(message->getData(), 0, message->MAX_DATA_SIZE);
switch(errno){ switch(errno){
case EAGAIN: case EAGAIN:
//O_NONBLOCK or MQ_NONBLOCK was set and there are no messages currently on the specified queue. //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages
//currently on the specified queue.
return MessageQueueIF::EMPTY; return MessageQueueIF::EMPTY;
case EBADF: case EBADF:
//mqdes doesn't represent a valid queue open for reading. //mqdes doesn't represent a valid queue open for reading.
@ -165,9 +171,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) {
case EINVAL: case EINVAL:
/* /*
* This value indicates one of the following: * This value indicates one of the following:
* * The pointer to the buffer for storing the received message, msg_ptr, is NULL. * - The pointer to the buffer for storing the received message,
* * The number of bytes requested, msg_len is less than zero. * msg_ptr, is NULL.
* * msg_len is anything other than the mq_msgsize of the specified queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't been set in the queue's mq_flags. * - The number of bytes requested, msg_len is less than zero.
* - msg_len is anything other than the mq_msgsize of the specified
* queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't
* been set in the queue's mq_flags.
*/ */
sif::error << "MessageQueue::receive: configuration error " sif::error << "MessageQueue::receive: configuration error "
<< strerror(errno) << std::endl; << strerror(errno) << std::endl;
@ -175,8 +184,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) {
case EMSGSIZE: case EMSGSIZE:
/* /*
* This value indicates one of the following: * This value indicates one of the following:
* * the QNX extended option MQ_READBUF_DYNAMIC hasn't been set, and the given msg_len is shorter than the mq_msgsize for the given queue. * - the QNX extended option MQ_READBUF_DYNAMIC hasn't been set,
* * the extended option MQ_READBUF_DYNAMIC has been set, but the given msg_len is too short for the message that would have been received. * and the given msg_len is shorter than the mq_msgsize for
* the given queue.
* - the extended option MQ_READBUF_DYNAMIC has been set, but the
* given msg_len is too short for the message that would have
* been received.
*/ */
sif::error << "MessageQueue::receive: configuration error " sif::error << "MessageQueue::receive: configuration error "
<< strerror(errno) << std::endl; << strerror(errno) << std::endl;
@ -224,9 +237,10 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) {
case EINVAL: case EINVAL:
/* /*
* This value indicates one of the following: * This value indicates one of the following:
* * mq_attr is NULL. * - mq_attr is NULL.
* * MQ_MULT_NOTIFY had been set for this queue, and the given mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once MQ_MULT_NOTIFY has been turned on, it may never be turned off. * - MQ_MULT_NOTIFY had been set for this queue, and the given
* * mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once
* MQ_MULT_NOTIFY has been turned on, it may never be turned off.
*/ */
default: default:
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
@ -275,7 +289,8 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
//TODO: Check if we're in ISR. //TODO: Check if we're in ISR.
if (result != 0) { if (result != 0) {
if(!ignoreFault){ if(!ignoreFault){
InternalErrorReporterIF* internalErrorReporter = objectManager->get<InternalErrorReporterIF>( InternalErrorReporterIF* internalErrorReporter =
objectManager->get<InternalErrorReporterIF>(
objects::INTERNAL_ERROR_REPORTER); objects::INTERNAL_ERROR_REPORTER);
if (internalErrorReporter != NULL) { if (internalErrorReporter != NULL) {
internalErrorReporter->queueMessageNotSent(); internalErrorReporter->queueMessageNotSent();
@ -283,10 +298,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
} }
switch(errno){ switch(errno){
case EAGAIN: case EAGAIN:
//The O_NONBLOCK flag was set when opening the queue, or the MQ_NONBLOCK flag was set in its attributes, and the specified queue is full. //The O_NONBLOCK flag was set when opening the queue, or the
//MQ_NONBLOCK flag was set in its attributes, and the
//specified queue is full.
return MessageQueueIF::FULL; return MessageQueueIF::FULL;
case EBADF: case EBADF:
//mq_des doesn't represent a valid message queue descriptor, or mq_des wasn't opened for writing. //mq_des doesn't represent a valid message queue descriptor,
//or mq_des wasn't opened for writing.
sif::error << "MessageQueue::sendMessage: Configuration error " sif::error << "MessageQueue::sendMessage: Configuration error "
<< strerror(errno) << " in mq_send mqSendTo: " << sendTo << strerror(errno) << " in mq_send mqSendTo: " << sendTo
<< " sent from " << sentFrom << std::endl; << " sent from " << sentFrom << std::endl;
@ -296,13 +314,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
case EINVAL: case EINVAL:
/* /*
* This value indicates one of the following: * This value indicates one of the following:
* * msg_ptr is NULL. * - msg_ptr is NULL.
* * msg_len is negative. * - msg_len is negative.
* * msg_prio is greater than MQ_PRIO_MAX. * - msg_prio is greater than MQ_PRIO_MAX.
* * msg_prio is less than 0. * - msg_prio is less than 0.
* * MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, * - MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, and
* and msg_prio is greater than the priority of the calling process. * msg_prio is greater than the priority of the calling process.
* */ */
sif::error << "MessageQueue::sendMessage: Configuration error " sif::error << "MessageQueue::sendMessage: Configuration error "
<< strerror(errno) << " in mq_send" << std::endl; << strerror(errno) << " in mq_send" << std::endl;
/*NO BREAK*/ /*NO BREAK*/