* approach to concurrency / signal safety ** a signal can occur at any time ** all programs have "critical sections" blocks of sequential instructions that must be executed to completion ** it's critical to ensure that it never uses or modifies variables that could be in an inconsistent state ** typical approach is to keep the signal handler short and simple transfer the unsafe code execution out of the signal handler * core model is an event queue ** signal handler triggers, push an event on the queue ** in the main control flow, loop dequeueing events and executing their handlers - this doesn't eliminate all critical sections - queue and dequeue are still critical - if you're handling multiple signal types, each handler is a critical section for the queue ** event queue will mainly be used when you need it for multiple signal types ** with a single signal, you can really just count * ignoring signals vs blocking signals ** ignore just means "I don't care" -- no signal handler ** blocking means "tell me later" -- one signal handler may execute critical sections need to be as short as possible also a reason to keep signal handlers short, by default the signal that triggered the handler is blocked during handler exec * probably need sigaction rather than signal for event counters.