Line data Source code
1 : /*
2 : * If not stated otherwise in this file or this component's LICENSE file the
3 : * following copyright and licenses apply:
4 : *
5 : * Copyright 2022 Sky UK
6 : *
7 : * Licensed under the Apache License, Version 2.0 (the "License");
8 : * you may not use this file except in compliance with the License.
9 : * You may obtain a copy of the License at
10 : *
11 : * http://www.apache.org/licenses/LICENSE-2.0
12 : *
13 : * Unless required by applicable law or agreed to in writing, software
14 : * distributed under the License is distributed on an "AS IS" BASIS,
15 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 : * See the License for the specific language governing permissions and
17 : * limitations under the License.
18 : */
19 :
20 : #ifndef FIREBOLT_RIALTO_IPC_I_IPC_CHANNEL_H_
21 : #define FIREBOLT_RIALTO_IPC_I_IPC_CHANNEL_H_
22 :
23 : #include <google/protobuf/service.h>
24 :
25 : #include <functional>
26 : #include <memory>
27 : #include <string>
28 : #include <utility>
29 :
30 : namespace firebolt::rialto::ipc
31 : {
32 : class IChannel;
33 :
34 : /**
35 : * @brief IChannel factory class, returns a new connected IChannel object
36 : */
37 : class IChannelFactory
38 : {
39 : public:
40 39 : IChannelFactory() = default;
41 39 : virtual ~IChannelFactory() = default;
42 :
43 : /**
44 : * @brief Create a IChannelFactory instance.
45 : *
46 : * @retval the factory instance or null on error.
47 : */
48 : static std::shared_ptr<IChannelFactory> createFactory();
49 :
50 : /**
51 : * @brief Create a connected IChannel object.
52 : *
53 : * \threadsafe
54 : *
55 : * @param[in] socketPath : The path of the socket to connect.
56 : *
57 : * @retval the connected ipc channel instance or null on error.
58 : */
59 : virtual std::shared_ptr<IChannel> createChannel(const std::string &socketPath) = 0;
60 :
61 : /**
62 : * @brief Create a connected IChannel object.
63 : *
64 : * \threadsafe
65 : *
66 : * Creates an IPC channel around the supplied socket fd.
67 : * The call takes ownership of the fd and it will close it when the channel is
68 : * destructed. The exception to this is if the call fails, in which case the
69 : * caller should close the socket themselves.
70 : *
71 : * @param[in] sockFd : The fd of the connected socket.
72 : *
73 : * @retval the connected ipc channel instance or null on error.
74 : */
75 : virtual std::shared_ptr<IChannel> createChannel(int sockFd) = 0;
76 : };
77 :
78 : class IChannel : public google::protobuf::RpcChannel
79 : {
80 : public:
81 426 : IChannel() = default;
82 426 : virtual ~IChannel() = default;
83 :
84 : IChannel(const IChannel &) = delete;
85 : IChannel &operator=(const IChannel &) = delete;
86 : IChannel(IChannel &&) = delete;
87 : IChannel &operator=(IChannel &&) = delete;
88 :
89 : /**
90 : * @brief Disconnect the IPC channel from the socket.
91 : *
92 : * \threadsafe
93 : */
94 : virtual void disconnect() = 0;
95 :
96 : /**
97 : * @brief Query whether the IPC channel is connected.
98 : *
99 : * \threadsafe
100 : *
101 : * @retval true if connected, false otherwise.
102 : */
103 : virtual bool isConnected() const = 0;
104 :
105 : /**
106 : * @brief Get the epoll file descriptor.
107 : *
108 : * \threadsafe
109 : *
110 : * @retval >= 0 on success, -1 otherwise.
111 : */
112 : virtual int fd() const = 0;
113 :
114 : /**
115 : * @brief Waits for any I/O to occur on the socket or timeout from a method call.
116 : *
117 : * The call will block for a maximum of timeoutMSecs, to make the call wait
118 : * indefinitely pass -1.
119 : *
120 : * @param[in] timeoutMSecs : The time to wait for I/O.
121 : *
122 : * @retval false if there was an error or the channel was disconnected, true otherwise
123 : */
124 : inline bool wait() { return this->wait(-1); }
125 : virtual bool wait(int timeoutMSecs) = 0;
126 :
127 : /**
128 : * @brief Processes at most one event on the channel, this may be a socket message or
129 : * a method call timeout.
130 : *
131 : * \threadsafe
132 : *
133 : * @retval false if there was an error or the channel was disconnected, true otherwise
134 : */
135 : virtual bool process() = 0;
136 :
137 : /**
138 : * @brief Subscribe for event message.
139 : *
140 : * @param[in] handler : The handler to be called when the event is triggered.
141 : *
142 : * @retval the tag of the subscribed event, -1 on error.
143 : */
144 2514 : template <class Message> inline int subscribe(std::function<void(const std::shared_ptr<Message> &message)> handler)
145 : {
146 2514 : if (!handler)
147 0 : return -1;
148 :
149 5028 : return this->subscribeImpl(Message::default_instance().GetTypeName(), Message::default_instance().GetDescriptor(),
150 5104 : [handler_ = std::move(handler)](const std::shared_ptr<google::protobuf::Message> &msg)
151 2554 : { handler_(std::dynamic_pointer_cast<Message>(msg)); });
152 : }
153 :
154 : /**
155 : * @brief Unsubscribe event.
156 : *
157 : * @param[in] eventTag : The tag of the event to unsubscribe too.
158 : *
159 : * @retval true on success.
160 : */
161 : virtual bool unsubscribe(int eventTag) = 0;
162 :
163 : private:
164 : virtual int subscribeImpl(const std::string &eventName, const google::protobuf::Descriptor *descriptor,
165 : std::function<void(const std::shared_ptr<google::protobuf::Message> &msg)> &&handler) = 0;
166 : };
167 :
168 : } // namespace firebolt::rialto::ipc
169 :
170 : #endif // FIREBOLT_RIALTO_IPC_I_IPC_CHANNEL_H_
|