summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/fmq/MessageQueueBase.h77
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;
}