Commit 5111f73da157233df0c8ed17ec89b666aef8f30f
1 parent
cd429cb7
Reduce blocking of threads when saving state
Showing
3 changed files
with
34 additions
and
2 deletions
mainapp.cpp
| ... | ... | @@ -210,7 +210,7 @@ MainApp::MainApp(const std::string &configFilePath) : |
| 210 | 210 | subscriptionStore->loadSessionsAndSubscriptions(settings->getSessionsDBFile()); |
| 211 | 211 | } |
| 212 | 212 | |
| 213 | - auto fSaveState = std::bind(&MainApp::saveState, this); | |
| 213 | + auto fSaveState = std::bind(&MainApp::saveStateInThread, this); | |
| 214 | 214 | timer.addCallback(fSaveState, 900000, "Save state."); |
| 215 | 215 | } |
| 216 | 216 | |
| ... | ... | @@ -355,8 +355,31 @@ void MainApp::queuePublishStatsOnDollarTopic() |
| 355 | 355 | } |
| 356 | 356 | } |
| 357 | 357 | |
| 358 | +/** | |
| 359 | + * @brief MainApp::saveStateInThread starts a thread for disk IO, because file IO is not async. | |
| 360 | + */ | |
| 361 | +void MainApp::saveStateInThread() | |
| 362 | +{ | |
| 363 | + // Prevent queueing it again when it's still running. | |
| 364 | + std::unique_lock<std::mutex> locker(saveStateMutex, std::try_to_lock); | |
| 365 | + if (!locker.owns_lock()) | |
| 366 | + return; | |
| 367 | + | |
| 368 | + // Join previous instances. | |
| 369 | + if (saveStateThread.joinable()) | |
| 370 | + saveStateThread.join(); | |
| 371 | + | |
| 372 | + auto f = std::bind(&MainApp::saveState, this); | |
| 373 | + saveStateThread = std::thread(f); | |
| 374 | + | |
| 375 | + pthread_t native = saveStateThread.native_handle(); | |
| 376 | + pthread_setname_np(native, "SaveState"); | |
| 377 | +} | |
| 378 | + | |
| 358 | 379 | void MainApp::saveState() |
| 359 | 380 | { |
| 381 | + std::lock_guard<std::mutex> lg(saveStateMutex); | |
| 382 | + | |
| 360 | 383 | try |
| 361 | 384 | { |
| 362 | 385 | if (!settings->storageDir.empty()) |
| ... | ... | @@ -366,6 +389,8 @@ void MainApp::saveState() |
| 366 | 389 | |
| 367 | 390 | const std::string sessionsDBPath = settings->getSessionsDBFile(); |
| 368 | 391 | subscriptionStore->saveSessionsAndSubscriptions(sessionsDBPath); |
| 392 | + | |
| 393 | + logger->logf(LOG_INFO, "Saving states done"); | |
| 369 | 394 | } |
| 370 | 395 | } |
| 371 | 396 | catch(std::exception &ex) |
| ... | ... | @@ -669,6 +694,9 @@ void MainApp::start() |
| 669 | 694 | } |
| 670 | 695 | |
| 671 | 696 | saveState(); |
| 697 | + | |
| 698 | + if (saveStateThread.joinable()) | |
| 699 | + saveStateThread.join(); | |
| 672 | 700 | } |
| 673 | 701 | |
| 674 | 702 | void MainApp::quit() | ... | ... |
mainapp.h
| ... | ... | @@ -71,6 +71,9 @@ class MainApp |
| 71 | 71 | |
| 72 | 72 | Logger *logger = Logger::getInstance(); |
| 73 | 73 | |
| 74 | + std::thread saveStateThread; | |
| 75 | + std::mutex saveStateMutex; | |
| 76 | + | |
| 74 | 77 | void setlimits(); |
| 75 | 78 | void loadConfig(); |
| 76 | 79 | void reloadConfig(); |
| ... | ... | @@ -84,6 +87,7 @@ class MainApp |
| 84 | 87 | void setFuzzFile(const std::string &fuzzFilePath); |
| 85 | 88 | void queuePublishStatsOnDollarTopic(); |
| 86 | 89 | void saveState(); |
| 90 | + void saveStateInThread(); | |
| 87 | 91 | |
| 88 | 92 | MainApp(const std::string &configFilePath); |
| 89 | 93 | public: | ... | ... |
subscriptionstore.cpp
| ... | ... | @@ -634,7 +634,7 @@ void SubscriptionStore::saveSessionsAndSubscriptions(const std::string &filePath |
| 634 | 634 | logger->logf(LOG_INFO, "Saving sessions and subscriptions to '%s'", filePath.c_str()); |
| 635 | 635 | |
| 636 | 636 | RWLockGuard lock_guard(&subscriptionsRwlock); |
| 637 | - lock_guard.wrlock(); | |
| 637 | + lock_guard.rdlock(); | |
| 638 | 638 | |
| 639 | 639 | // First copy the sessions... |
| 640 | 640 | ... | ... |