Skip to content

Commit 180cc72

Browse files
smilesa-maurice
authored andcommitted
Only maintain a repo scheduler when a Repo instance is present.
The Repo scheduler is crashing in it's destructor on shutdown in some environments so make the scheduler lifetime dependent upon the Repo object lifetime. This also reduces resource usage when no Database instances are present. PiperOrigin-RevId: 255657460
1 parent 96f86fa commit 180cc72

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

database/src/desktop/core/repo.cc

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "database/src/desktop/core/repo.h"
1616

1717
#include "app/src/callback.h"
18+
#include "app/src/mutex.h"
1819
#include "app/src/log.h"
1920
#include "app/src/scheduler.h"
2021
#include "app/src/variant_util.h"
@@ -40,7 +41,9 @@ using callback::NewCallback;
4041
namespace database {
4142
namespace internal {
4243

43-
scheduler::Scheduler Repo::s_scheduler_;
44+
static Mutex g_scheduler_mutex; // NOLINT
45+
static int g_scheduler_ref_count = 0;
46+
scheduler::Scheduler* Repo::s_scheduler_;
4447

4548
// Transaction Response class to pass to PersistentConnection.
4649
// This is used to capture all the data to use when ResponseCallback is
@@ -86,10 +89,16 @@ Repo::Repo(App* app, DatabaseInternal* database, const char* url)
8689
parser.secure);
8790
url_ = host_info_.ToString();
8891

92+
{
93+
MutexLock lock(g_scheduler_mutex);
94+
g_scheduler_ref_count++;
95+
if (s_scheduler_ == nullptr) s_scheduler_ = new scheduler::Scheduler();
96+
}
97+
8998
connection_.reset(new connection::PersistentConnection(app, host_info_, this,
90-
&s_scheduler_));
99+
s_scheduler_));
91100
// Kick off any expensive additional initialization
92-
s_scheduler_.Schedule(NewCallback(
101+
s_scheduler_->Schedule(NewCallback(
93102
[](ThisRef ref) {
94103
ThisRefLock lock(&ref);
95104
if (lock.GetReference() != nullptr) {
@@ -107,6 +116,14 @@ Repo::~Repo() {
107116
// while the SyncTree is being torn down.
108117
safe_this_.ClearReference();
109118
connection_.reset(nullptr);
119+
{
120+
MutexLock lock(g_scheduler_mutex);
121+
if (g_scheduler_ref_count) g_scheduler_ref_count--;
122+
if (g_scheduler_ref_count == 0) {
123+
delete s_scheduler_;
124+
s_scheduler_ = nullptr;
125+
}
126+
}
110127
}
111128

112129
void Repo::AddEventCallback(UniquePtr<EventRegistration> event_registration) {

database/src/desktop/core/repo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class Repo : public connection::PersistentConnectionEventHandler {
105105

106106
const std::string& url() const { return url_; }
107107

108-
static scheduler::Scheduler& scheduler() { return s_scheduler_; }
108+
static scheduler::Scheduler& scheduler() { return *s_scheduler_; }
109109

110110
ThisRef& this_ref() { return safe_this_; }
111111

@@ -158,7 +158,7 @@ class Repo : public connection::PersistentConnectionEventHandler {
158158
// The scheduler shared with every DatabaseInternal. It is designed to
159159
// out-live any class which is using it, so that it is safe to use even in
160160
// destructor.
161-
static scheduler::Scheduler s_scheduler_;
161+
static scheduler::Scheduler* s_scheduler_;
162162

163163
// Caches information about the connection to the host.
164164
connection::HostInfo host_info_;

0 commit comments

Comments
 (0)