#ifndef R2_CORE_TASK_H #define R2_CORE_TASK_H #ifdef __cplusplus extern "C" { #endif typedef void (*RCoreTaskCallback)(void *user, char *out); typedef enum r_core_task_mode_t { R_CORE_TASK_MODE_COOP, // Current cooperative model R_CORE_TASK_MODE_THREAD, // True threading with isolated core R_CORE_TASK_MODE_FORK // Process fork with IPC } RCoreTaskMode; typedef enum r_core_task_state_t { R_CORE_TASK_STATE_BEFORE_START, R_CORE_TASK_STATE_RUNNING, R_CORE_TASK_STATE_SLEEPING, R_CORE_TASK_STATE_DONE } RTaskState; typedef struct r_core_task_t { int id; RTaskState state; bool transient; // delete when finished bool dispatched; bool cmd_log; RCoreTaskMode mode; RThreadSemaphore *running_sem; void *user; RCore *core; RCons *cons; // owned child console for captured command output struct r_cmd_context_t *cur_context; // innermost command context running on this task // Thread/fork specific RThread *thread; // Thread handle (for thread mode) int pid; // Process ID (for fork mode) // Existing dispatch mechanism RThreadCond *dispatch_cond; RThreadLock *dispatch_lock; // Command and results char *cmd; char *res; RCoreTaskCallback cb; } RCoreTask; typedef struct r_core_tasks_t { int task_id_next; RList *tasks; RList *tasks_queue; struct r_core_task_t *main_task; RThreadLock *lock; #if !HAVE_TH_LOCAL RList *task_threads; // (thread, task) bindings resolved by r_core_task_self #endif struct r_core_task_t *foreground_task; // Current ^C target RCoreTaskMode default_mode; // Default execution mode int tasks_running; RCore *main_core; // Reference to main core } RCoreTaskScheduler; R_API void r_core_task_scheduler_init(RCoreTaskScheduler *tasks, RCore *core); R_API void r_core_task_scheduler_fini(RCoreTaskScheduler *tasks); R_API RCoreTask *r_core_task_get(RCoreTaskScheduler *scheduler, int id); R_API int r_core_task_running_tasks_count(RCoreTaskScheduler *scheduler); R_API const char *r_core_task_status(RCoreTask *task); R_API RCoreTask *r_core_task_new(RCore *core, RCoreTaskMode mode, bool create_cons, const char *cmd, RCoreTaskCallback cb, void *user); R_API void r_core_task_enqueue(RCoreTaskScheduler *scheduler, RCoreTask *task); R_API int r_core_task_run_sync(RCoreTaskScheduler *scheduler, RCoreTask *task); R_API void r_core_task_sync_begin(RCoreTaskScheduler *scheduler); R_API void r_core_task_sync_end(RCoreTaskScheduler *scheduler); R_API void r_core_task_yield(RCoreTaskScheduler *scheduler); R_API void r_core_task_sleep_begin(RCoreTask *task); R_API void r_core_task_sleep_end(RCoreTask *task); R_API int r_core_task_del(RCoreTaskScheduler *scheduler, int id); R_API void r_core_task_del_all_done(RCoreTaskScheduler *scheduler); R_API RCoreTask *r_core_task_self(RCoreTaskScheduler *scheduler); R_API bool r_core_task_ismain(RCoreTaskScheduler *scheduler); R_API void r_core_task_join(RCoreTaskScheduler *scheduler, RCoreTask *current, int id); R_API void r_core_task_set_foreground(RCoreTaskScheduler *scheduler, int task_id); R_API RCoreTask *r_core_task_get_foreground(RCoreTaskScheduler *scheduler); R_API void r_core_task_set_default_mode(RCoreTaskScheduler *scheduler, RCoreTaskMode mode); R_API RCoreTaskMode r_core_task_get_default_mode(RCoreTaskScheduler *scheduler); R_API int r_core_task_run(RCoreTaskScheduler *scheduler, RCoreTask *task, int mode); R_API int r_core_task_run_threaded(RCoreTaskScheduler *scheduler, RCoreTask *task); R_API int r_core_task_run_forked(RCoreTaskScheduler *scheduler, RCoreTask *task); R_API void r_core_task_set_foreground(RCoreTaskScheduler *scheduler, int task_id); R_API RCoreTask *r_core_task_get_foreground(RCoreTaskScheduler *scheduler); R_API RCoreTask *r_core_task_submit(RCore *core, const char *cmd, RCoreTaskCallback cb, void *user, bool capture_cons, int mode); R_API int r_core_task_id(const RCoreTask *t); R_API bool r_core_task_wait(RCoreTask *t, ut64 timeout_ms); R_API bool r_core_task_cancel(RCoreTask *t, bool hard); R_API void r_core_task_cancel_all(RCore *core, bool hard); R_API void r_core_task_free(RCoreTask *t); #ifdef __cplusplus } #endif #endif