Skip to content
This repository was archived by the owner on Jun 7, 2026. It is now read-only.

Commit a982a49

Browse files
committed
Fix segfault when copying issue callback instance
1 parent 7d00e8e commit a982a49

7 files changed

Lines changed: 30 additions & 31 deletions

File tree

src/service/project/pages.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ namespace service {
237237
Task<TaskResult<FileTree>> ResolvedProject::getDirectoryTree() { co_return getDirectoryTree(format_.getRoot()); }
238238

239239
Task<> validatePageFile(const FileTreeEntry &entry, const ResolvedProject &resolved,
240-
const std::shared_ptr<ProjectIssueCallback> &issues, const std::vector<std::string> &requiredAttributes) {
240+
const std::shared_ptr<ProjectIssueCallback> issues, const std::vector<std::string> &requiredAttributes) {
241241
const auto path = entry.path + DOCS_FILE_EXT;
242242
if (const auto title = resolved.getPageTitle(path); !title) {
243243
co_await issues->addIssue(ProjectIssueLevel::WARNING, ProjectIssueType::FILE, ProjectError::NO_PAGE_TITLE, "", path);
@@ -258,7 +258,7 @@ namespace service {
258258
}
259259
}
260260

261-
Task<> validatePagesTree(const FileTree &tree, const ResolvedProject &resolved, const std::shared_ptr<ProjectIssueCallback> &issues,
261+
Task<> validatePagesTree(const FileTree &tree, const ResolvedProject &resolved, const std::shared_ptr<ProjectIssueCallback> issues,
262262
const std::vector<std::string> &requiredAttributes) {
263263
for (const auto &entry: tree) {
264264
if (entry.type == FileType::FILE) {

src/service/storage/deployment.cc

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ namespace service {
7676

7777
Task<std::vector<ProjectVersion>> setupProjectVersions(const ResolvedProject &resolved,
7878
const std::unordered_map<std::string, std::string> &branches,
79-
const std::shared_ptr<spdlog::logger> logger, ProjectIssueCallback &issues) {
79+
const std::shared_ptr<spdlog::logger> logger, const std::shared_ptr<ProjectIssueCallback> &issues) {
8080
const auto path = resolved.getFormat().getWikiMetadataPath();
8181
const ProjectFileIssueCallback fileIssues(issues, path);
8282

@@ -153,13 +153,13 @@ namespace service {
153153
deployment.setStatus(enumToStr(DeploymentStatus::LOADING));
154154
co_await global::database->updateModel(deployment);
155155

156-
ProjectIssueCallback issues{deployment.getValueOfId(), logger};
156+
const auto issues = std::make_shared<ProjectIssueCallback>(deployment.getValueOfId(), logger);
157157

158158
// 1. Clone repository
159159
const auto [repo, cloneError] =
160160
co_await git::cloneRepository(project.getValueOfSourceRepo(), clonePath, project.getValueOfSourceBranch(), logger);
161161
if (!repo || cloneError.error != ProjectError::OK) {
162-
co_await issues.addIssue(ProjectIssueLevel::ERROR, ProjectIssueType::GIT_CLONE, cloneError.error, cloneError.message);
162+
co_await issues->addIssue(ProjectIssueLevel::ERROR, ProjectIssueType::GIT_CLONE, cloneError.error, cloneError.message);
163163
co_return cloneError.error;
164164
}
165165

@@ -170,7 +170,7 @@ namespace service {
170170

171171
if (!defaultVersion) {
172172
logger->error("Project version creation database error.");
173-
co_await issues.addIssue(ProjectIssueLevel::ERROR, ProjectIssueType::INTERNAL, ProjectError::UNKNOWN);
173+
co_await issues->addIssue(ProjectIssueLevel::ERROR, ProjectIssueType::INTERNAL, ProjectError::UNKNOWN);
174174
co_return ProjectError::UNKNOWN;
175175
}
176176
}
@@ -179,7 +179,7 @@ namespace service {
179179
const auto revision = git::getLatestRevision(repo);
180180
if (!revision) {
181181
logger->error("Error getting commit information");
182-
co_await issues.addIssue(ProjectIssueLevel::ERROR, ProjectIssueType::GIT_INFO, ProjectError::UNKNOWN);
182+
co_await issues->addIssue(ProjectIssueLevel::ERROR, ProjectIssueType::GIT_INFO, ProjectError::UNKNOWN);
183183
co_return ProjectError::UNKNOWN;
184184
}
185185
deployment.setRevision(nlohmann::json(*revision).dump());
@@ -188,19 +188,18 @@ namespace service {
188188
// 4. Ingest game content
189189
const auto projectLog = getProjectLogger(project, false);
190190
const auto cloneDocsRoot = clonePath / removeLeadingSlash(project.getValueOfSourcePath());
191-
const auto sharedIssues = std::make_shared<ProjectIssueCallback>(issues);
192-
ResolvedProject resolved{project, cloneDocsRoot, *defaultVersion, sharedIssues, projectLog};
191+
ResolvedProject resolved{project, cloneDocsRoot, *defaultVersion, issues, projectLog};
193192

194193
// 5. Validate metadata
195194
if (const auto [c, e, details] = resolved.validateProjectMetadata(); !details.empty()) {
196195
logger->error("Invalid project metadata found.");
197-
co_await issues.addIssue(ProjectIssueLevel::ERROR, ProjectIssueType::META, ProjectError::INVALID_META, details);
196+
co_await issues->addIssue(ProjectIssueLevel::ERROR, ProjectIssueType::META, ProjectError::INVALID_META, details);
198197
co_return ProjectError::INVALID_META;
199198
}
200199

201200
// Validate pages
202201
co_await resolved.validatePages();
203-
if (issues.hasErrors()) {
202+
if (issues->hasErrors()) {
204203
logger->error("Found invalid page, aborting");
205204
co_return ProjectError::UNKNOWN;
206205
}
@@ -213,7 +212,7 @@ namespace service {
213212
co_return ProjectError::UNKNOWN;
214213
}
215214

216-
if (issues.hasErrors()) {
215+
if (issues->hasErrors()) {
217216
logger->error("Encountered issues during project setup, aborting");
218217
co_return ProjectError::UNKNOWN;
219218
}

src/service/storage/ingestor/ingestor.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace content {
1919

2020
Task<Error> SubIngestor::finish() { co_return Error::Ok; }
2121

22-
Ingestor::Ingestor(ProjectBase &proj, const std::shared_ptr<spdlog::logger> &log, ProjectIssueCallback &issues,
22+
Ingestor::Ingestor(ProjectBase &proj, const std::shared_ptr<spdlog::logger> &log, const std::shared_ptr<ProjectIssueCallback> &issues,
2323
const std::set<std::string> &enableModules, const bool deleteExisting) :
2424
project_(proj), logger_(log), issues_(issues), enableModules_(enableModules), deleteExisting_(deleteExisting) {}
2525

@@ -61,7 +61,7 @@ namespace content {
6161
co_return result;
6262
} catch (std::exception &e) {
6363
logger.error("Error ingesting project data: {}", e.what());
64-
issues_.addIssueAsync(ProjectIssueLevel::ERROR, ProjectIssueType::INGESTOR, ProjectError::UNKNOWN, e.what());
64+
issues_->addIssueAsync(ProjectIssueLevel::ERROR, ProjectIssueType::INGESTOR, ProjectError::UNKNOWN, e.what());
6565

6666
project_.getProjectDatabase().setDBClientPointer(clientPtr);
6767
co_return Error::ErrInternal;
@@ -98,7 +98,7 @@ namespace content {
9898
const auto [items] = co_await ingestor->prepare();
9999
allResults.items.insert(items.begin(), items.end());
100100
} catch (std::exception &e) {
101-
issues_.addIssueAsync(ProjectIssueLevel::ERROR, ProjectIssueType::INGESTOR, ProjectError::UNKNOWN, e.what());
101+
issues_->addIssueAsync(ProjectIssueLevel::ERROR, ProjectIssueType::INGESTOR, ProjectError::UNKNOWN, e.what());
102102
co_return Error::ErrInternal;
103103
}
104104
}
@@ -136,7 +136,7 @@ namespace content {
136136
}
137137
} catch (std::exception &e) {
138138
const auto details = std::format("[{}] {}", name, e.what());
139-
issues_.addIssueAsync(ProjectIssueLevel::ERROR, ProjectIssueType::INGESTOR, ProjectError::UNKNOWN, details);
139+
issues_->addIssueAsync(ProjectIssueLevel::ERROR, ProjectIssueType::INGESTOR, ProjectError::UNKNOWN, details);
140140
co_return Error::ErrInternal;
141141
}
142142
}
@@ -152,7 +152,7 @@ namespace content {
152152
}
153153
} catch (std::exception &e) {
154154
const auto details = std::format("[{}] {}", name, e.what());
155-
issues_.addIssueAsync(ProjectIssueLevel::ERROR, ProjectIssueType::INGESTOR, ProjectError::UNKNOWN, details);
155+
issues_->addIssueAsync(ProjectIssueLevel::ERROR, ProjectIssueType::INGESTOR, ProjectError::UNKNOWN, details);
156156
co_return Error::ErrInternal;
157157
}
158158
}

src/service/storage/ingestor/ingestor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ namespace content {
4141

4242
class Ingestor {
4343
public:
44-
explicit Ingestor(service::ProjectBase &, const std::shared_ptr<spdlog::logger> &, service::ProjectIssueCallback &,
44+
explicit Ingestor(service::ProjectBase &, const std::shared_ptr<spdlog::logger> &, const std::shared_ptr<service::ProjectIssueCallback> &,
4545
const std::set<std::string> &enableModules, bool deleteExisting);
4646

4747
drogon::Task<service::Error> runIngestor() const;
@@ -60,7 +60,7 @@ namespace content {
6060

6161
const service::ProjectBase &project_;
6262
const std::shared_ptr<spdlog::logger> &logger_;
63-
service::ProjectIssueCallback &issues_;
63+
std::shared_ptr<service::ProjectIssueCallback> issues_;
6464
const std::set<std::string> enableModules_;
6565
const bool deleteExisting_;
6666
};

src/service/storage/issues.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,28 +69,28 @@ namespace service {
6969
if (level == ProjectIssueLevel::ERROR)
7070
hasErrors_ = true;
7171

72-
app().getLoop()->queueInLoop(
73-
async_func([*this, level, type, subject, details = std::string(details), file = std::string(file)]() mutable -> Task<> {
74-
co_await addIssue(level, type, subject, details, file);
75-
}));
72+
app().getLoop()->queueInLoop(async_func([self = shared_from_this(), level, type, subject, details, file]() -> Task<> {
73+
co_await self->addIssue(level, type, subject, details, file);
74+
}));
7675
}
7776

7877
bool ProjectIssueCallback::hasErrors() const { return hasErrors_; }
7978

80-
ProjectFileIssueCallback::ProjectFileIssueCallback(ProjectIssueCallback &issues, const std::filesystem::path &path) :
79+
ProjectFileIssueCallback::ProjectFileIssueCallback(const std::shared_ptr<ProjectIssueCallback> &issues,
80+
const std::filesystem::path &path) :
8181
issues_(issues), absolutePath_(path), path_(path) {}
8282

8383
ProjectFileIssueCallback::ProjectFileIssueCallback(const ProjectFileIssueCallback &issues, const std::filesystem::path &path) :
8484
issues_(issues.issues_), absolutePath_(path), path_(relative(path, issues.path_)) {}
8585

8686
Task<> ProjectFileIssueCallback::addIssue(const ProjectIssueLevel level, const ProjectIssueType type, const ProjectError subject,
8787
const std::string details) const {
88-
co_await issues_.addIssue(level, type, subject, details, path_.string());
88+
co_await issues_->addIssue(level, type, subject, details, path_.string());
8989
}
9090

9191
void ProjectFileIssueCallback::addIssueAsync(const ProjectIssueLevel level, const ProjectIssueType type, const ProjectError subject,
9292
const std::string &details) const {
93-
issues_.addIssueAsync(level, type, subject, details, path_.string());
93+
issues_->addIssueAsync(level, type, subject, details, path_.string());
9494
}
9595

9696
std::optional<ResourceLocation> ProjectFileIssueCallback::validateResourceLocation(const std::string &str) const {

src/service/storage/issues.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace service {
2828
std::string enumToStr(ProjectError status);
2929
ProjectError parseProjectError(const std::string &str);
3030

31-
class ProjectIssueCallback {
31+
class ProjectIssueCallback : public std::enable_shared_from_this<ProjectIssueCallback> {
3232
public:
3333
explicit ProjectIssueCallback(const std::string &, const std::shared_ptr<spdlog::logger> &);
3434

@@ -49,7 +49,7 @@ namespace service {
4949

5050
class ProjectFileIssueCallback {
5151
public:
52-
explicit ProjectFileIssueCallback(ProjectIssueCallback &, const std::filesystem::path &);
52+
explicit ProjectFileIssueCallback(const std::shared_ptr<ProjectIssueCallback> &, const std::filesystem::path &);
5353

5454
explicit ProjectFileIssueCallback(const ProjectFileIssueCallback &, const std::filesystem::path &);
5555

@@ -62,7 +62,7 @@ namespace service {
6262
std::optional<nlohmann::json> readAndValidateJson(const nlohmann::json &schema) const;
6363

6464
private:
65-
ProjectIssueCallback &issues_;
65+
std::shared_ptr<ProjectIssueCallback> issues_;
6666
const std::filesystem::path absolutePath_;
6767
const std::filesystem::path path_;
6868
};

src/service/system/game_data.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,15 +216,15 @@ namespace service {
216216
logger.info("Ingesting game data");
217217
ProjectBase &project = *global::virtualProject;
218218
const auto projectLogger = global::storage->getProjectLogger(project.getProject(), false);
219-
ProjectIssueCallback issues{"", projectLogger};
219+
const auto issues = std::make_shared<ProjectIssueCallback>("", projectLogger);
220220
const content::Ingestor ingestor{project, projectLogger, issues, enabledModules, false};
221221

222222
if (const auto result = co_await ingestor.runIngestor(); result != Error::Ok) {
223223
projectLogger->error("Error ingesting game data");
224224
co_return Error::ErrInternal;
225225
}
226226

227-
if (issues.hasErrors()) {
227+
if (issues->hasErrors()) {
228228
projectLogger->error("Encountered issues during game data ingestion");
229229
co_return Error::ErrInternal;
230230
}

0 commit comments

Comments
 (0)