Skip to content

Commit 5a05063

Browse files
dkosmariDaniel K. O. (dkosmari)
and
Daniel K. O. (dkosmari)
authored
Ensure the network is connected. (#26)
* created upstream branch --HG-- branch : upstream * backported changes to upstream --HG-- branch : upstream * fixed a typo, now the sync option should work properly --HG-- branch : upstream * backported changes to upstream --HG-- branch : upstream * Backported to upstream. --HG-- branch : upstream * Backported to upstream. --HG-- branch : upstream * Backported changes. --HG-- branch : upstream * Backported changes to upstream. --HG-- branch : upstream * Merged libcurlwrapper and timezone service changes. --HG-- branch : upstream * Forgot to add curl-related sources. --HG-- branch : upstream * Backported Time Sync changes to upstream. --HG-- branch : upstream * Update workflow to use git submodules. --HG-- branch : upstream * - Ensure background thread is finished when plugin unloads. - Updated libwupsxx. --HG-- branch : upstream * Changed Makefile to build objects in subdirectories, to avoid conflicts when two different files in different directories produce the same object file name. --HG-- branch : upstream * Ensure the network is initialized before doing network operations. --HG-- branch : upstream * Forgot to merge all changes. --HG-- branch : upstream * Ensure synchronization task is launched asynchronously. --HG-- branch : upstream --------- Co-authored-by: Daniel K. O. (dkosmari) <none@none>
1 parent d97d8e0 commit 5a05063

7 files changed

+74
-23
lines changed

include/synchronize_item.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818

1919
struct synchronize_item : wups::config::button_item {
2020

21-
std::future<void> sync_result;
22-
std::stop_source sync_stopper;
21+
std::future<void> task_result;
22+
std::stop_source task_stopper;
2323

2424

2525
synchronize_item();

include/utils.hpp

+20
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ namespace utils {
5656
std::chrono::minutes>
5757
fetch_timezone(int idx);
5858

59+
60+
// RAII class to ensure network is working.
61+
// It blocks until the network is available, of throws std::runtime_error.
62+
class network_guard {
63+
64+
struct init_guard {
65+
init_guard();
66+
~init_guard();
67+
};
68+
69+
struct connect_guard {
70+
connect_guard();
71+
~connect_guard();
72+
};
73+
74+
init_guard init;
75+
connect_guard conn;
76+
77+
};
78+
5979
} // namespace utils
6080

6181
#endif

source/cfg.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,8 @@ namespace cfg {
192192
{
193193
logger::initialize(PLUGIN_NAME);
194194

195-
// logger::printf("reloading configs\n");
196195
cfg::reload();
197196

198-
// logger::printf("building config items\n");
199197
root.add(make_config_screen());
200198
root.add(make_preview_screen());
201199
root.add(synchronize_item::create());

source/clock_item.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ clock_item::run()
110110
using std::to_string;
111111
using time_utils::seconds_to_human;
112112

113+
utils::network_guard net_guard;
114+
113115
for (auto& [key, value] : server_infos) {
114116
value.name->text.clear();
115117
value.correction->text.clear();

source/core.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ namespace {
9191
return ticks_to_string(ticks);
9292
}
9393

94-
}
94+
} // namespace
9595

9696

9797
namespace core {
@@ -291,6 +291,8 @@ namespace core {
291291
{
292292
using time_utils::seconds_to_human;
293293

294+
utils::network_guard net_guard;
295+
294296
// ensure notification is initialized if needed
295297
notify::guard notify_guard{cfg::notify > 0};
296298

@@ -489,7 +491,4 @@ namespace core {
489491

490492
} // namespace background
491493

492-
493-
494-
495494
} // namespace core

source/synchronize_item.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ synchronize_item::on_started()
4040
{
4141
status_msg = "Synchronizing...";
4242

43-
sync_stopper = {};
43+
task_stopper = {};
4444

4545
auto task = [this](std::stop_token token)
4646
{
@@ -55,15 +55,17 @@ synchronize_item::on_started()
5555
}
5656
};
5757

58-
sync_result = std::async(task, sync_stopper.get_token());
58+
task_result = std::async(std::launch::async,
59+
std::move(task),
60+
task_stopper.get_token());
5961
}
6062

6163

6264
void
6365
synchronize_item::on_finished()
6466
{
6567
try {
66-
sync_result.get();
68+
task_result.get();
6769
status_msg = "Success!";
6870
cfg::save_important_vars();
6971
}
@@ -77,5 +79,5 @@ synchronize_item::on_finished()
7779
void
7880
synchronize_item::on_cancel()
7981
{
80-
sync_stopper.request_stop();
82+
task_stopper.request_stop();
8183
}

source/utils.cpp

+41-11
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,18 @@
99
#include <iterator> // distance()
1010
#include <stdexcept> // logic_error, runtime_error
1111

12+
#include <nn/ac.h>
13+
1214
#include "utils.hpp"
1315

1416
#include "http_client.hpp"
1517

1618

1719
using namespace std::literals;
1820

21+
using std::logic_error;
22+
using std::runtime_error;
23+
1924

2025
namespace utils {
2126

@@ -123,17 +128,14 @@ namespace utils {
123128
case 2:
124129
return "https://ipapi.co";
125130
default:
126-
throw std::logic_error{"invalid tz service"};
131+
throw logic_error{"Invalid tz service."};
127132
}
128133
}
129134

130135

131136
std::pair<std::string, std::chrono::minutes>
132137
fetch_timezone(int idx)
133138
{
134-
if (idx < 0 || idx >= num_tz_services)
135-
throw std::logic_error{"invalid service"};
136-
137139
const char* service = get_tz_service_name(idx);
138140

139141
static const char* urls[num_tz_services] = {
@@ -142,6 +144,8 @@ namespace utils {
142144
"https://ipapi.co/csv"
143145
};
144146

147+
network_guard net_guard;
148+
145149
std::string response = http::get(urls[idx]);
146150

147151
switch (idx) {
@@ -150,7 +154,7 @@ namespace utils {
150154
{
151155
auto tokens = csv_split(response);
152156
if (size(tokens) != 2)
153-
throw std::runtime_error{"Could not parse response from "s + service};
157+
throw runtime_error{"Could not parse response from "s + service};
154158
std::string name = tokens[0];
155159
auto offset = std::chrono::seconds{std::stoi(tokens[1])};
156160
return {name, duration_cast<std::chrono::minutes>(offset)};
@@ -163,26 +167,26 @@ namespace utils {
163167
// returned as +HHMM, not seconds.
164168
auto lines = split(response, "\r\n");
165169
if (size(lines) != 2)
166-
throw std::runtime_error{"Could not parse response from "s + service};
170+
throw runtime_error{"Could not parse response from "s + service};
167171

168172
auto keys = csv_split(lines[0]);
169173
auto values = csv_split(lines[1]);
170174
if (size(keys) != size(values))
171-
throw std::runtime_error{"Incoherent response from "s + service};
175+
throw runtime_error{"Incoherent response from "s + service};
172176

173177
auto tz_it = std::ranges::find(keys, "timezone");
174178
auto offset_it = std::ranges::find(keys, "utc_offset");
175179
if (tz_it == keys.end() || offset_it == keys.end())
176-
throw std::runtime_error{"Could not find timezone or utc_offset fields"
177-
" in response."};
180+
throw runtime_error{"Could not find timezone or utc_offset fields"
181+
" in response."};
178182

179183
auto tz_idx = std::distance(keys.begin(), tz_it);;
180184
auto offset_idx = std::distance(keys.begin(), offset_it);
181185

182186
std::string name = values[tz_idx];
183187
std::string hhmm = values[offset_idx];
184188
if (empty(hhmm))
185-
throw std::runtime_error{"Invalid UTC offset string."};
189+
throw runtime_error{"Invalid UTC offset string."};
186190

187191
char sign = hhmm[0];
188192
std::string hh = hhmm.substr(1, 2);
@@ -196,9 +200,35 @@ namespace utils {
196200
}
197201

198202
default:
199-
throw std::logic_error{"invalid tz service"};
203+
throw logic_error{"Invalid tz service."};
200204
}
201205

202206
}
203207

208+
209+
network_guard::init_guard::init_guard()
210+
{
211+
if (!nn::ac::Initialize())
212+
throw runtime_error{"Network error (nn::ac::Initialize() failed)"};
213+
}
214+
215+
216+
network_guard::init_guard::~init_guard()
217+
{
218+
nn::ac::Finalize();
219+
}
220+
221+
222+
network_guard::connect_guard::connect_guard()
223+
{
224+
if (!nn::ac::Connect())
225+
throw runtime_error{"Network error (nn::ac::Connect() failed)"};
226+
}
227+
228+
229+
network_guard::connect_guard::~connect_guard()
230+
{
231+
nn::ac::Close();
232+
}
233+
204234
} // namespace utils

0 commit comments

Comments
 (0)