Fixed the heap-use-after-free issue.

Just standard multithreading stuff; access to the allocator while hot
threads are running means stuff can change underneath us even /during/
a read.  I've mutex locked state for stuff in the drawing domain which
stops this issue.
This commit is contained in:
2025-12-12 04:29:32 +00:00
parent 5d78cb20df
commit a5666328b7
4 changed files with 12 additions and 4 deletions

View File

@@ -52,7 +52,7 @@ constexpr u64 clamp_to_width(const DrawState &ds, f64 val)
(val - ds.bounds.lower_val);
}
void draw_tree(const DrawState &ds, const State &state)
void draw_tree(DrawState &ds, State &state)
{
// Number line
DrawLine(0, HEIGHT / 2, WIDTH, HEIGHT / 2, WHITE);
@@ -63,6 +63,7 @@ void draw_tree(const DrawState &ds, const State &state)
DrawLine(lower_x, LINE_TOP, lower_x, LINE_BOTTOM, WHITE);
DrawLine(upper_x, LINE_TOP, upper_x, LINE_BOTTOM, WHITE);
state.mutex.lock();
std::stack<std::pair<u64, f64>> stack;
cw::node::Node n = state.allocator.get_val(0);
stack.push(std::make_pair(0, n.value.norm));
@@ -87,6 +88,7 @@ void draw_tree(const DrawState &ds, const State &state)
stack.push(std::make_pair(n.right, right.value.norm));
}
}
state.mutex.unlock();
}
using Clock = std::chrono::steady_clock;

View File

@@ -12,6 +12,7 @@ namespace cw::state
{
void DrawState::compute_bounds()
{
state.mutex.lock();
bounds.leftmost = state.allocator.get_val(0);
while (bounds.leftmost.left >= 0)
bounds.leftmost = state.allocator.get_val(bounds.leftmost.left);
@@ -19,6 +20,7 @@ namespace cw::state
bounds.rightmost = state.allocator.get_val(0);
while (bounds.rightmost.right >= 0)
bounds.rightmost = state.allocator.get_val(bounds.rightmost.right);
state.mutex.unlock();
bounds.lower_val = std::floorl(bounds.leftmost.value.norm);
bounds.upper_val = std::ceill(bounds.rightmost.value.norm);

View File

@@ -29,14 +29,14 @@ namespace cw::state
struct DrawState
{
const State &state;
State &state;
struct Bounds
{
cw::node::Node leftmost, rightmost;
f64 lower_val, upper_val;
} bounds;
DrawState(const State &state) : state{state} {};
DrawState(State &state) : state{state} {};
void compute_bounds(void);
};