blob: 136251559af248d474695d41c999cbe3ef9c474b [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001namespace aos {
2
3template <class T>
4bool ScopedMessagePtr<T>::Send() {
5 assert(msg_ != NULL);
6 msg_->SetTimeToNow();
7 assert(queue_ != NULL);
Brian Silverman08661c72013-09-01 17:24:38 -07008 bool return_value = queue_->WriteMessage(msg_, RawQueue::kOverride);
brians343bc112013-02-10 01:53:46 +00009 msg_ = NULL;
10 return return_value;
11}
12
13template <class T>
14bool ScopedMessagePtr<T>::SendBlocking() {
15 assert(msg_ != NULL);
16 msg_->SetTimeToNow();
17 assert(queue_ != NULL);
Brian Silverman08661c72013-09-01 17:24:38 -070018 bool return_value = queue_->WriteMessage(msg_, RawQueue::kBlock);
brians343bc112013-02-10 01:53:46 +000019 msg_ = NULL;
20 return return_value;
21}
22
23template <class T>
24void ScopedMessagePtr<T>::reset(T *msg) {
25 if (queue_ != NULL && msg_ != NULL) {
Brian Silverman078aee92013-11-12 22:17:05 -080026 queue_->FreeMessage(msg_);
brians343bc112013-02-10 01:53:46 +000027 }
28 msg_ = msg;
29}
30
brians343bc112013-02-10 01:53:46 +000031template <class T>
32void Queue<T>::Init() {
33 if (queue_ == NULL) {
Brian Silverman08661c72013-09-01 17:24:38 -070034 queue_ = RawQueue::Fetch(queue_name_, sizeof(T),
35 static_cast<int>(T::kHash),
36 T::kQueueLength);
brians343bc112013-02-10 01:53:46 +000037 queue_msg_.set_queue(queue_);
38 }
39}
40
41template <class T>
Austin Schuhdc1c84a2013-02-23 16:33:10 -080042void Queue<T>::Clear() {
Austin Schuhfa033692013-02-24 01:00:55 -080043 if (queue_ != NULL) {
Austin Schuhdc1c84a2013-02-23 16:33:10 -080044 queue_msg_.reset();
45 queue_ = NULL;
46 queue_msg_.set_queue(NULL);
47 }
Brian Silvermand8a7cf02014-03-22 17:15:23 -070048 index_ = 0;
Austin Schuhdc1c84a2013-02-23 16:33:10 -080049}
50
51template <class T>
brians343bc112013-02-10 01:53:46 +000052bool Queue<T>::FetchNext() {
53 Init();
Brian Silverman08661c72013-09-01 17:24:38 -070054 const T *msg = static_cast<const T *>(
Austin Schuh287d98e2014-03-09 00:41:55 -080055 queue_->ReadMessageIndex(RawQueue::kNonBlock, &index_));
brians343bc112013-02-10 01:53:46 +000056 // Only update the internal pointer if we got a new message.
57 if (msg != NULL) {
58 queue_msg_.reset(msg);
59 }
60 return msg != NULL;
61}
62
63template <class T>
Brian Silverman428de562014-04-10 15:59:19 -070064void Queue<T>::FetchNextBlocking() {
brians343bc112013-02-10 01:53:46 +000065 Init();
Brian Silverman428de562014-04-10 15:59:19 -070066 const T *msg = static_cast<const T *>(
67 queue_->ReadMessageIndex(RawQueue::kBlock, &index_));
brians343bc112013-02-10 01:53:46 +000068 queue_msg_.reset(msg);
69 assert (msg != NULL);
brians343bc112013-02-10 01:53:46 +000070}
71
72template <class T>
73bool Queue<T>::FetchLatest() {
74 Init();
Brian Silverman7faaec72014-05-26 16:25:38 -070075 static constexpr Options<RawQueue> kOptions =
76 RawQueue::kFromEnd | RawQueue::kNonBlock;
77 const T *msg =
78 static_cast<const T *>(queue_->ReadMessageIndex(kOptions, &index_));
brians343bc112013-02-10 01:53:46 +000079 // Only update the internal pointer if we got a new message.
80 if (msg != NULL && msg != queue_msg_.get()) {
81 queue_msg_.reset(msg);
82 return true;
83 }
Brian Silverman08661c72013-09-01 17:24:38 -070084 // The message has to get freed if we didn't use it (and RawQueue::FreeMessage
85 // is ok to call on NULL).
86 queue_->FreeMessage(msg);
brians343bc112013-02-10 01:53:46 +000087 return false;
88}
89
90template <class T>
Brian Silverman428de562014-04-10 15:59:19 -070091void Queue<T>::FetchAnother() {
92 if (!FetchLatest()) FetchNextBlocking();
93}
94
95template <class T>
brians343bc112013-02-10 01:53:46 +000096ScopedMessagePtr<T> Queue<T>::MakeMessage() {
97 Init();
98 return ScopedMessagePtr<T>(queue_, MakeRawMessage());
99}
100
101template <class T>
102T *Queue<T>::MakeRawMessage() {
Brian Silverman08661c72013-09-01 17:24:38 -0700103 T *ret = static_cast<T *>(queue_->GetMessage());
brians35b15c42013-02-26 04:39:09 +0000104 assert(ret != NULL);
Brian Silvermanc06af4c2015-10-25 01:50:41 -0400105 ret->Zero();
brians35b15c42013-02-26 04:39:09 +0000106 return ret;
brians343bc112013-02-10 01:53:46 +0000107}
108
109template <class T>
110aos::MessageBuilder<T> Queue<T>::MakeWithBuilder() {
111 Init();
Brian Silverman42456d82014-08-19 12:43:59 -0400112 T *const ret = MakeRawMessage();
Brian Silverman42456d82014-08-19 12:43:59 -0400113 return aos::MessageBuilder<T>(queue_, ret);
brians343bc112013-02-10 01:53:46 +0000114}
115
brians343bc112013-02-10 01:53:46 +0000116} // namespace aos