---
name: "dispatch_source_set_event_handler"
section: "3"
platform: "linux"
package: "libdispatch-dev"
version: "0~svn197-3.2"
release: "Debian 8 (Jessie)"
platforms: ["linux"]
url: "https://new.carta.tech/dispatch_source_create"
---

# dispatch\_source\_set\_event\_handler(3)

dispatch event sources

Part of [dispatch\_source\_create(3)](/dispatch_source_create/3.md).

## NAME

**dispatch\_source\_create** – dispatch event sources

## SYNOPSIS

**#include \<dispatch/dispatch.h\>**

*dispatch\_source\_t*\

**dispatch\_source\_create**(*dispatch\_source\_type\_t type*, *uintptr\_t handle*, *unsigned long mask*, *dispatch\_queue\_t queue*);

*void*\

**dispatch\_source\_set\_event\_handler**(*dispatch\_source\_t source*, *void (^block)(void)*);

*void*\

**dispatch\_source\_set\_event\_handler\_f**(*dispatch\_source\_t source*, *void (\*function)(void \*)*);

*void*\

**dispatch\_source\_set\_cancel\_handler**(*dispatch\_source\_t source*, *void (^block)(void)*);

*void*\

**dispatch\_source\_set\_cancel\_handler\_f**(*dispatch\_source\_t source*, *void (\*function)(void \*)*);

*void*\

**dispatch\_source\_cancel**(*dispatch\_source\_t source*);

*void*\

**dispatch\_source\_testcancel**(*dispatch\_source\_t source*);

*uintptr\_t*\

**dispatch\_source\_get\_handle**(*dispatch\_source\_t source*);

*unsigned long*\

**dispatch\_source\_get\_mask**(*dispatch\_source\_t source*);

*unsigned long*\

**dispatch\_source\_get\_data**(*dispatch\_source\_t source*);

*void*\

**dispatch\_source\_merge\_data**(*dispatch\_source\_t source*, *unsigned long data*);

*void*\

**dispatch\_source\_set\_timer**(*dispatch\_source\_t source*, *dispatch\_time\_t start*, *uint64\_t interval*, *uint64\_t leeway*);

## DESCRIPTION

Dispatch event sources may be used to monitor a variety of system objects and  events including file descriptors, mach ports, processes, virtual filesystem nodes, signal delivery and timers.

When a state change occurs, the dispatch source will submit its event handler block to its target queue.

The **dispatch\_source\_create**() function creates a new dispatch source object that may be retained and released with calls to **dispatch\_retain**() and **dispatch\_release**() respectively. Newly created sources are created in a suspended state. After the source has been configured by setting an event handler, cancellation handler, context, etc., the source must be activated by a call to **dispatch\_resume**() before any events will be delivered.

Dispatch sources may be one of the following types:

- DISPATCH\_SOURCE\_TYPE\_DATA\_ADD

- DISPATCH\_SOURCE\_TYPE\_DATA\_OR

- DISPATCH\_SOURCE\_TYPE\_MACH\_SEND

- DISPATCH\_SOURCE\_TYPE\_MACH\_RECV

- DISPATCH\_SOURCE\_TYPE\_PROC

- DISPATCH\_SOURCE\_TYPE\_READ

- DISPATCH\_SOURCE\_TYPE\_SIGNAL

- DISPATCH\_SOURCE\_TYPE\_TIMER

- DISPATCH\_SOURCE\_TYPE\_VNODE

- DISPATCH\_SOURCE\_TYPE\_WRITE

The *handle* and *mask* arguments to **dispatch\_source\_create**() and the return values of the  **dispatch\_source\_get\_handle**(), **dispatch\_source\_get\_mask**(), and **dispatch\_source\_get\_data**() functions should be interpreted according to the type of the dispatch source.

The  **dispatch\_source\_get\_handle**() function returns the underlying handle to the dispatch source (i.e. file descriptor, mach port, process identifer, etc.). The result of this function may be cast directly to the underlying type.

The  **dispatch\_source\_get\_mask**() function returns the set of flags that were specified at source creation time via the *mask* argument.

The **dispatch\_source\_get\_data**() function returns the currently pending data for the dispatch source. This function should only be called from within the source's event handler. The result of calling this function from any other context is undefined.

The **dispatch\_source\_merge\_data**() function is intended for use with the *DISPATCH\_SOURCE\_TYPE\_DATA\_ADD* and *DISPATCH\_SOURCE\_TYPE\_DATA\_OR* source types. The result of using this function with any other source type is undefined. Calling this function will atomically add or logical OR the data into the source's data, and trigger the delivery of the source's event handler.

## SOURCE EVENT HANDLERS

In order to receive events from the dispatch source, an event handler should be specified via **dispatch\_source\_set\_event\_handler**(). The event handler block is submitted to the source's target queue when the state of the underlying system handle changes, or when an event occurs.

Dispatch sources may be suspended or resumed independently of their target queues using **dispatch\_suspend**() and **dispatch\_resume**() on the dispatch source directly. The data describing events which occur while a source is suspended are coalesced and delivered once the source is resumed.

The *handler* block need not be reentrant safe, as it is not resubmitted to the target *queue* until any prior invocation for that dispatch source has completed. When the handler is set, the dispatch source will perform a **Block\_copy**() on the *handler* block.

## CANCELLATION

The **dispatch\_source\_cancel**() function asynchronously cancels the dispatch source, preventing any further invocation of its event handler block. Cancellation does not interrupt a currently executing handler block (non-preemptive).

The **dispatch\_source\_testcancel**() function may be used to determine whether the specified source has been canceled. A non-zero value will be returned if the source is canceled.

When a dispatch source is canceled its optional cancellation handler will be submitted to its target queue. The cancellation handler may be specified via **dispatch\_source\_set\_cancel\_handler**(). This cancellation handler is invoked only once, and only as a direct consequence of calling **dispatch\_source\_cancel**().

*Important:* a cancellation handler is required for file descriptor and mach port based sources in order to safely close the descriptor or destroy the port. Closing the descriptor or port before the cancellation handler has run may result in a race condition: if a new descriptor is allocated with the same value as the recently closed descriptor while the source's event handler is still running, the event handler may read/write data to the wrong descriptor.

## DISPATCH SOURCE TYPES

The following section contains a summary of supported dispatch event types and the interpretation of their parameters and returned data.

*DISPATCH\_SOURCE\_TYPE\_DATA\_ADD*, *DISPATCH\_SOURCE\_TYPE\_DATA\_OR*

Sources of this type allow applications to manually trigger the source's event handler via a call to  **dispatch\_source\_merge\_data**(). The data will be merged with the source's pending data via an atomic add or logic OR (based on the source's type), and the event handler block will be submitted to the source's target queue. The *data* is application defined. These sources have no *handle* or *mask* and zero should be used.

*DISPATCH\_SOURCE\_TYPE\_MACH\_SEND*

Sources of this type monitor a mach port with a send right for state changes. The *handle* is the mach port (mach\_port\_t) to monitor and the *mask* may be:

- • DISPATCH\_MACH\_SEND\_DEAD

  The port's corresponding receive right has been destroyed

The data returned by **dispatch\_source\_get\_data**() indicates which of the events in the *mask* were observed.

*DISPATCH\_SOURCE\_TYPE\_MACH\_RECV*

Sources of this type monitor a mach port with a receive right for state changes. The *handle* is the mach port (mach\_port\_t) to monitor and the *mask* is unused and should be zero. The event handler block will be submitted to the target queue when a message on the mach port is waiting to be received.

*DISPATCH\_SOURCE\_TYPE\_PROC*

Sources of this type monitor processes for state changes. The *handle* is the process identifier (pid\_t) of the process to monitor and the *mask* may be one or more of the following:

- • DISPATCH\_PROC\_EXIT

  The process has exited and is available to  [wait(2)](/wait/2.md).

- • DISPATCH\_PROC\_FORK

  The process has created one or more child processes.

- • DISPATCH\_PROC\_EXEC

  The process has become another executable image via a call to [execve(2)](/execve/2.md) or [posix\_spawn(2)](/posix_spawn/2.md).

- • DISPATCH\_PROC\_REAP

  The process status has been collected by its parent process via [wait(2)](/wait/2.md).

- • DISPATCH\_PROC\_SIGNAL

  A signal was delivered to the process.

The data returned by **dispatch\_source\_get\_data**() indicates which of the events in the *mask* were observed.

*DISPATCH\_SOURCE\_TYPE\_READ*

Sources of this type monitor file descriptors for pending data. The *handle* is the file descriptor (int) to monitor and the *mask* is unused and should be zero.

The data returned by **dispatch\_source\_get\_data**() is an estimated number of bytes available to be read from the descriptor. This estimate should be treated as a suggested *minimum* read buffer size. There are no guarantees that a complete read of this size will be performed.

Users of this source type are strongly encouraged to perform non-blocking I/O and handle any truncated reads or error conditions that may occur. See [fcntl(2)](/fcntl/2.md) for additional information about setting the *O\_NONBLOCK* flag on a file descriptor.

*DISPATCH\_SOURCE\_TYPE\_SIGNAL*

Sources of this type monitor signals delivered to the current process. The *handle* is the signal number to monitor (int) and the *mask* is unused and should be zero.

The data returned by **dispatch\_source\_get\_data**() is the number of signals received since the last invocation of the event handler block.

Unlike signal handlers specified via **sigaction**(), the execution of the event handler block does not interrupt the current thread of execution; therefore the handler block is not limited to the use of signal safe interfaces defined in [sigaction(2)](/sigaction/2.md). Furthermore, multiple observers of a given signal are supported; thus allowing applications and libraries to cooperate safely. However, a dispatch source *does* *not* install a signal handler or otherwise alter the behavior of signal delivery. Therefore, applications must ignore or at least catch any signal that terminates a process by default. For example, near the top of **main**():

```
signal(SIGTERM, SIG_IGN);
```

*DISPATCH\_SOURCE\_TYPE\_TIMER*

Sources of this type periodically submit the event handler block to the target queue on an interval specified by **dispatch\_source\_set\_timer**(). The *handle* and *mask* arguments are unused and should be zero.

A best effort attempt is made to submit the event handler block to the target queue at the specified time; however, actual invocation may occur at a later time.

The data returned by **dispatch\_source\_get\_data**() is the number of times the timer has fired since the last invocation of the event handler block.

The function **dispatch\_source\_set\_timer**() takes as an argument the *start* time of the timer (initial fire time) represented as a *dispatch\_time\_t*. The timer dispatch source will use the same clock as the function used to create this value. (See [dispatch\_time(3)](/dispatch_time/3.md) for more information.) The *interval*, in nanoseconds, specifies the period at which the timer should repeat. All timers will repeat indefinitely until **dispatch\_source\_cancel**() is called. The  *leeway*, in nanoseconds, is a hint to the system that it may defer the timer in order to align with other system activity for improved system performance or reduced power consumption. (For example, an application might perform a periodic task every 5 minutes with a leeway of up to 30 seconds.) Note that some latency is to be expected for all timers even when a value of zero is used.

*Note*: Under the C language, untyped numbers default to the  *int* type. This can lead to truncation bugs when arithmetic operations with other numbers are expected to generate a *uint64\_t* sized result. When in doubt, use *ull* as a suffix. For example:

```
3ull * NSEC_PER_SEC
```

*DISPATCH\_SOURCE\_TYPE\_VNODE*

Sources of this type monitor the virtual filesystem nodes for state changes. The *handle* is a file descriptor (int) referencing the node to monitor, and  the *mask* may be one or more of the following:

- • DISPATCH\_VNODE\_DELETE

  The referenced node was removed from the filesystem namespace via [unlink(2)](/unlink/2.md).

- • DISPATCH\_VNODE\_WRITE

  A write to the referenced file occurred

- • DISPATCH\_VNODE\_EXTEND

  The referenced file was extended

- • DISPATCH\_VNODE\_ATTRIB

  The metadata attributes of the referenced node have changed

- • DISPATCH\_VNODE\_LINK

  The link count on the referenced node has changed

- • DISPATCH\_VNODE\_RENAME

  The referenced node was renamed

- • DISPATCH\_VNODE\_REVOKE

  Access to the referenced node was revoked via  [revoke(2)](/revoke/2.md) or the underlying fileystem was unmounted.

The data returned by **dispatch\_source\_get\_data**() indicates which of the events in the *mask* were observed.

*DISPATCH\_SOURCE\_TYPE\_WRITE*

Sources of this type monitor file descriptors for available write buffer space. The *handle* is the file descriptor (int) to monitor and the *mask* is unused and should be zero.

Users of this source type are strongly encouraged to perform non-blocking I/O and handle any truncated reads or error conditions that may occur. See [fcntl(2)](/fcntl/2.md) for additional information about setting the *O\_NONBLOCK* flag on a file descriptor.

## SEE ALSO

[dispatch(3)](/dispatch/3.md), [dispatch\_object(3)](/dispatch_object/3.md), [dispatch\_queue\_create(3)](/dispatch_queue_create/3.md)
