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 : #include "IpcModule.h"
21 : #include "RialtoClientLogging.h"
22 :
23 : namespace firebolt::rialto::client
24 : {
25 387 : IpcModule::IpcModule(IIpcClient &ipcClient) : m_ipc{ipcClient}
26 : {
27 387 : RIALTO_CLIENT_LOG_DEBUG("entry:");
28 : }
29 :
30 387 : IpcModule::~IpcModule()
31 : {
32 387 : RIALTO_CLIENT_LOG_DEBUG("entry:");
33 : }
34 :
35 583 : bool IpcModule::unsubscribeFromAllEvents(const std::shared_ptr<ipc::IChannel> &ipcChannel)
36 : {
37 583 : if (!ipcChannel)
38 : {
39 74 : return false;
40 : }
41 :
42 509 : bool result = true;
43 2961 : for (auto it = m_eventTags.begin(); it != m_eventTags.end(); it++)
44 : {
45 2452 : if (!ipcChannel->unsubscribe(*it))
46 : {
47 3 : result = false;
48 : }
49 : }
50 509 : m_eventTags.clear();
51 :
52 509 : return result;
53 : }
54 :
55 595 : bool IpcModule::attachChannel()
56 : {
57 : // get the channel
58 595 : std::shared_ptr<ipc::IChannel> ipcChannel{getConnectedChannel()};
59 :
60 : // If not connected, try to recover and reconnect first
61 595 : if (!ipcChannel)
62 : {
63 87 : RIALTO_CLIENT_LOG_WARN("Channel not connected. Trying to recover...");
64 87 : if (!m_ipc.reconnect())
65 : {
66 85 : RIALTO_CLIENT_LOG_ERROR("Reconnection failed.");
67 85 : return false;
68 : }
69 :
70 2 : ipcChannel = getConnectedChannel();
71 2 : if (!ipcChannel)
72 : {
73 1 : RIALTO_CLIENT_LOG_ERROR("Failed to get the ipc channel");
74 1 : return false;
75 : }
76 : }
77 :
78 : // create the RPC stubs
79 509 : if (!createRpcStubs(ipcChannel))
80 : {
81 0 : RIALTO_CLIENT_LOG_ERROR("Could not create the ipc module stubs");
82 0 : return false;
83 : }
84 :
85 : // install listeners
86 509 : if (!subscribeToEvents(ipcChannel))
87 : {
88 4 : RIALTO_CLIENT_LOG_ERROR("Could not subscribe to ipc module events");
89 4 : unsubscribeFromAllEvents(ipcChannel);
90 4 : return false;
91 : }
92 :
93 505 : m_ipcChannel = ipcChannel;
94 :
95 505 : return true;
96 595 : }
97 :
98 579 : void IpcModule::detachChannel()
99 : {
100 : // uninstalls listeners
101 579 : if (!unsubscribeFromAllEvents(m_ipcChannel.lock()))
102 : {
103 74 : RIALTO_CLIENT_LOG_ERROR("Failed to unsubscribe to some ipc module events, this can lead to core dumps in IPC");
104 : }
105 :
106 : // remove IPC
107 579 : m_ipcChannel.reset();
108 : }
109 :
110 979 : bool IpcModule::reattachChannelIfRequired()
111 : {
112 979 : std::shared_ptr<ipc::IChannel> ipcChannel = m_ipcChannel.lock();
113 979 : if ((nullptr == ipcChannel) || (!ipcChannel->isConnected()))
114 : {
115 208 : RIALTO_CLIENT_LOG_INFO("Ipc channel no longer connected, attach new channel");
116 208 : detachChannel();
117 208 : if (!attachChannel())
118 : {
119 74 : RIALTO_CLIENT_LOG_ERROR("Failed attach to the ipc channel");
120 74 : return false;
121 : }
122 : }
123 :
124 905 : return true;
125 979 : }
126 :
127 597 : std::shared_ptr<ipc::IChannel> IpcModule::getConnectedChannel()
128 : {
129 597 : std::shared_ptr<ipc::IChannel> ipcChannel = m_ipc.getChannel().lock();
130 597 : if (ipcChannel && ipcChannel->isConnected())
131 : {
132 509 : return ipcChannel;
133 : }
134 88 : return nullptr;
135 597 : }
136 : }; // namespace firebolt::rialto::client
|