Skip to content

Commit

Permalink
Added ^C handling to some examples for clean exits.
Browse files Browse the repository at this point in the history
  • Loading branch information
fpagliughi committed Jul 6, 2024
1 parent 33d219a commit 0bf6394
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- The `properties` list implements a const iterator
- Added a `to_string()` and `operator<<()` for reason codes.
- Cleaned up and fixed a number of example apps.
- Most apps no except server URI from the command line
- 'data_publish' example uses C++17 std::filesystem for creating a file-based encrypted persistence for messages.
- Reorganized the source repository
- Completely reformat the sources and added a .clang-format file (a project master and a slightly-different one for headers).
- Added GitHub CI Action, removing legacy Travis and Appveyor files
Expand Down
17 changes: 15 additions & 2 deletions examples/async_publish_time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
#include <iostream>
#include <string>
#include <thread> // For sleep
#include <atomic>
#include <csignal>

#include "mqtt/async_client.h"

Expand All @@ -69,6 +71,14 @@ const int DELTA_MS = 100;
// How many to buffer while off-line
const int MAX_BUFFERED_MESSAGES = 1200;

// Atomic flag to tell the main loop to exit.
atomic<bool> quit{false};

// Handler for ^C (SIGINT)
void ctrlc_handler(int) {
quit = true;
}

// --------------------------------------------------------------------------
// Gets the current time as the number of milliseconds since the epoch:
// like a time_t with ms resolution.
Expand Down Expand Up @@ -130,14 +140,17 @@ int main(int argc, char* argv[])
auto top = mqtt::topic(cli, "data/time", QOS);
cout << "Publishing data..." << endl;

// Install a ^C handler for user to signal when to exit
signal(SIGINT, ctrlc_handler);

// Sync clock to start of delta period
while (timestamp() % DELTA_MS != 0)
;

uint64_t t = timestamp(), tlast = t, tstart = t;

top.publish(to_string(t));

while (true) {
while (!quit) {
this_thread::sleep_for(SAMPLE_PERIOD);

t = timestamp();
Expand Down
41 changes: 34 additions & 7 deletions examples/data_publish.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
#include <thread>
#include <filesystem>
#include <fstream>
#include <csignal>
#include <mutex>
#include <condition_variable>

#include "mqtt/async_client.h"

Expand All @@ -77,6 +80,20 @@ const fs::path PERSIST_DIR{"persist"};
// A key for encoding the persistence data
const string PERSIST_KEY{"elephant"};

// Condition variable & flag to tell the main loop to exit.
std::condition_variable cv;
std::mutex mtx;
bool quit{false};

// Handler for ^C (SIGINT)
void ctrlc_handler(int) {
{
lock_guard<mutex> lk(mtx);
quit = true;
}
cv.notify_one();
}

/////////////////////////////////////////////////////////////////////////////

// Example of user-based file persistence with a simple XOR encoding scheme.
Expand Down Expand Up @@ -108,7 +125,7 @@ class encoded_file_persistence : virtual public mqtt::iclient_persistence
}

// Gets the persistence file name for the supplied key.
fs::path path_name(const string& key) const { return dir_ /key; }
fs::path path_name(const string& key) const { return dir_ / key; }

public:
// Create the persistence object with the specified encoding key
Expand Down Expand Up @@ -138,7 +155,10 @@ class encoded_file_persistence : virtual public mqtt::iclient_persistence

// Close the persistent store that was previously opened.
// Remove the persistence directory, if it's empty.
void close() override { fs::remove(dir_); }
void close() override {
fs::remove(dir_);
fs::remove(dir_.parent_path());
}

// Clears persistence, so that it no longer contains any persisted data.
// Just remove all the files from the persistence directory.
Expand Down Expand Up @@ -271,12 +291,18 @@ int main(int argc, char* argv[])
char tmbuf[32];
unsigned nsample = 0;

// The time at which to reads the next sample, starting now
auto tm = steady_clock::now();
// Install a ^C handler for user to signal when to exit
signal(SIGINT, ctrlc_handler);

// The steady time at which to read the next sample
auto tm = steady_clock::now() + 250ms;

// Pace the sampling by letting the condition variable time out
// periodically. When 'cv' is signaled, it's time to quit.
unique_lock lk(mtx);

while (true) {
// Pace the samples to the desired rate
this_thread::sleep_until(tm);
while (!cv.wait_until(lk, tm, []{ return quit; })) {
lk.unlock();

// Get a timestamp and format as a string
time_t t = system_clock::to_time_t(system_clock::now());
Expand All @@ -293,6 +319,7 @@ int main(int argc, char* argv[])
top.publish(std::move(payload));

tm += PERIOD;
lk.lock();
}

// Disconnect
Expand Down

0 comments on commit 0bf6394

Please sign in to comment.