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 
17 #ifndef INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
18 #define INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
19 
20 #include <memory>
21 #include <type_traits>
22 #include <utility>
23 
24 #include "perfetto/ext/ipc/basic_types.h"
25 
26 namespace perfetto {
27 namespace ipc {
28 
29 // Wraps the result of an asynchronous invocation. This is the equivalent of a
30 // std::pair<unique_ptr<T>, bool> with syntactic sugar. It is used as callback
31 // argument by Deferred<T>. T is a ProtoMessage subclass (i.e. generated .pb.h).
32 template <typename T>
33 class AsyncResult {
34  public:
Create()35   static AsyncResult Create() {
36     return AsyncResult(std::unique_ptr<T>(new T()));
37   }
38 
39   AsyncResult(std::unique_ptr<T> msg = nullptr,
40               bool has_more = false,
41               int fd = -1)
msg_(std::move (msg))42       : msg_(std::move(msg)), has_more_(has_more), fd_(fd) {
43     static_assert(std::is_base_of<ProtoMessage, T>::value, "T->ProtoMessage");
44   }
45   AsyncResult(AsyncResult&&) noexcept = default;
46   AsyncResult& operator=(AsyncResult&&) = default;
47 
success()48   bool success() const { return !!msg_; }
49   explicit operator bool() const { return success(); }
50 
has_more()51   bool has_more() const { return has_more_; }
set_has_more(bool has_more)52   void set_has_more(bool has_more) { has_more_ = has_more; }
53 
set_msg(std::unique_ptr<T> msg)54   void set_msg(std::unique_ptr<T> msg) { msg_ = std::move(msg); }
release_msg()55   T* release_msg() { return msg_.release(); }
56   T* operator->() { return msg_.get(); }
57   T& operator*() { return *msg_; }
58 
set_fd(int fd)59   void set_fd(int fd) { fd_ = fd; }
fd()60   int fd() const { return fd_; }
61 
62  private:
63   std::unique_ptr<T> msg_;
64   bool has_more_ = false;
65 
66   // Optional. Only for messages that convey a file descriptor, for sharing
67   // memory across processes.
68   int fd_ = -1;
69 };
70 
71 }  // namespace ipc
72 }  // namespace perfetto
73 
74 #endif  // INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
75