created unique_ptr for RawQueue messages and used it
diff --git a/aos/atom_code/camera/Buffers.cpp b/aos/atom_code/camera/Buffers.cpp
index d0d20f5..37a707b 100644
--- a/aos/atom_code/camera/Buffers.cpp
+++ b/aos/atom_code/camera/Buffers.cpp
@@ -61,24 +61,21 @@
}
void Buffers::Release() {
- if (message_ != NULL) {
- queue_->FreeMessage(message_);
- message_ = NULL;
- }
+ message_.reset();
}
-const void *Buffers::GetNext(bool block,
- uint32_t *bytesused, timeval *timestamp, uint32_t *sequence) {
+const void *Buffers::GetNext(bool block, uint32_t *bytesused,
+ timeval *timestamp, uint32_t *sequence) {
Release();
// TODO(brians) make sure the camera reader process hasn't died
do {
if (block) {
- message_ = static_cast<const Message *>(queue_->ReadMessage(
- RawQueue::kPeek | RawQueue::kBlock));
+ message_.reset(static_cast<const Message *>(
+ queue_->ReadMessage(RawQueue::kPeek | RawQueue::kBlock)));
} else {
static int index = 0;
- message_ = static_cast<const Message *>(queue_->ReadMessageIndex(
- RawQueue::kBlock, &index));
+ message_.reset(static_cast<const Message *>(
+ queue_->ReadMessageIndex(RawQueue::kBlock, &index)));
}
} while (block && message_ == NULL);
if (message_ != NULL) {
@@ -132,9 +129,12 @@
return myfds[0];
}
-Buffers::Buffers() : server_(CreateSocket(connect)), fd_(FetchFD()), message_(NULL) {
+Buffers::Buffers()
+ : server_(CreateSocket(connect)),
+ fd_(FetchFD()),
+ queue_(RawQueue::Fetch(kQueueName.c_str(), sizeof(Message), 971, 1)),
+ message_(queue_) {
MMap();
- queue_ = RawQueue::Fetch(kQueueName.c_str(), sizeof(Message), 971, 1);
}
Buffers::~Buffers() {
diff --git a/aos/atom_code/camera/Buffers.h b/aos/atom_code/camera/Buffers.h
index 080e9eb..d1f49b8 100644
--- a/aos/atom_code/camera/Buffers.h
+++ b/aos/atom_code/camera/Buffers.h
@@ -8,6 +8,7 @@
#include "aos/atom_code/ipc_lib/queue.h"
#include "aos/common/type_traits.h"
+#include "aos/atom_code/ipc_lib/unique_message_ptr.h"
namespace aos {
namespace camera {
@@ -17,6 +18,7 @@
// It has to do a lot of the same things as all the other ones, but it gets
// the information from different places (some of it gets sent out by it).
friend class Reader;
+
// Not an abstract name so that an existing one can just be unlinked without
// disturbing it if necessary (like with shm_link).
static const std::string kFDServerName;
@@ -50,14 +52,17 @@
uint32_t sequence;
};
static_assert(shm_ok<Message>::value, "it's going through queues");
- // The current one. Sometimes NULL.
- const Message *message_;
- static const std::string kQueueName;
+
// NULL for the Reader one.
- RawQueue *queue_;
+ RawQueue *const queue_;
+ // The current one. Sometimes NULL.
+ unique_message_ptr<const Message> message_;
+
+ static const std::string kQueueName;
// Make the actual mmap calls.
// Called by Buffers() automatically.
void MMap();
+
public:
Buffers();
// Will clean everything up.
@@ -89,4 +94,3 @@
} // namespace aos
#endif
-
diff --git a/aos/atom_code/camera/camera.gyp b/aos/atom_code/camera/camera.gyp
index f1743be..a8865bd 100644
--- a/aos/atom_code/camera/camera.gyp
+++ b/aos/atom_code/camera/camera.gyp
@@ -47,9 +47,11 @@
'dependencies': [
'<(AOS)/atom_code/ipc_lib/ipc_lib.gyp:queue',
'<(AOS)/build/aos.gyp:logging',
+ '<(AOS)/atom_code/ipc_lib/ipc_lib.gyp:scoped_message_ptr',
],
'export_dependent_settings': [
'<(AOS)/atom_code/ipc_lib/ipc_lib.gyp:queue',
+ '<(AOS)/atom_code/ipc_lib/ipc_lib.gyp:scoped_message_ptr',
],
},
{
diff --git a/aos/atom_code/ipc_lib/ipc_lib.gyp b/aos/atom_code/ipc_lib/ipc_lib.gyp
index af9d779..229c66c 100644
--- a/aos/atom_code/ipc_lib/ipc_lib.gyp
+++ b/aos/atom_code/ipc_lib/ipc_lib.gyp
@@ -82,5 +82,18 @@
'is_special_test': 1,
},
},
+ {
+ 'target_name': 'scoped_message_ptr',
+ 'type': 'static_library',
+ 'sources': [
+ #'scoped_message_ptr.h',
+ ],
+ 'dependencies': [
+ 'queue',
+ ],
+ 'export_dependent_settings': [
+ 'queue',
+ ],
+ },
],
}
diff --git a/aos/atom_code/ipc_lib/unique_message_ptr.h b/aos/atom_code/ipc_lib/unique_message_ptr.h
new file mode 100644
index 0000000..e30a4c0
--- /dev/null
+++ b/aos/atom_code/ipc_lib/unique_message_ptr.h
@@ -0,0 +1,39 @@
+#include <memory>
+
+#include "aos/atom_code/ipc_lib/queue.h"
+
+namespace aos {
+namespace internal {
+
+template<typename T>
+class queue_free {
+ public:
+ queue_free(RawQueue *queue) : queue_(queue) {}
+
+ void operator()(const T *message) {
+ queue_->FreeMessage(static_cast<const void *>(message));
+ }
+
+ private:
+ RawQueue *const queue_;
+};
+
+} // namespace internal
+
+template<typename T>
+class unique_message_ptr : public ::std::unique_ptr<T, ::aos::internal::queue_free<T>> {
+ public:
+ unique_message_ptr(RawQueue *queue, T *message = NULL)
+ : ::std::unique_ptr<T, ::aos::internal::queue_free<T>>(message, ::aos::internal::queue_free<T>(queue)) {}
+
+ // Perfectly forward this so that the move functionality of ::std::unique_ptr
+ // works.
+ template <typename... Args>
+ unique_message_ptr<T> &operator=(Args &&... args) {
+ ::std::unique_ptr<T, ::aos::internal::queue_free<T>>::operator=(
+ ::std::forward<Args>(args)...);
+ return *this;
+ }
+};
+
+} // namespace aos