Eroxl's Notes
Event-Driven Programming

Event-driven programming is a programming paradigm where the flow of the program is determined by events—occurrences such as I/O completions, user interactions, or timer expirations. Code is structured around event handlers (callbacks) that execute asynchronously when their associated events occur.

Key Concepts

  • Event: An occurrence that triggers code execution (e.g., disk read completion, mouse click)
  • Event Handler: A function that executes when a specific event occurs
  • Event Registration: Associating a handler with an event
  • Event Firing: Triggering the execution of registered handlers

Example

void computeChecksum(char *buf, int blockNum, int numBytes) {
    char xsum = 0;
    for (int i = 0; i < numBytes; i++)
        xsum ^= buf[i];
    printf("Checksum: %d\n", xsum);
    free(buf);
}

void checksumDiskData(int blockNum, int numBytes) {
    char *buf = malloc(numBytes);
    // Register handler and initiate read
    diskRead(buf, blockNum, numBytes, computeChecksum);
    // Function returns immediately; handler runs later
}

Challenges

Event-driven code is inherently more difficult than sequential code:

  • Callback hell: Deeply nested callbacks make code hard to read and maintain
  • Control flow: The execution order is non-obvious from reading the code
  • Debugging: Stack traces are fragmented across multiple callback invocations
  • State management: Sharing data between handlers requires careful management

Why Use Event-Driven Programming

Despite the difficulties, event-driven programming is necessary when dealing with asynchronous operations like I/O. The CPU can execute millions of instructions while waiting for a single disk read; event-driven code allows useful work during these waits.

Event-driven programming is common in:

  • GUI applications (handling user input events)
  • Web programming (JavaScript, Node.js)
  • Operating systems (handling interrupts)
  • Network programming (handling incoming connections and data)