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 394 : IpcModule::IpcModule(IIpcClient &ipcClient) : m_ipc{ipcClient}
26 : {
27 394 : RIALTO_CLIENT_LOG_DEBUG("entry:");
28 : }
29 :
30 394 : IpcModule::~IpcModule()
31 : {
32 394 : RIALTO_CLIENT_LOG_DEBUG("entry:");
33 : }
34 :
35 594 : bool IpcModule::unsubscribeFromAllEvents(const std::shared_ptr<ipc::IChannel> &ipcChannel)
36 : {
37 594 : if (!ipcChannel)
38 : {
39 76 : return false;
40 : }
41 :
42 518 : bool result = true;
43 3002 : for (auto it = m_eventTags.begin(); it != m_eventTags.end(); it++)
44 : {
45 2484 : if (!ipcChannel->unsubscribe(*it))
46 : {
47 3 : result = false;
48 : }
49 : }
50 518 : m_eventTags.clear();
51 :
52 518 : return result;
53 : }
54 :
55 606 : bool IpcModule::attachChannel()
56 : {
57 : // get the channel
58 606 : std::shared_ptr<ipc::IChannel> ipcChannel{getConnectedChannel()};
59 :
60 : // If not connected, try to recover and reconnect first
61 606 : if (!ipcChannel)
62 : {
63 89 : RIALTO_CLIENT_LOG_WARN("Channel not connected. Trying to recover...");
64 89 : if (!m_ipc.reconnect())
65 : {
66 87 : RIALTO_CLIENT_LOG_ERROR("Reconnection failed.");
67 87 : 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 518 : 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 518 : 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 514 : m_ipcChannel = ipcChannel;
94 :
95 514 : return true;
96 606 : }
97 :
98 590 : void IpcModule::detachChannel()
99 : {
100 : // uninstalls listeners
101 590 : if (!unsubscribeFromAllEvents(m_ipcChannel.lock()))
102 : {
103 76 : 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 590 : m_ipcChannel.reset();
108 : }
109 :
110 992 : bool IpcModule::reattachChannelIfRequired()
111 : {
112 992 : std::shared_ptr<ipc::IChannel> ipcChannel = m_ipcChannel.lock();
113 992 : if ((nullptr == ipcChannel) || (!ipcChannel->isConnected()))
114 : {
115 212 : RIALTO_CLIENT_LOG_INFO("Ipc channel no longer connected, attach new channel");
116 212 : detachChannel();
117 212 : if (!attachChannel())
118 : {
119 76 : RIALTO_CLIENT_LOG_ERROR("Failed attach to the ipc channel");
120 76 : return false;
121 : }
122 : }
123 :
124 916 : return true;
125 992 : }
126 :
127 608 : std::shared_ptr<ipc::IChannel> IpcModule::getConnectedChannel()
128 : {
129 608 : std::shared_ptr<ipc::IChannel> ipcChannel = m_ipc.getChannel().lock();
130 608 : if (ipcChannel && ipcChannel->isConnected())
131 : {
132 518 : return ipcChannel;
133 : }
134 90 : return nullptr;
135 608 : }
136 : }; // namespace firebolt::rialto::client
|