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