A routine which is executed when an interrupt occurs. Interrupt handlers typically deal with low-level events in the hardware of a computer system such as a character arriving at a serial port or a tick of a real-time clock. Special care is required when writing an interrupt handler to ensure that either the interrupt which triggered the handler's execution is masked out (inhibitted) until the handler exits, or the handler is re-entrant so that multiple concurrent invocations will not interfere with each other.
If interrupts are masked then the handler must execute as quickly as possible so that important events are not missed. This is often arranged by splitting the processing associated with the event into "upper" and "lower" halves. The lower part is the interrupt handler which masks out further interrupts as required, checks that the appropriate event has occurred (this may be necessary if several events share the same interrupt), services the interrupt, e.g. by reading a character from a UART and writing it to a queue, and re-enabling interrupts.
The upper half executes as part of a user process. It waits until the interrupt handler has run. Normally the operating system is responsible for reactivating a process which is waiting for some low-level event. It detects this by a shared flag or by inspecting a shared queue or by some other synchronisation mechanism. It is important that the upper and lower halves do not interfere if an interrupt occurs during the execution of upper half code. This is usually ensured by disabling interrupts during critical sections of code such as removing a character from a queue.