#pragma once /** ** \defgroup task Task ** Task is responsible for running JS in C. It exposes just what is needed for ** sandboxed or trusted code, helps with communiciation between parent and ** child processes, including function calls and async operations across the ** boundaries. ** @{ */ #include #include "quickjs.h" /** An event loop. */ typedef struct uv_loop_s uv_loop_t; /** A timer. */ typedef struct uv_timer_s uv_timer_t; /** A task identifier. */ typedef int taskid_t; /** A promise identifier. */ typedef int promiseid_t; /** An exported function identifier. */ typedef int exportid_t; /** A handle to a task. */ typedef struct _tf_taskstub_t tf_taskstub_t; /** A task. */ typedef struct _tf_task_t tf_task_t; /** A trace instance. */ typedef struct _tf_trace_t tf_trace_t; /** An SSB instance. */ typedef struct _tf_ssb_t tf_ssb_t; /** The fixed ID of the parent task. */ static const taskid_t k_task_parent_id = 0; /** A message type that can be sent between tasks. */ typedef enum _tf_task_message_t { kResolvePromise, kRejectPromise, kInvokeExport, kReleaseExport, kReleaseImport, kActivate, kExecute, kKill, kSetImports, kGetExports, kLoadFile, kTaskError, kTaskTrace, kPrint, } tf_task_message_t; /** ** Create a task. ** @return A new task. */ tf_task_t* tf_task_create(); /** ** Configure a task from a file descriptor. Typically a pipe to the parent ** task's process. ** @param task The task to configure. ** @param fd The file descriptor. */ void tf_task_configure_from_fd(tf_task_t* task, int fd); /** ** Set the port number on which to run an SSB secure handshake server. ** @param task The task. ** @param port The port number or 0 to disable. */ void tf_task_set_ssb_port(tf_task_t* task, int port); /** ** Set the port number on which to run an HTTP server. ** @param task The task. ** @param port The port number of 0 to disable. */ void tf_task_set_http_port(tf_task_t* task, int port); /** ** Set the port number on which to run an HTTPS server. ** @param task The task. ** @param port The port number of 0 to disable. */ void tf_task_set_https_port(tf_task_t* task, int port); /** ** Set the path to the SQLite database. ** @param task The task. ** @param path The database path. */ void tf_task_set_db_path(tf_task_t* task, const char* path); /** ** Set the path to a zip file from which to load all static data. ** @param task The task. ** @param path The zip file path or NULL. */ void tf_task_set_zip_path(tf_task_t* task, const char* path); /** ** Get the path to the zipp file being used for static data. ** @param task The task. ** @return The zip file path or NULL. */ const char* tf_task_get_zip_path(tf_task_t* task); /** ** Set arbitrary named arguments that will be made available to the task. ** @param task The task. ** @param args A string of the form "key=value,other_key=other_value,..." */ void tf_task_set_args(tf_task_t* task, const char* args); /** ** Get whether this instance is configure to run in a single process. ** @param task The running task. ** @return true if all tasks are running in a single process. */ bool tf_task_get_one_proc(tf_task_t* task); /** ** Set whether all tasks should run in a single process. Only supported to ** appease Apple's limitations. ** @param task The running task. ** @param one_proc True if subprocesses should not be used. */ void tf_task_set_one_proc(tf_task_t* task, bool one_proc); /** ** Start a task running its script. ** @param task The task. */ void tf_task_activate(tf_task_t* task); /** ** Update a task until it is done or stopped. ** @param task The task. */ void tf_task_run(tf_task_t* task); /** ** Run a script from file on disk. ** @param task The task. ** @param file The path to the script file to run. ** @return 0 if there was a problem or 1 if the script was started. */ int tf_task_execute(tf_task_t* task, const char* file); /** ** Set a task as trusted or untrusted. Trusted tasks have more interface exposed to them. ** @param task The task. ** @param trusted true if the task is trusted. */ void tf_task_set_trusted(tf_task_t* task, bool trusted); /** ** Get the JS context from a task. ** @param task The task. ** @return The context. */ JSContext* tf_task_get_context(tf_task_t* task); /** ** Destroy a task. ** @param task The task. */ void tf_task_destroy(tf_task_t* task); /** ** Convert a function to an integer handle that can be passed across processes. ** @param task The running task. ** @param to The task stub to which the handle will be passed. ** @param function The functoin to export. ** @return A handle representing the function. */ exportid_t tf_task_export_function(tf_task_t* task, tf_taskstub_t* to, JSValue function); /** ** Create a function that can be called from a handle to an exported function ** from another task. ** @param task The running task. ** @param stub_id The task stub from which the function was exported. ** @param export_id The handle to the function. ** @return A function that, when called, invokes the corresponding function in ** the remote task. */ JSValue tf_task_add_import(tf_task_t* task, taskid_t stub_id, exportid_t export_id); /** ** Get the event loop from a task. ** @param task The task. ** @return The loop. */ uv_loop_t* tf_task_get_loop(tf_task_t* task); /** ** Get the task from a JS context. ** @param context The context. ** @return The task. */ tf_task_t* tf_task_get(JSContext* context); /** ** Get the trace instance from a task. ** @param task The task. ** @return The trace instance. */ tf_trace_t* tf_task_get_trace(tf_task_t* task); /** ** Get the SSB instance from a task. ** @param task The task. ** @return The SSB instance. */ tf_ssb_t* tf_task_get_ssb(tf_task_t* task); /** ** Get the name of a task. ** @param task The task. ** @return The task's name as derived from the script it is running. */ const char* tf_task_get_name(tf_task_t* task); /** ** Print through a task's parent. ** @param task The running task. ** @param argc The number of arguments to print. ** @param argv The arguments to print. */ void tf_task_print(tf_task_t* task, int argc, JSValueConst* argv); /** ** Allocate a promise object. ** @param task The running task. ** @param[out] out_promise The promise that was allocated. ** @return The promise JS object. */ JSValue tf_task_allocate_promise(tf_task_t* task, promiseid_t* out_promise); /** ** Reject a promise. ** @param task The running task. ** @param promise The promise to reject. ** @param error The value with which to reject the promise. */ void tf_task_reject_promise(tf_task_t* task, promiseid_t promise, JSValue error); /** ** Resolve a promise. ** @param task The running task. ** @param promise The promise to resolve. ** @param result The value with which to resolve the promise. */ void tf_task_resolve_promise(tf_task_t* task, promiseid_t promise, JSValue result); /** ** Send a message referencing a promise across a packet stream. ** @param from The task originating the message. ** @param to The task handle receiving the message. ** @param type The message type. ** @param promise The promise. ** @param payload The content of the message. */ void tf_task_send_promise_message(tf_task_t* from, tf_taskstub_t* to, tf_task_message_t type, promiseid_t promise, JSValue payload); /** ** Have a task handle a message from a packaet stream. ** @param packetType The type of the message. ** @param begin The data. ** @param length The size of the data. ** @param userData The task stub from which the packet was received. */ void tf_task_on_receive_packet(int packetType, const char* begin, size_t length, void* userData); /** ** Generate an unused task identifier representing the task stub from the running task. ** @param task The running task. ** @param stub A handle to the task requesting an identifier. ** @return The new identifier. */ taskid_t tf_task_allocate_task_id(tf_task_t* task, tf_taskstub_t* stub); /** ** Remove a task stub from a task. ** @param task The parent task. ** @param child The task handle to remove. */ void tf_task_remove_child(tf_task_t* task, tf_taskstub_t* child); /** ** Send an error to the parent task. ** @param task The current task. ** @param error The potential error. ** @return true If the object was an error or exception and it was passed to ** the parent task. */ bool tf_task_send_error_to_parent(tf_task_t* task, JSValue error); /** ** Get a report of recent disconnections. ** @param task The task. ** @return A JSON representation of recent disconnections that must be freed ** with tf_free(). */ char* tf_task_get_disconnections(tf_task_t* task); /** ** Get a report of miscellaneous debug information. ** @param task The task. ** @return A JSON representation of various debug information that must be ** freed with tf_free(). */ char* tf_task_get_debug(tf_task_t* task); /** ** Get a report of hitches that occurred. ** @param task The task. ** @return A JSON report of recent hitches that must be freed with tf_free(). */ char* tf_task_get_hitches(tf_task_t* task); /** @} */