NAME ^

src/events.c - Event handling stuff

DESCRIPTION ^

An event_thread handles async events for all interpreters. When events are due, they are placed in per interpreter task_queues, where they are handled then by the check_event* opcodes.

IO events and signals are caught in the io_thread, which again dispatches these to one or all interpreters.

Signal Handling ^

static void sig_handler(int signum)

Handle signal signum.

TODO - Only SIGHUP is handled at the moment for testing

static void Parrot_sigaction(int sig, NULLOK(void (*handler)(int)))

Signal handlers are common to all threads, signal block masks are specific, so we install one handler then block that signal and unblock it in the thread, that will receive that signal.

static void Parrot_unblock_signal(int sig)

unblock a signal

PARROT_API void Parrot_init_signals(void)

RT#48260: Not yet documented!!!

Initialization ^

static void init_events_first(PARROT_INTERP)

Init event system for first interpreter.

static void init_events_all(PARROT_INTERP)

Init events for all interpreters.

PARROT_API void Parrot_init_events(PARROT_INTERP)

Initialize the event system.

Event Handler Functions ^

PARROT_API void Parrot_schedule_event(PARROT_INTERP, NOTNULL(parrot_event *ev))

Create queue entry and insert event into task queue.

static void schedule_signal_event(int signum)

create and schedule a signal event

PARROT_API void Parrot_new_timer_event(PARROT_INTERP, NULLOK(PMC *timer), FLOATVAL diff, FLOATVAL interval, int repeat, NULLOK(PMC *sub), parrot_event_type_enum typ)

Create a new timer event due at diff from now, repeated at interval and running the passed sub.

PARROT_API void Parrot_new_cb_event(PARROT_INTERP, NOTNULL(PMC *cbi), NOTNULL(char *ext))

Prepare and schedule a callback event.

PARROT_API void Parrot_del_timer_event(PARROT_INTERP, NOTNULL(PMC *timer))

Deactivate the timer identified by timer.

PARROT_API void Parrot_new_terminate_event(PARROT_INTERP)

Create a terminate event, interpreter will leave the run-loop when this event arrives.

PARROT_API void Parrot_new_suspend_for_gc_event(PARROT_INTERP)

Create a suspend-for-GC event, interpreter will wait on a condition variable for GC to finish when the event arrives.

PARROT_API void Parrot_kill_event_loop(PARROT_INTERP)

Schedule event-loop terminate event. This shuts down the event thread.

PARROT_API void Parrot_schedule_interp_qentry(PARROT_INTERP, NOTNULL(struct QUEUE_ENTRY *entry))

Put a queue entry into the interpreters task queue and enable event checking for the interpreter.

void Parrot_schedule_broadcast_qentry(NOTNULL(struct QUEUE_ENTRY *entry))

Broadcast an event.

IO Thread Handling ^

static void store_io_event(NOTNULL(pending_io_events *ios), NOTNULL(parrot_event *ev))

RT#48260: Not yet documented!!!

static void io_thread_ready_rd(NOTNULL(pending_io_events *ios), int ready_rd)

RT#48260: Not yet documented!!!

PARROT_CAN_RETURN_NULL static void *io_thread(SHIM(void *data))

The IO thread uses select/poll to handle IO events and signals.

It waits on input from the message pipe to insert file descriptors in the wait sets.

static void stop_io_thread(void)

Tell the IO thread to stop.

PARROT_API void Parrot_event_add_io_event(PARROT_INTERP, NULLOK(PMC *pio), NULLOK(PMC *sub), NULLOK(PMC *data), INTVAL which)

RT#48260: Not yet documented!!!

Event Handler Thread Functions ^

PARROT_MALLOC PARROT_CANNOT_RETURN_NULL static QUEUE_ENTRY *dup_entry(ARGIN(const QUEUE_ENTRY *entry))

Duplicate queue entry.

PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL static QUEUE_ENTRY *dup_entry_interval(NOTNULL(QUEUE_ENTRY *entry), FLOATVAL now)

Duplicate timed entry and add interval to abs_time.

static int process_events(NOTNULL(QUEUE *event_q))

Do something, when an event arrived caller has locked the mutex returns 0 if event thread terminates.

PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL static void *event_thread(NOTNULL(void *data))

The event thread is started by the first interpreter. It handles all events for all interpreters.

Sleep Handling ^

PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL static opcode_t *wait_for_wakeup(PARROT_INTERP, NULLOK(opcode_t *next))

Sleep on the event queue condition. If an event arrives, the event is processed. Terminate the loop if sleeping is finished.

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL opcode_t *Parrot_sleep_on_event(PARROT_INTERP, FLOATVAL t, NULLOK(opcode_t *next))

Go to sleep. This is called from the sleep opcode.

Event Handling for Run-Loops ^

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL opcode_t *Parrot_do_check_events(PARROT_INTERP, NULLOK(opcode_t *next))

Explicitly sync called by the check_event opcode from run loops.

static void event_to_exception(PARROT_INTERP, ARGIN(const parrot_event *event))

Convert event to exception and throw it.

PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL static opcode_t *do_event(PARROT_INTERP, NOTNULL(parrot_event *event), NULLOK(opcode_t *next))

Run user code or such.

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL opcode_t *Parrot_do_handle_events(PARROT_INTERP, int restore, NULLOK(opcode_t *next))

Called by the check_event__ opcode from run loops or from above. When called from the check_events__ opcode, we have to restore the op_func_table.

SEE ALSO ^

include/parrot/events.h and docs/dev/events.pod.


parrot