Commit 5111f73da157233df0c8ed17ec89b666aef8f30f

Authored by Wiebe Cazemier
1 parent cd429cb7

Reduce blocking of threads when saving state

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 &amp;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  
... ...