#include /* Letter type for unified message queue */ typedef enum { LETTER_BLOB, /* Blob message */ LETTER_CALLBACK /* JSValue callback function */ } letter_type; typedef struct letter { letter_type type; union { blob *blob_data; /* For LETTER_BLOB */ JSValue callback; /* For LETTER_CALLBACK */ }; } letter; #define ACTOR_IDLE 0 // Actor not doing anything #define ACTOR_READY 1 // Actor ready for a turn #define ACTOR_RUNNING 2 // Actor taking a turn #define ACTOR_EXHAUSTED 3 // Actor waiting for GC #define ACTOR_RECLAIMING 4 // Actor running GC #define ACTOR_SLOW 5 // Actor going slowly; deprioritize typedef struct cell_rt { JSContext *context; JSValue idx_buffer; JSValue on_exception; JSValue message_handle; void *init_wota; /* Protects JSContext usage */ pthread_mutex_t *mutex; /* for everything else */ pthread_mutex_t *msg_mutex; /* For message queue and timers queue */ char *id; int idx_count; /* The “mailbox” for incoming messages + a dedicated lock for it: */ letter *letters; /* CHANGED FOR EVENTS: a separate lock for the actor->events queue */ struct { uint32_t key; JSValue value; } *timers; int state; uint32_t ar; // timer for unneeded double ar_secs; // time for unneeded JSValue unneeded; // fn to call before unneeded int disrupt; int main_thread_only; int affinity; JSValue actor_sym; const char *name; // human friendly name cell_hook trace_hook; } cell_rt; cell_rt *create_actor(void *wota); const char *register_actor(const char *id, cell_rt *actor, int mainthread, double ar); void actor_disrupt(cell_rt *actor); JSValue actor_sym(cell_rt *actor); const char *send_message(const char *id, void *msg); const char *register_actor(const char *id, cell_rt *actor, int mainthread, double ar); void actor_unneeded(cell_rt *actor, JSValue fn, double seconds); void script_startup(cell_rt *rt); int uncaught_exception(JSContext *js, JSValue v); int actor_exists(const char *id); void set_actor_state(cell_rt *actor); void actor_clock(cell_rt *actor, JSValue fn); uint32_t actor_delay(cell_rt *actor, JSValue fn, double seconds); JSValue actor_remove_timer(cell_rt *actor, uint32_t timer_id); void exit_handler(void); int actor_interrupt_cb(JSRuntime *rt, cell_rt *crt); void actor_loop(); void actor_initialize(void); void actor_free(cell_rt *actor); uint64_t cell_ns(); void cell_sleep(double seconds); int randombytes(void *buf, size_t n);