Skip to content

Commit 74349d1

Browse files
gh-87: Enforce STOP.
1 parent a7e9605 commit 74349d1

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

src/interpreter.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,17 @@ static int parfor_worker(void* arg) {
350350

351351
// ============ Helper functions ============
352352

353+
// Return non-zero if the current executing thread has been requested to stop.
354+
static inline int interpreter_thr_should_stop(Interpreter* interp) {
355+
if (!interp || !interp->current_thr) return 0;
356+
int finished = 0;
357+
mtx_lock(&interp->current_thr->state_lock);
358+
finished = interp->current_thr->finished;
359+
mtx_unlock(&interp->current_thr->state_lock);
360+
return finished;
361+
}
362+
363+
353364
static void* safe_malloc(size_t size) {
354365
void* ptr = malloc(size);
355366
if (!ptr) {
@@ -2245,6 +2256,12 @@ static ExecResult exec_stmt(Interpreter* interp, Stmt* stmt, Env* env, LabelMap*
22452256
if (!stmt) return make_ok(value_null());
22462257
trace_log_step(interp, stmt, env);
22472258

2259+
// If running in a background thread and a STOP has been requested for
2260+
// this thread, terminate execution cooperatively by returning early.
2261+
if (interpreter_thr_should_stop(interp)) {
2262+
return make_ok(value_null());
2263+
}
2264+
22482265
switch (stmt->type) {
22492266
case STMT_BLOCK:
22502267
return exec_stmt_list(interp, &stmt->as.block, env, labels);
@@ -2785,6 +2802,9 @@ static ExecResult exec_stmt(Interpreter* interp, Stmt* stmt, Env* env, LabelMap*
27852802
const unsigned long long max_iterations = 18446744073709551615; // Prevent infinite loops
27862803

27872804
while (1) {
2805+
if (interpreter_thr_should_stop(interp)) {
2806+
break;
2807+
}
27882808
if (++iteration_count > max_iterations) {
27892809
interp->loop_depth--;
27902810
return make_error("Infinite loop detected", stmt->line, stmt->column);
@@ -2900,6 +2920,9 @@ static ExecResult exec_stmt(Interpreter* interp, Stmt* stmt, Env* env, LabelMap*
29002920
}
29012921

29022922
for (int64_t idx = 1; idx <= limit; idx++) {
2923+
if (interpreter_thr_should_stop(interp)) {
2924+
break;
2925+
}
29032926
if (++iteration_count > max_iterations) {
29042927
/* cleanup alias/temp and restore previous local if needed */
29052928
env_delete(env, stmt->as.for_stmt.counter);

0 commit comments

Comments
 (0)