Skip to content

Commit e0b54c1

Browse files
authored
Fix deadlock in Greengrass discovery sample (#795)
1 parent 9020190 commit e0b54c1

File tree

1 file changed

+64
-57
lines changed
  • samples/greengrass/basic_discovery

1 file changed

+64
-57
lines changed

samples/greengrass/basic_discovery/main.cpp

Lines changed: 64 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@
2020
using namespace Aws::Crt;
2121
using namespace Aws::Discovery;
2222

23-
std::shared_ptr<Mqtt::MqttConnection> getMqttConnection(
23+
static std::shared_ptr<Mqtt::MqttConnection> getMqttConnection(
2424
Aws::Iot::MqttClient &mqttClient,
25-
DiscoverResponse *response,
25+
const Aws::Crt::Vector<GGGroup> &ggGroups,
2626
Utils::cmdData &cmdData,
2727
std::promise<void> &shutdownCompletedPromise)
2828
{
2929
std::shared_ptr<Mqtt::MqttConnection> connection;
3030

31-
for (const auto &groupToUse : *response->GGGroups)
31+
for (const auto &groupToUse : ggGroups)
3232
{
3333
for (const auto &connectivityInfo : *groupToUse.Cores->at(0).Connectivity)
3434
{
@@ -115,6 +115,23 @@ std::shared_ptr<Mqtt::MqttConnection> getMqttConnection(
115115
return nullptr;
116116
}
117117

118+
static void printGreengrassResponse(const Aws::Crt::Vector<GGGroup> &ggGroups)
119+
{
120+
for (const auto &ggGroup : ggGroups)
121+
{
122+
fprintf(stdout, "Group ID: %s\n", ggGroup.GGGroupId->c_str());
123+
for (const auto &ggCore : *ggGroup.Cores)
124+
{
125+
fprintf(stdout, " Thing ARN: %s\n", ggCore.ThingArn->c_str());
126+
for (const auto &connectivity : *ggCore.Connectivity)
127+
{
128+
fprintf(stdout, " Connectivity Host Address: %s\n", connectivity.HostAddress->c_str());
129+
fprintf(stdout, " Connectivity Host Port: %u\n", connectivity.Port.value());
130+
}
131+
}
132+
}
133+
}
134+
118135
int main(int argc, char *argv[])
119136
{
120137
/************************ Setup ****************************/
@@ -191,63 +208,23 @@ int main(int argc, char *argv[])
191208
Aws::Iot::MqttClient mqttClient;
192209
std::shared_ptr<Mqtt::MqttConnection> connection(nullptr);
193210

194-
std::promise<void> connectionFinishedPromise;
211+
DiscoverResponse discoverResponse;
212+
213+
std::promise<bool> discoveryStatusPromise;
195214
std::promise<void> shutdownCompletedPromise;
196215

216+
// Initiate gathering a list of discoverable Greengrass cores.
217+
// NOTE: This is an asynchronous operation, so it completes before the results are actually ready. You need to use
218+
// synchronization techniques to obtain its results. For simplicity, we use promise/future in this sample.
197219
discoveryClient->Discover(
198-
cmdData.input_thingName, [&](DiscoverResponse *response, int error, int httpResponseCode) {
220+
cmdData.input_thingName,
221+
[&discoverResponse, &discoveryStatusPromise](DiscoverResponse *response, int error, int httpResponseCode) {
199222
fprintf(stdout, "Discovery completed with error code %d; http code %d\n", error, httpResponseCode);
200-
if (!error && response->GGGroups)
201-
{
202-
// Print the discovery response information and then exit. Does not use the discovery info.
203-
// (unless in CI, in which case just note it was successful and exit)
204-
if (cmdData.input_PrintDiscoverRespOnly)
205-
{
206-
// Print the discovery response information and then exit (unless in CI, in which case just note it
207-
// was successful)
208-
if (!cmdData.input_isCI)
209-
{
210-
for (size_t a = 0; a < response->GGGroups->size(); a++)
211-
{
212-
auto tmpGroup = std::move(response->GGGroups->at(a));
213-
fprintf(stdout, "Group ID: %s\n", tmpGroup.GGGroupId->c_str());
214-
for (size_t b = 0; b < tmpGroup.Cores->size(); b++)
215-
{
216-
fprintf(stdout, " Thing ARN: %s\n", tmpGroup.Cores->at(b).ThingArn->c_str());
217-
for (size_t c = 0; c < tmpGroup.Cores->at(b).Connectivity->size(); c++)
218-
{
219-
fprintf(
220-
stdout,
221-
" Connectivity Host Address: %s\n",
222-
tmpGroup.Cores->at(b).Connectivity->at(c).HostAddress->c_str());
223-
fprintf(
224-
stdout,
225-
" Connectivity Host Port: %d\n",
226-
tmpGroup.Cores->at(b).Connectivity->at(c).Port.value());
227-
}
228-
}
229-
}
230-
}
231-
else
232-
{
233-
fprintf(
234-
stdout,
235-
"Received a greengrass discovery result! Not showing result in CI for possible data "
236-
"sensitivity.\n");
237-
}
238-
exit(0);
239-
}
240223

241-
connection = getMqttConnection(mqttClient, response, cmdData, shutdownCompletedPromise);
242-
if (connection)
243-
{
244-
connectionFinishedPromise.set_value();
245-
}
246-
else
247-
{
248-
fprintf(stderr, "All connection attempts failed\n");
249-
exit(-1);
250-
}
224+
if (!error && response->GGGroups.has_value())
225+
{
226+
discoverResponse = *response;
227+
discoveryStatusPromise.set_value(true);
251228
}
252229
else
253230
{
@@ -256,12 +233,42 @@ int main(int argc, char *argv[])
256233
"Discover failed with error: %s, and http response code %d\n",
257234
aws_error_debug_str(error),
258235
httpResponseCode);
259-
exit(-1);
236+
discoveryStatusPromise.set_value(false);
260237
}
261238
});
262239

263-
connectionFinishedPromise.get_future().wait();
240+
// Wait for the discovery process to return actual discovery results, or error if something went wrong.
241+
auto isDiscoverySucceeded = discoveryStatusPromise.get_future().get();
242+
if (!isDiscoverySucceeded)
243+
{
244+
return 1;
245+
}
246+
247+
// Print the discovery response information and then exit. Does not use the discovery info.
248+
if (cmdData.input_PrintDiscoverRespOnly)
249+
{
250+
if (!cmdData.input_isCI)
251+
{
252+
printGreengrassResponse(*discoverResponse.GGGroups);
253+
}
254+
else
255+
{
256+
fprintf(
257+
stdout,
258+
"Received a greengrass discovery result! Not showing result in CI for possible data sensitivity.\n");
259+
}
260+
return 0;
261+
}
262+
263+
// Try to establish a connection with one of the discovered Greengrass cores.
264+
connection = getMqttConnection(mqttClient, *discoverResponse.GGGroups, cmdData, shutdownCompletedPromise);
265+
if (!connection)
266+
{
267+
fprintf(stderr, "All connection attempts failed\n");
268+
exit(-1);
269+
}
264270

271+
// Now, with the established connection to a Greengrass core, we can perform MQTT-related actions.
265272
if (cmdData.input_mode == "both" || cmdData.input_mode == "subscribe")
266273
{
267274
auto onMessage = [&](Mqtt::MqttConnection & /*connection*/,

0 commit comments

Comments
 (0)