diff options
| author | physick <mynameisgennadiy@vk.com> | 2026-07-28 01:07:07 +0500 |
|---|---|---|
| committer | physick <mynameisgennadiy@vk.com> | 2026-07-28 01:07:07 +0500 |
| commit | 2802c8e8bb987206da0991129e30f0c198cd8f37 (patch) | |
| tree | ea24e597346e986039dde716f73d97f42d636056 /src/wren_inter/wren_inter.c | |
| parent | 26957338e8b42df4ad18ab38f08c70fba4c14bb4 (diff) | |
versioning fix
Diffstat (limited to 'src/wren_inter/wren_inter.c')
| -rw-r--r-- | src/wren_inter/wren_inter.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/wren_inter/wren_inter.c b/src/wren_inter/wren_inter.c index 10ecc93..868b2fe 100644 --- a/src/wren_inter/wren_inter.c +++ b/src/wren_inter/wren_inter.c @@ -33,6 +33,7 @@ void errorFn(WrenVM* vm, WrenErrorType errorType, } } +// Obsolete char *EvaluateScript(char *script) { TraceLog(LOG_INFO, "Evaluating %s...", script); WrenVM *vm = InterpreterPrepareMachine(); @@ -77,3 +78,100 @@ void InterpreterFreeMachine(WrenVM *vm) { if (sb != NULL && sb->val != NULL) free(sb); wrenFreeVM(vm); } + +// ========== Async ========== + +typedef struct { + // The data that you want to access in the worker + void *data; + // Toggle this to true when the task is finished + bool is_done; +} Task; + +bool RunWithCancellation(Task *task, void *(*runner) (void *), int timeout); + +#if defined(unix) || defined(__unix__) || defined(__unix) + +#include <threads.h> +#include <pthread.h> +#include <unistd.h> + +// Returns false if the process was aborted +bool RunWithCancellation(Task *task, void *(*runner) (void *), int timeout) { + pthread_t thread_id; + if (pthread_create(&thread_id, NULL, runner, &task) != 0) { + TraceLog(LOG_ERROR, "Failed to create a pthread"); + return RESULT_INIT_ERROR; + } + + int elapsed = 0; + while (!task->is_done && elapsed < timeout) { + sleep(1); + elapsed += 1; + } + + if (!task->is_done) { + pthread_cancel(thread_id); + pthread_join(thread_id, NULL); + return false; + } + + return true; +} + +#endif + +// The task that the interpreter would need to run. Made for async reasons +typedef struct { + WrenVM *vm; + const char *module; + const char *script; + WrenInterpretResult result; + bool is_done; +} wrenTask; + +// Runs the wrenTask asynchronously +// FIX: Inject the cancellation parameters inside the worker thread definition +void *wren_worker(void *arg) { + int old_type; + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old_type); // + + Task *task_raw = (Task*)arg; + wrenTask *task = (wrenTask*)task_raw->data; + task->result = wrenInterpret(task->vm, task->module, task->script); + task_raw->is_done = true; + return NULL; +} + + +enum PUZZLE_TEST_RESULT wrenInterpretLimited(WrenVM* vm, const char* module, + const char* script, int sMax) { + + wrenTask *data = malloc(sizeof(wrenTask)); + data->vm = vm; + data->module = module; + data->script = script; + data->result = 0; + + Task *task = malloc(sizeof(Task)); + task->is_done = false; + task->data = data; + + if (!RunWithCancellation(task, wren_worker, sMax)) { + return RESULT_TIMEOUT; + } + + WrenInterpretResult interpret_res = data->result; + + free(data); + free(task); + + switch (interpret_res) { + case WREN_RESULT_COMPILE_ERROR: + return RESULT_COMPTIME_ERR; + case WREN_RESULT_RUNTIME_ERROR: + return RESULT_RUNTIME_ERR; + default: break; + } + return RESULT_OK; +} |
