diff options
-rw-r--r-- | include/fmq/MessageQueueBase.h | 77 |
1 files changed, 48 insertions, 29 deletions
diff --git a/include/fmq/MessageQueueBase.h b/include/fmq/MessageQueueBase.h index abffe74..147e964 100644 --- a/include/fmq/MessageQueueBase.h +++ b/include/fmq/MessageQueueBase.h @@ -35,6 +35,10 @@ namespace android { template <template <typename, MQFlavor> class MQDescriptorType, typename T, MQFlavor flavor> struct MessageQueueBase { typedef MQDescriptorType<T, flavor> Descriptor; + enum Error : int { + NONE, + POINTER_CORRUPTION, /** Read/write pointers mismatch */ + }; /** * @param Desc MQDescriptor describing the FMQ. @@ -68,22 +72,28 @@ struct MessageQueueBase { 0) {} /** - * @param pointerCorruptionDetected Optional output parameter which indicates - * a mismatch between internal pointers indicating possible queue memory corruption. + * @param errorDetected Optional output parameter which indicates + * any errors that the client might care about. + * @param errorMessage Optional output parameter for a human-readable + * error description. * * @return Number of items of type T that can be written into the FMQ * without a read. */ - size_t availableToWrite(bool* pointerCorruptionDetected = nullptr) const; + size_t availableToWrite(Error* errorDetected = nullptr, + std::string* errorMessage = nullptr) const; /** - * @param pointerCorruptionDetected Optional output parameter which indicates - * a mismatch between internal pointers indicating possible queue memory corruption. + * @param errorDetected Optional output parameter which indicates + * any errors that the client might care about. + * @param errorMessage Optional output parameter for a human-readable + * error description. * * @return Number of items of type T that are waiting to be read from the * FMQ. */ - size_t availableToRead(bool* pointerCorruptionDetected = nullptr) const; + size_t availableToRead(Error* errorDetected = nullptr, + std::string* errorMessage = nullptr) const; /** * Returns the size of type T in bytes. @@ -433,8 +443,8 @@ struct MessageQueueBase { uint8_t* getRingBufferPtr() const { return mRing; } private: - size_t availableToWriteBytes(bool* pointerCorruptionDetected) const; - size_t availableToReadBytes(bool* pointerCorruptionDetected) const; + size_t availableToWriteBytes(Error* errorDetected, std::string* errorMessage) const; + size_t availableToReadBytes(Error* errorDetected, std::string* errorMessage) const; MessageQueueBase(const MessageQueueBase& other) = delete; MessageQueueBase& operator=(const MessageQueueBase& other) = delete; @@ -1053,35 +1063,43 @@ bool MessageQueueBase<MQDescriptorType, T, flavor>::readBlocking(T* data, size_t template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor> size_t MessageQueueBase<MQDescriptorType, T, flavor>::availableToWriteBytes( - bool* pointerCorruptionDetected) const { + Error* errorDetected, std::string* errorMessage) const { size_t queueSizeBytes = mDesc->getSize(); - size_t availableBytes = availableToReadBytes(pointerCorruptionDetected); + Error localErrorDetected = Error::NONE; + size_t availableBytes = availableToReadBytes(&localErrorDetected, errorMessage); + if (localErrorDetected != Error::NONE) { + if (errorDetected != nullptr) { + *errorDetected = localErrorDetected; + } + return 0; + } if (queueSizeBytes < availableBytes) { - hardware::details::logError( + std::string errorMsg = "The write or read pointer has become corrupted. Writing to the queue is no " "longer possible. Queue size: " + - std::to_string(queueSizeBytes) + ", available: " + std::to_string(availableBytes)); - if (pointerCorruptionDetected != nullptr) { - *pointerCorruptionDetected = true; + std::to_string(queueSizeBytes) + ", available: " + std::to_string(availableBytes); + hardware::details::logError(errorMsg); + if (errorDetected != nullptr) { + *errorDetected = Error::POINTER_CORRUPTION; + } + if (errorMessage != nullptr) { + *errorMessage = std::move(errorMsg); } return 0; } - if (pointerCorruptionDetected != nullptr) { - *pointerCorruptionDetected = false; - } return queueSizeBytes - availableBytes; } template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor> size_t MessageQueueBase<MQDescriptorType, T, flavor>::availableToWrite( - bool* pointerCorruptionDetected) const { - return availableToWriteBytes(pointerCorruptionDetected) / sizeof(T); + Error* errorDetected, std::string* errorMessage) const { + return availableToWriteBytes(errorDetected, errorMessage) / sizeof(T); } template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor> size_t MessageQueueBase<MQDescriptorType, T, flavor>::availableToRead( - bool* pointerCorruptionDetected) const { - return availableToReadBytes(pointerCorruptionDetected) / sizeof(T); + Error* errorDetected, std::string* errorMessage) const { + return availableToReadBytes(errorDetected, errorMessage) / sizeof(T); } template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor> @@ -1154,7 +1172,7 @@ MessageQueueBase<MQDescriptorType, T, flavor>::commitWrite(size_t nMessages) { template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor> size_t MessageQueueBase<MQDescriptorType, T, flavor>::availableToReadBytes( - bool* pointerCorruptionDetected) const { + Error* errorDetected, std::string* errorMessage) const { /* * This method is invoked by implementations of both read() and write() and * hence requires a memory_order_acquired load for both mReadPtr and @@ -1163,18 +1181,19 @@ size_t MessageQueueBase<MQDescriptorType, T, flavor>::availableToReadBytes( uint64_t writePtr = mWritePtr->load(std::memory_order_acquire); uint64_t readPtr = mReadPtr->load(std::memory_order_acquire); if (writePtr < readPtr) { - hardware::details::logError( + std::string errorMsg = "The write or read pointer has become corrupted. Reading from the queue is no " "longer possible. Write pointer: " + - std::to_string(writePtr) + ", read pointer: " + std::to_string(readPtr)); - if (pointerCorruptionDetected != nullptr) { - *pointerCorruptionDetected = true; + std::to_string(writePtr) + ", read pointer: " + std::to_string(readPtr); + hardware::details::logError(errorMsg); + if (errorDetected != nullptr) { + *errorDetected = Error::POINTER_CORRUPTION; + } + if (errorMessage != nullptr) { + *errorMessage = std::move(errorMsg); } return 0; } - if (pointerCorruptionDetected != nullptr) { - *pointerCorruptionDetected = false; - } return writePtr - readPtr; } |