🔍 Module Scanned
src/engine/core/ (automated audit scan)
📝 Summary
In JobQueue.doReprioritize, when re-adding jobs to the priority queue fails (due to an allocation error), the job is silently dropped without calling its cleanup_fn. This causes a memory leak for generic jobs that own heap-allocated context.
📍 Location
- File:
src/engine/core/job_system.zig:226-229
- Function/Scope:
JobQueue.doReprioritize
🔴 Severity: High
- High: Memory leaks, race conditions, incorrect rendering, broken features
💥 Impact
When the priority queue's underlying array grows during add() and the allocation fails, any generic job that was successfully extracted from the original queue and appended to the temporary list is permanently lost. The cleanup_fn is never called, leaking any heap-allocated context the job owns. This accumulates over time as the player moves and the queue is repeatedly reprioritized.
🔎 Evidence
// Re-add with updated priorities
for (temp.items) |job| {
self.jobs.add(job) catch {
log.log.warn("Job queue: failed to re-add job after priority update", .{});
continue; // <-- BUG: job dropped, cleanup never called
};
}
Compare to the correct pattern in doReprioritize at line 217-221:
temp.append(self.allocator, updated_job) catch {
log.log.warn("Job queue: dropped job during priority update (allocation failed)", .{});
updated_job.cleanup(); // <-- CORRECT: cleanup is called
continue;
};
The first catch block (line 219) correctly calls updated_job.cleanup() before dropping the job. The second catch block (line 226-229) does not, causing a leak.
🛠️ Proposed Fix
Add job.cleanup() before continue in the second catch block at line 226:
self.jobs.add(job) catch {
log.log.warn("Job queue: failed to re-add job after priority update", .{});
job.cleanup(); // Release generic job context before dropping
continue;
};
✅ Acceptance Criteria
📚 References
- Related:
Job.cleanup() at line 92-101 which handles cleanup for generic jobs
- Related:
doReprioritize at line 217-221 which correctly calls cleanup before dropping jobs
🔍 Module Scanned
src/engine/core/(automated audit scan)📝 Summary
In
JobQueue.doReprioritize, when re-adding jobs to the priority queue fails (due to an allocation error), the job is silently dropped without calling itscleanup_fn. This causes a memory leak for generic jobs that own heap-allocated context.📍 Location
src/engine/core/job_system.zig:226-229JobQueue.doReprioritize🔴 Severity: High
💥 Impact
When the priority queue's underlying array grows during
add()and the allocation fails, any generic job that was successfully extracted from the original queue and appended to the temporary list is permanently lost. Thecleanup_fnis never called, leaking any heap-allocated context the job owns. This accumulates over time as the player moves and the queue is repeatedly reprioritized.🔎 Evidence
Compare to the correct pattern in
doReprioritizeat line 217-221:The first
catchblock (line 219) correctly callsupdated_job.cleanup()before dropping the job. The secondcatchblock (line 226-229) does not, causing a leak.🛠️ Proposed Fix
Add
job.cleanup()beforecontinuein the second catch block at line 226:✅ Acceptance Criteria
src/engine/core/job_system.zigpasscleanup_fnthat fail to re-prioritize have their cleanup calledstd.mem.Allocatorfails duringjobs.add()indoReprioritize📚 References
Job.cleanup()at line 92-101 which handles cleanup for generic jobsdoReprioritizeat line 217-221 which correctly calls cleanup before dropping jobs