About Run Loops

Core Foundation provides the basis for every application’s event loop with the CFRunLoop opaque type. A CFRunLoop object monitors objects that represent various sources of input to a task. The run loop dispatches control when an input source becomes ready for processing. Examples of input sources might include user input devices, network connections, periodic or time-delayed events, and asynchronous callbacks. Input sources are registered with a run loop, and when a run loop is “run”, callback functions associated with each input source are called when some activity occurs.

While being run, a run loop goes through a cycle of activities. Input sources are checked, timers which need firing are fired, and then the run loop blocks, waiting for something to happen (or in the case of timers, waiting for it to be time for something to happen). When something does happen, the run loop wakes up, processes the activity (usually by calling a callback function for an input source), checks other sources, fires timers, and goes back to sleep. And so on.

Run loops are strongly tied to the threads in your application. Every thread has exactly one run loop. No more and no less. Each thread’s run loop monitors its own independent list of objects. (See Input Modes for details on how a run loop can monitor subsets of its objects.) In a Carbon or Cocoa application, for instance, the main thread’s run loop normally monitors all the events generated by the user. Additional threads may use their run loops to listen for (and then process) network activity, to receive messages from other threads or processes, or to perform periodic activities. By placing these input sources in different run loops on separate threads, the events can be processed without blocking any other thread’s run loop, such as the main thread’s run loop, which processes user events.

Three types of objects can be placed into and monitored by a run loop: sources, timers, and observers. Each is described in the following sections.

Sources

Run loop sources, represented by the CFRunLoopSource opaque type, are abstractions of input sources that can be put into a run loop. Input sources typically generate asynchronous events, such as messages arriving on a network port or actions performed by the user.

An input source type normally defines an API for creating and operating on objects of the type, as if it were a separate entity from the run loop, then provides a function to create a CFRunLoopSource for an object. The run loop source can then be registered with the run loop and act as an intermediary between the run loop and the actual input source type object. Examples of input sources include CFMachPort, CFMessagePort, and CFSocket.

Timers

Run loop timers, represented by the CFRunLoopTimer opaque type, are specialized run loop sources that fire at preset times in the future. Timers can fire either only once or repeatedly at fixed time intervals. Repeating timers can also have their next firing time manually adjusted.

Observers

Run loop observers, represented by the CFRunLoopObserver opaque type, provide a general means to receive callbacks at different points within a running run loop. In contrast to sources, which fire when an asynchronous event occurs, and timers, which fire when a particular time passes, observers fire at special locations within the execution of the run loop, such as before sources are processed or before the run loop goes to sleep, waiting for an event to occur. In essence, observers are specialized run loop sources that represent events inside the run loop itself.

Observers can be either one-time events or repeated every time through the run loop’s loop.