Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2017 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
Hector Dearman | e1e56b6 | 2018-02-21 19:11:58 +0000 | [diff] [blame] | 17 | #ifndef INCLUDE_PERFETTO_PROTOZERO_MESSAGE_HANDLE_H_ |
| 18 | #define INCLUDE_PERFETTO_PROTOZERO_MESSAGE_HANDLE_H_ |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 19 | |
| 20 | #include <functional> |
| 21 | |
Oystein Eftevaag | a812a94 | 2018-03-23 11:52:32 -0700 | [diff] [blame] | 22 | #include "perfetto/base/export.h" |
Hector Dearman | e1e56b6 | 2018-02-21 19:11:58 +0000 | [diff] [blame] | 23 | #include "perfetto/protozero/message.h" |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 24 | |
| 25 | namespace protozero { |
| 26 | |
Hector Dearman | aaa4c19 | 2018-02-19 11:57:35 +0000 | [diff] [blame] | 27 | class Message; |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 28 | |
Hector Dearman | aaa4c19 | 2018-02-19 11:57:35 +0000 | [diff] [blame] | 29 | // MessageHandle allows to decouple the lifetime of a proto message |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 30 | // from the underlying storage. It gives the following guarantees: |
| 31 | // - The underlying message is finalized (if still alive) if the handle goes |
| 32 | // out of scope. |
| 33 | // - In Debug / DCHECK_ALWAYS_ON builds, the handle becomes null once the |
| 34 | // message is finalized. This is to enforce the append-only API. For instance |
| 35 | // when adding two repeated messages, the addition of the 2nd one forces |
| 36 | // the finalization of the first. |
Hector Dearman | aaa4c19 | 2018-02-19 11:57:35 +0000 | [diff] [blame] | 37 | // Think about this as a WeakPtr<Message> which calls |
| 38 | // Message::Finalize() when going out of scope. |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 39 | |
Oystein Eftevaag | a812a94 | 2018-03-23 11:52:32 -0700 | [diff] [blame] | 40 | class PERFETTO_EXPORT MessageHandleBase { |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 41 | public: |
Hector Dearman | aaa4c19 | 2018-02-19 11:57:35 +0000 | [diff] [blame] | 42 | ~MessageHandleBase(); |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 43 | |
| 44 | // Move-only type. |
Hector Dearman | aaa4c19 | 2018-02-19 11:57:35 +0000 | [diff] [blame] | 45 | MessageHandleBase(MessageHandleBase&&) noexcept; |
| 46 | MessageHandleBase& operator=(MessageHandleBase&&); |
Primiano Tucci | d52e627 | 2018-04-06 19:06:53 +0200 | [diff] [blame] | 47 | explicit operator bool() const { |
Florian Mayer | 8a8044f | 2018-01-11 16:03:09 +0000 | [diff] [blame] | 48 | #if PERFETTO_DCHECK_IS_ON() |
| 49 | PERFETTO_DCHECK(!message_ || generation_ == message_->generation_); |
| 50 | #endif |
Primiano Tucci | d52e627 | 2018-04-06 19:06:53 +0200 | [diff] [blame] | 51 | return !!message_; |
Florian Mayer | 8a8044f | 2018-01-11 16:03:09 +0000 | [diff] [blame] | 52 | } |
Primiano Tucci | d52e627 | 2018-04-06 19:06:53 +0200 | [diff] [blame] | 53 | |
| 54 | protected: |
| 55 | explicit MessageHandleBase(Message* = nullptr); |
Hector Dearman | aaa4c19 | 2018-02-19 11:57:35 +0000 | [diff] [blame] | 56 | Message* operator->() const { |
Florian Mayer | 8a8044f | 2018-01-11 16:03:09 +0000 | [diff] [blame] | 57 | #if PERFETTO_DCHECK_IS_ON() |
| 58 | PERFETTO_DCHECK(!message_ || generation_ == message_->generation_); |
| 59 | #endif |
| 60 | return message_; |
| 61 | } |
Primiano Tucci | d52e627 | 2018-04-06 19:06:53 +0200 | [diff] [blame] | 62 | Message& operator*() const { return *(operator->()); } |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 63 | |
| 64 | private: |
Hector Dearman | aaa4c19 | 2018-02-19 11:57:35 +0000 | [diff] [blame] | 65 | friend class Message; |
| 66 | MessageHandleBase(const MessageHandleBase&) = delete; |
| 67 | MessageHandleBase& operator=(const MessageHandleBase&) = delete; |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 68 | |
| 69 | void reset_message() { message_ = nullptr; } |
Hector Dearman | aaa4c19 | 2018-02-19 11:57:35 +0000 | [diff] [blame] | 70 | void Move(MessageHandleBase&&); |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 71 | |
Hector Dearman | aaa4c19 | 2018-02-19 11:57:35 +0000 | [diff] [blame] | 72 | Message* message_; |
Florian Mayer | 8a8044f | 2018-01-11 16:03:09 +0000 | [diff] [blame] | 73 | #if PERFETTO_DCHECK_IS_ON() |
| 74 | uint32_t generation_; |
| 75 | #endif |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 76 | }; |
| 77 | |
| 78 | template <typename T> |
Hector Dearman | aaa4c19 | 2018-02-19 11:57:35 +0000 | [diff] [blame] | 79 | class MessageHandle : public MessageHandleBase { |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 80 | public: |
Hector Dearman | aaa4c19 | 2018-02-19 11:57:35 +0000 | [diff] [blame] | 81 | MessageHandle() : MessageHandle(nullptr) {} |
| 82 | explicit MessageHandle(T* message) : MessageHandleBase(message) {} |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 83 | |
| 84 | T& operator*() const { |
Hector Dearman | aaa4c19 | 2018-02-19 11:57:35 +0000 | [diff] [blame] | 85 | return static_cast<T&>(MessageHandleBase::operator*()); |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | T* operator->() const { |
Hector Dearman | aaa4c19 | 2018-02-19 11:57:35 +0000 | [diff] [blame] | 89 | return static_cast<T*>(MessageHandleBase::operator->()); |
Primiano Tucci | 4f9b6d7 | 2017-12-05 20:59:16 +0000 | [diff] [blame] | 90 | } |
| 91 | }; |
| 92 | |
| 93 | } // namespace protozero |
| 94 | |
Hector Dearman | e1e56b6 | 2018-02-21 19:11:58 +0000 | [diff] [blame] | 95 | #endif // INCLUDE_PERFETTO_PROTOZERO_MESSAGE_HANDLE_H_ |