/*
 * Copyright (c) 2009-2013 Apple Inc. All rights reserved.
 *
 * @APPLE_APACHE_LICENSE_HEADER_START@
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @APPLE_APACHE_LICENSE_HEADER_END@
 */

#include "internal.h"

#if defined(__FreeBSD__)
#include <fcntl.h>
#define F_RDADVISE F_RDAHEAD
#endif

#ifndef DISPATCH_IO_DEBUG
#define DISPATCH_IO_DEBUG DISPATCH_DEBUG
#endif

#ifndef PAGE_SIZE
#define PAGE_SIZE ((size_t)getpagesize())
#endif

#if DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
#define _dispatch_io_data_retain(x) _dispatch_objc_retain(x)
#define _dispatch_io_data_release(x) _dispatch_objc_release(x)
#else
#define _dispatch_io_data_retain(x) dispatch_retain(x)
#define _dispatch_io_data_release(x) dispatch_release(x)
#endif

typedef void (^dispatch_fd_entry_init_callback_t)(dispatch_fd_entry_t fd_entry);

DISPATCH_EXPORT DISPATCH_NOTHROW
void _dispatch_iocntl(uint32_t param, uint64_t value);

static dispatch_operation_t _dispatch_operation_create(
		dispatch_op_direction_t direction, dispatch_io_t channel, off_t offset,
		size_t length, dispatch_data_t data, dispatch_queue_t queue,
		dispatch_io_handler_t handler);
static void _dispatch_operation_enqueue(dispatch_operation_t op,
		dispatch_op_direction_t direction, dispatch_data_t data);
static dispatch_source_t _dispatch_operation_timer(dispatch_queue_t tq,
		dispatch_operation_t op);
static inline void _dispatch_fd_entry_retain(dispatch_fd_entry_t fd_entry);
static inline void _dispatch_fd_entry_release(dispatch_fd_entry_t fd_entry);
static void _dispatch_fd_entry_init_async(dispatch_fd_t fd,
		dispatch_fd_entry_init_callback_t completion_callback);
static dispatch_fd_entry_t _dispatch_fd_entry_create_with_fd(dispatch_fd_t fd,
		uintptr_t hash);
static dispatch_fd_entry_t _dispatch_fd_entry_create_with_path(
		dispatch_io_path_data_t path_data, dev_t dev, mode_t mode);
static int _dispatch_fd_entry_open(dispatch_fd_entry_t fd_entry,
		dispatch_io_t channel);
static void _dispatch_fd_entry_cleanup_operations(dispatch_fd_entry_t fd_entry,
		dispatch_io_t channel);
static void _dispatch_stream_init(dispatch_fd_entry_t fd_entry,
		dispatch_queue_t tq);
static void _dispatch_stream_dispose(dispatch_fd_entry_t fd_entry,
		dispatch_op_direction_t direction);
static void _dispatch_disk_init(dispatch_fd_entry_t fd_entry, dev_t dev);
static void _dispatch_stream_enqueue_operation(dispatch_stream_t stream,
		dispatch_operation_t operation, dispatch_data_t data);
static void _dispatch_disk_enqueue_operation(dispatch_disk_t dsk,
		dispatch_operation_t operation, dispatch_data_t data);
static void _dispatch_stream_cleanup_operations(dispatch_stream_t stream,
		dispatch_io_t channel);
static void _dispatch_disk_cleanup_inactive_operations(dispatch_disk_t disk,
		dispatch_io_t channel);
static void _dispatch_stream_source_handler(void *ctx);
static void _dispatch_stream_queue_handler(void *ctx);
static void _dispatch_stream_handler(void *ctx);
static void _dispatch_disk_handler(void *ctx);
static void _dispatch_disk_perform(void *ctxt);
static void _dispatch_operation_advise(dispatch_operation_t op,
		size_t chunk_size);
static int _dispatch_operation_perform(dispatch_operation_t op);
static void _dispatch_operation_deliver_data(dispatch_operation_t op,
		dispatch_op_flags_t flags);

// Macros to wrap syscalls which return -1 on error, and retry on EINTR
#define _dispatch_io_syscall_switch_noerr(_err, _syscall, ...) do { \
		switch (((_err) = (((_syscall) == -1) ? errno : 0))) { \
		case EINTR: continue; \
		__VA_ARGS__ \
		} \
		break; \
	} while (1)
#define _dispatch_io_syscall_switch(__err, __syscall, ...) do { \
		_dispatch_io_syscall_switch_noerr(__err, __syscall, \
		case 0: break; \
		__VA_ARGS__ \
		); \
	} while (0)
#define _dispatch_io_syscall(__syscall) do { int __err; \
		_dispatch_io_syscall_switch(__err, __syscall); \
	} while (0)

enum {
	DISPATCH_OP_COMPLETE = 1,
	DISPATCH_OP_DELIVER,
	DISPATCH_OP_DELIVER_AND_COMPLETE,
	DISPATCH_OP_COMPLETE_RESUME,
	DISPATCH_OP_RESUME,
	DISPATCH_OP_ERR,
	DISPATCH_OP_FD_ERR,
};

#define _dispatch_io_Block_copy(x) \
		((__typeof__(x))_dispatch_Block_copy((dispatch_block_t)(x)))

#pragma mark -
#pragma mark dispatch_io_debug

#if DISPATCH_IO_DEBUG
#if !DISPATCH_DEBUG
#define _dispatch_io_log(x, ...) do { \
			_dispatch_log("%llu\t%p\t" x, _dispatch_absolute_time(), \
			(void *)_dispatch_thread_self(), ##__VA_ARGS__); \
		} while (0)
#ifdef _dispatch_object_debug
#undef _dispatch_object_debug
#define _dispatch_object_debug dispatch_debug
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
#else
#define _dispatch_io_log(x, ...) _dispatch_debug(x, ##__VA_ARGS__)
#endif // DISPATCH_DEBUG
#else
#define _dispatch_io_log(x, ...)
#endif // DISPATCH_IO_DEBUG

#define _dispatch_fd_debug(msg, fd, ...) \
		_dispatch_io_log("fd[0x%x]: " msg, fd, ##__VA_ARGS__)
#define _dispatch_op_debug(msg, op, ...) \
		_dispatch_io_log("op[%p]: " msg, op, ##__VA_ARGS__)
#define _dispatch_channel_debug(msg, channel, ...) \
		_dispatch_io_log("channel[%p]: " msg, channel, ##__VA_ARGS__)
#define _dispatch_fd_entry_debug(msg, fd_entry, ...) \
		_dispatch_io_log("fd_entry[%p]: " msg, fd_entry, ##__VA_ARGS__)
#define _dispatch_disk_debug(msg, disk, ...) \
		_dispatch_io_log("disk[%p]: " msg, disk, ##__VA_ARGS__)

#pragma mark -
#pragma mark dispatch_io_hashtables

// Global hashtable of dev_t -> disk_s mappings
DISPATCH_CACHELINE_ALIGN
static TAILQ_HEAD(, dispatch_disk_s) _dispatch_io_devs[DIO_HASH_SIZE];
// Global hashtable of fd -> fd_entry_s mappings
DISPATCH_CACHELINE_ALIGN
static TAILQ_HEAD(, dispatch_fd_entry_s) _dispatch_io_fds[DIO_HASH_SIZE];

static dispatch_once_t  _dispatch_io_devs_lockq_pred;
static dispatch_queue_t _dispatch_io_devs_lockq;
static dispatch_queue_t _dispatch_io_fds_lockq;

static char const * const _dispatch_io_key = "io";

static void
_dispatch_io_fds_lockq_init(void *context DISPATCH_UNUSED)
{
	_dispatch_io_fds_lockq = dispatch_queue_create(
			"com.apple.libdispatch-io.fd_lockq", NULL);
	unsigned int i;
	for (i = 0; i < DIO_HASH_SIZE; i++) {
		TAILQ_INIT(&_dispatch_io_fds[i]);
	}
}

static void
_dispatch_io_devs_lockq_init(void *context DISPATCH_UNUSED)
{
	_dispatch_io_devs_lockq = dispatch_queue_create(
			"com.apple.libdispatch-io.dev_lockq", NULL);
	unsigned int i;
	for (i = 0; i < DIO_HASH_SIZE; i++) {
		TAILQ_INIT(&_dispatch_io_devs[i]);
	}
}

#pragma mark -
#pragma mark dispatch_io_defaults

enum {
	DISPATCH_IOCNTL_CHUNK_PAGES = 1,
	DISPATCH_IOCNTL_LOW_WATER_CHUNKS,
	DISPATCH_IOCNTL_INITIAL_DELIVERY,
	DISPATCH_IOCNTL_MAX_PENDING_IO_REQS,
};

static struct dispatch_io_defaults_s {
	size_t chunk_size, low_water_chunks, max_pending_io_reqs;
	bool initial_delivery;
} dispatch_io_defaults = {
	.chunk_size = DIO_MAX_CHUNK_SIZE,
	.low_water_chunks = DIO_DEFAULT_LOW_WATER_CHUNKS,
	.max_pending_io_reqs = DIO_MAX_PENDING_IO_REQS,
};

#define _dispatch_iocntl_set_default(p, v) do { \
		dispatch_io_defaults.p = (__typeof__(dispatch_io_defaults.p))(v); \
	} while (0)

void
_dispatch_iocntl(uint32_t param, uint64_t value)
{
	switch (param) {
	case DISPATCH_IOCNTL_CHUNK_PAGES:
		_dispatch_iocntl_set_default(chunk_size, value * PAGE_SIZE);
		break;
	case DISPATCH_IOCNTL_LOW_WATER_CHUNKS:
		_dispatch_iocntl_set_default(low_water_chunks, value);
		break;
	case DISPATCH_IOCNTL_INITIAL_DELIVERY:
		_dispatch_iocntl_set_default(initial_delivery, value);
	case DISPATCH_IOCNTL_MAX_PENDING_IO_REQS:
		_dispatch_iocntl_set_default(max_pending_io_reqs, value);
		break;
	}
}

#pragma mark -
#pragma mark dispatch_io_t

static dispatch_io_t
_dispatch_io_create(dispatch_io_type_t type)
{
	dispatch_io_t channel = _dispatch_object_alloc(DISPATCH_VTABLE(io),
			sizeof(struct dispatch_io_s));
	channel->do_next = DISPATCH_OBJECT_LISTLESS;
	channel->do_targetq = _dispatch_get_root_queue(DISPATCH_QOS_DEFAULT, true);
	channel->params.type = type;
	channel->params.high = SIZE_MAX;
	channel->params.low = dispatch_io_defaults.low_water_chunks *
			dispatch_io_defaults.chunk_size;
	channel->queue = dispatch_queue_create("com.apple.libdispatch-io.channelq",
			NULL);
	return channel;
}

static void
_dispatch_io_init(dispatch_io_t channel, dispatch_fd_entry_t fd_entry,
		dispatch_queue_t queue, int err, void (^cleanup_handler)(int))
{
	// Enqueue the cleanup handler on the suspended close queue
	if (cleanup_handler) {
		_dispatch_retain(queue);
		dispatch_async(!err ? fd_entry->close_queue : channel->queue, ^{
			dispatch_async(queue, ^{
				_dispatch_channel_debug("cleanup handler invoke: err %d",
						channel, err);
				cleanup_handler(err);
			});
			_dispatch_release(queue);
		});
	}
	if (fd_entry) {
		channel->fd_entry = fd_entry;
		dispatch_retain(fd_entry->barrier_queue);
		dispatch_retain(fd_entry->barrier_group);
		channel->barrier_queue = fd_entry->barrier_queue;
		channel->barrier_group = fd_entry->barrier_group;
	} else {
		// Still need to create a barrier queue, since all operations go
		// through it
		channel->barrier_queue = dispatch_queue_create(
				"com.apple.libdispatch-io.barrierq", NULL);
		channel->barrier_group = dispatch_group_create();
	}
}

void
_dispatch_io_dispose(dispatch_io_t channel, DISPATCH_UNUSED bool *allow_free)
{
	_dispatch_object_debug(channel, "%s", __func__);
	if (channel->fd_entry &&
			!(channel->atomic_flags & (DIO_CLOSED|DIO_STOPPED))) {
		if (channel->fd_entry->path_data) {
			// This modification is safe since path_data->channel is checked
			// only on close_queue (which is still suspended at this point)
			channel->fd_entry->path_data->channel = NULL;
		}
		// Cleanup handlers will only run when all channels related to this
		// fd are complete
		_dispatch_fd_entry_release(channel->fd_entry);
	}
	if (channel->queue) {
		dispatch_release(channel->queue);
	}
	if (channel->barrier_queue) {
		dispatch_release(channel->barrier_queue);
	}
	if (channel->barrier_group) {
		dispatch_release(channel->barrier_group);
	}
}

static int
_dispatch_io_validate_type(dispatch_io_t channel, mode_t mode)
{
	int err = 0;
	if (S_ISDIR(mode)) {
		err = EISDIR;
	} else if (channel->params.type == DISPATCH_IO_RANDOM &&
			(S_ISFIFO(mode) || S_ISSOCK(mode))) {
		err = ESPIPE;
	}
	return err;
}

static int
_dispatch_io_get_error(dispatch_operation_t op, dispatch_io_t channel,
		bool ignore_closed)
{
	// On _any_ queue
	int err;
	if (op) {
		channel = op->channel;
	}
	if (channel->atomic_flags & (DIO_CLOSED|DIO_STOPPED)) {
		if (!ignore_closed || channel->atomic_flags & DIO_STOPPED) {
			err = ECANCELED;
		} else {
			err = 0;
		}
	} else {
		err = op ? op->fd_entry->err : channel->err;
	}
	return err;
}

#pragma mark -
#pragma mark dispatch_io_channels

dispatch_io_t
dispatch_io_create(dispatch_io_type_t type, dispatch_fd_t fd,
		dispatch_queue_t queue, void (^cleanup_handler)(int))
{
	if (type != DISPATCH_IO_STREAM && type != DISPATCH_IO_RANDOM) {
		return DISPATCH_BAD_INPUT;
	}
	dispatch_io_t channel = _dispatch_io_create(type);
	channel->fd = fd;
	_dispatch_channel_debug("create", channel);
	channel->fd_actual = fd;
	dispatch_suspend(channel->queue);
	_dispatch_retain(queue);
	_dispatch_retain(channel);
	_dispatch_fd_entry_init_async(fd, ^(dispatch_fd_entry_t fd_entry) {
		// On barrier queue
		int err = fd_entry->err;
		if (!err) {
			err = _dispatch_io_validate_type(channel, fd_entry->stat.mode);
		}
		if (!err && type == DISPATCH_IO_RANDOM) {
			off_t f_ptr;
			_dispatch_io_syscall_switch_noerr(err,
				f_ptr = lseek(fd_entry->fd, 0, SEEK_CUR),
				case 0: channel->f_ptr = f_ptr; break;
				default: (void)dispatch_assume_zero(err); break;
			);
		}
		channel->err = err;
		_dispatch_fd_entry_retain(fd_entry);
		_dispatch_io_init(channel, fd_entry, queue, err, cleanup_handler);
		dispatch_resume(channel->queue);
		_dispatch_object_debug(channel, "%s", __func__);
		_dispatch_release(channel);
		_dispatch_release(queue);
	});
	_dispatch_object_debug(channel, "%s", __func__);
	return channel;
}

dispatch_io_t
dispatch_io_create_f(dispatch_io_type_t type, dispatch_fd_t fd,
		dispatch_queue_t queue, void *context,
		void (*cleanup_handler)(void *context, int error))
{
	return dispatch_io_create(type, fd, queue, !cleanup_handler ? NULL :
			^(int error){ cleanup_handler(context, error); });
}

dispatch_io_t
dispatch_io_create_with_path(dispatch_io_type_t type, const char *path,
		int oflag, mode_t mode, dispatch_queue_t queue,
		void (^cleanup_handler)(int error))
{
	if ((type != DISPATCH_IO_STREAM && type != DISPATCH_IO_RANDOM) ||
			!(*path == '/')) {
		return DISPATCH_BAD_INPUT;
	}
	size_t pathlen = strlen(path);
	dispatch_io_path_data_t path_data = malloc(sizeof(*path_data) + pathlen+1);
	if (!path_data) {
		return DISPATCH_OUT_OF_MEMORY;
	}
	dispatch_io_t channel = _dispatch_io_create(type);
	channel->fd = -1;
	_dispatch_channel_debug("create with path %s", channel, path);
	channel->fd_actual = -1;
	path_data->channel = channel;
	path_data->oflag = oflag;
	path_data->mode = mode;
	path_data->pathlen = pathlen;
	memcpy(path_data->path, path, pathlen + 1);
	_dispatch_retain(queue);
	_dispatch_retain(channel);
	dispatch_async(channel->queue, ^{
		int err = 0;
		struct stat st;
		_dispatch_io_syscall_switch_noerr(err,
			(path_data->oflag & O_NOFOLLOW) == O_NOFOLLOW
#if __APPLE__
					|| (path_data->oflag & O_SYMLINK) == O_SYMLINK
#endif
					? lstat(path_data->path, &st) : stat(path_data->path, &st),
			case 0:
				err = _dispatch_io_validate_type(channel, st.st_mode);
				break;
			default:
				if ((path_data->oflag & O_CREAT) &&
						(*(path_data->path + path_data->pathlen - 1) != '/')) {
					// Check parent directory
					char *c = strrchr(path_data->path, '/');
					dispatch_assert(c);
					*c = 0;
					int perr;
					_dispatch_io_syscall_switch_noerr(perr,
						stat(path_data->path, &st),
						case 0:
							// Since the parent directory exists, open() will
							// create a regular file after the fd_entry has
							// been filled in
							st.st_mode = S_IFREG;
							err = 0;
							break;
					);
					*c = '/';
				}
				break;
		);
		channel->err = err;
		if (err) {
			free(path_data);
			_dispatch_io_init(channel, NULL, queue, err, cleanup_handler);
			_dispatch_release(channel);
			_dispatch_release(queue);
			return;
		}
		dispatch_suspend(channel->queue);
		dispatch_once_f(&_dispatch_io_devs_lockq_pred, NULL,
				_dispatch_io_devs_lockq_init);
		dispatch_async(_dispatch_io_devs_lockq, ^{
			dispatch_fd_entry_t fd_entry = _dispatch_fd_entry_create_with_path(
					path_data, st.st_dev, st.st_mode);
			_dispatch_io_init(channel, fd_entry, queue, 0, cleanup_handler);
			dispatch_resume(channel->queue);
			_dispatch_object_debug(channel, "%s", __func__);
			_dispatch_release(channel);
			_dispatch_release(queue);
		});
	});
	_dispatch_object_debug(channel, "%s", __func__);
	return channel;
}

dispatch_io_t
dispatch_io_create_with_path_f(dispatch_io_type_t type, const char *path,
		int oflag, mode_t mode, dispatch_queue_t queue, void *context,
		void (*cleanup_handler)(void *context, int error))
{
	return dispatch_io_create_with_path(type, path, oflag, mode, queue,
			!cleanup_handler ? NULL :
			^(int error){ cleanup_handler(context, error); });
}

dispatch_io_t
dispatch_io_create_with_io(dispatch_io_type_t type, dispatch_io_t in_channel,
		dispatch_queue_t queue, void (^cleanup_handler)(int error))
{
	if (type != DISPATCH_IO_STREAM && type != DISPATCH_IO_RANDOM) {
		return DISPATCH_BAD_INPUT;
	}
	dispatch_io_t channel = _dispatch_io_create(type);
	_dispatch_channel_debug("create with channel %p", channel, in_channel);
	dispatch_suspend(channel->queue);
	_dispatch_retain(queue);
	_dispatch_retain(channel);
	_dispatch_retain(in_channel);
	dispatch_async(in_channel->queue, ^{
		int err0 = _dispatch_io_get_error(NULL, in_channel, false);
		if (err0) {
			channel->err = err0;
			_dispatch_io_init(channel, NULL, queue, err0, cleanup_handler);
			dispatch_resume(channel->queue);
			_dispatch_release(channel);
			_dispatch_release(in_channel);
			_dispatch_release(queue);
			return;
		}
		dispatch_async(in_channel->barrier_queue, ^{
			int err = _dispatch_io_get_error(NULL, in_channel, false);
			// If there is no error, the fd_entry for the in_channel is valid.
			// Since we are running on in_channel's queue, the fd_entry has been
			// fully resolved and will stay valid for the duration of this block
			if (!err) {
				err = in_channel->err;
				if (!err) {
					err = in_channel->fd_entry->err;
				}
			}
			if (!err) {
				err = _dispatch_io_validate_type(channel,
						in_channel->fd_entry->stat.mode);
			}
			if (!err && type == DISPATCH_IO_RANDOM && in_channel->fd != -1) {
				off_t f_ptr;
				_dispatch_io_syscall_switch_noerr(err,
					f_ptr = lseek(in_channel->fd_entry->fd, 0, SEEK_CUR),
					case 0: channel->f_ptr = f_ptr; break;
					default: (void)dispatch_assume_zero(err); break;
				);
			}
			channel->err = err;
			if (err) {
				_dispatch_io_init(channel, NULL, queue, err, cleanup_handler);
				dispatch_resume(channel->queue);
				_dispatch_release(channel);
				_dispatch_release(in_channel);
				_dispatch_release(queue);
				return;
			}
			if (in_channel->fd == -1) {
				// in_channel was created from path
				channel->fd = -1;
				channel->fd_actual = -1;
				mode_t mode = in_channel->fd_entry->stat.mode;
				dev_t dev = in_channel->fd_entry->stat.dev;
				size_t path_data_len = sizeof(struct dispatch_io_path_data_s) +
						in_channel->fd_entry->path_data->pathlen + 1;
				dispatch_io_path_data_t path_data = malloc(path_data_len);
				memcpy(path_data, in_channel->fd_entry->path_data,
						path_data_len);
				path_data->channel = channel;
				// lockq_io_devs is known to already exist
				dispatch_async(_dispatch_io_devs_lockq, ^{
					dispatch_fd_entry_t fd_entry;
					fd_entry = _dispatch_fd_entry_create_with_path(path_data,
							dev, mode);
					_dispatch_io_init(channel, fd_entry, queue, 0,
							cleanup_handler);
					dispatch_resume(channel->queue);
					_dispatch_release(channel);
					_dispatch_release(queue);
				});
			} else {
				dispatch_fd_entry_t fd_entry = in_channel->fd_entry;
				channel->fd = in_channel->fd;
				channel->fd_actual = in_channel->fd_actual;
				_dispatch_fd_entry_retain(fd_entry);
				_dispatch_io_init(channel, fd_entry, queue, 0, cleanup_handler);
				dispatch_resume(channel->queue);
				_dispatch_release(channel);
				_dispatch_release(queue);
			}
			_dispatch_release(in_channel);
			_dispatch_object_debug(channel, "%s", __func__);
		});
	});
	_dispatch_object_debug(channel, "%s", __func__);
	return channel;
}

dispatch_io_t
dispatch_io_create_with_io_f(dispatch_io_type_t type, dispatch_io_t in_channel,
		dispatch_queue_t queue, void *context,
		void (*cleanup_handler)(void *context, int error))
{
	return dispatch_io_create_with_io(type, in_channel, queue,
			!cleanup_handler ? NULL :
			^(int error){ cleanup_handler(context, error); });
}

#pragma mark -
#pragma mark dispatch_io_accessors

void
dispatch_io_set_high_water(dispatch_io_t channel, size_t high_water)
{
	_dispatch_retain(channel);
	dispatch_async(channel->queue, ^{
		_dispatch_channel_debug("set high water: %zu", channel, high_water);
		if (channel->params.low > high_water) {
			channel->params.low = high_water;
		}
		channel->params.high = high_water ? high_water : 1;
		_dispatch_release(channel);
	});
}

void
dispatch_io_set_low_water(dispatch_io_t channel, size_t low_water)
{
	_dispatch_retain(channel);
	dispatch_async(channel->queue, ^{
		_dispatch_channel_debug("set low water: %zu", channel, low_water);
		if (channel->params.high < low_water) {
			channel->params.high = low_water ? low_water : 1;
		}
		channel->params.low = low_water;
		_dispatch_release(channel);
	});
}

void
dispatch_io_set_interval(dispatch_io_t channel, uint64_t interval,
		unsigned long flags)
{
	_dispatch_retain(channel);
	dispatch_async(channel->queue, ^{
		_dispatch_channel_debug("set interval: %llu", channel,
		  (unsigned long long)interval);
		channel->params.interval = interval < INT64_MAX ? interval : INT64_MAX;
		channel->params.interval_flags = flags;
		_dispatch_release(channel);
	});
}

void
_dispatch_io_set_target_queue(dispatch_io_t channel, dispatch_queue_t dq)
{
	_dispatch_retain(dq);
	_dispatch_retain(channel);
	dispatch_async(channel->queue, ^{
		dispatch_queue_t prev_dq = channel->do_targetq;
		channel->do_targetq = dq;
		_dispatch_release(prev_dq);
		_dispatch_object_debug(channel, "%s", __func__);
		_dispatch_release(channel);
	});
}

dispatch_fd_t
dispatch_io_get_descriptor(dispatch_io_t channel)
{
	if (channel->atomic_flags & (DIO_CLOSED|DIO_STOPPED)) {
		return -1;
	}
	dispatch_fd_t fd = channel->fd_actual;
	if (fd == -1 && !_dispatch_io_get_error(NULL, channel, false)) {
		dispatch_thread_context_t ctxt =
				_dispatch_thread_context_find(_dispatch_io_key);
		if (ctxt && ctxt->dtc_io_in_barrier == channel) {
			(void)_dispatch_fd_entry_open(channel->fd_entry, channel);
		}
	}
	return channel->fd_actual;
}

#pragma mark -
#pragma mark dispatch_io_operations

static void
_dispatch_io_stop(dispatch_io_t channel)
{
	_dispatch_channel_debug("stop", channel);
	(void)os_atomic_or2o(channel, atomic_flags, DIO_STOPPED, relaxed);
	_dispatch_retain(channel);
	dispatch_async(channel->queue, ^{
		dispatch_async(channel->barrier_queue, ^{
			_dispatch_object_debug(channel, "%s", __func__);
			dispatch_fd_entry_t fd_entry = channel->fd_entry;
			if (fd_entry) {
				_dispatch_channel_debug("stop cleanup", channel);
				_dispatch_fd_entry_cleanup_operations(fd_entry, channel);
				if (!(channel->atomic_flags & DIO_CLOSED)) {
					if (fd_entry->path_data) {
						fd_entry->path_data->channel = NULL;
					}
					channel->fd_entry = NULL;
					_dispatch_fd_entry_release(fd_entry);
				}
			} else if (channel->fd != -1) {
				// Stop after close, need to check if fd_entry still exists
				_dispatch_retain(channel);
				dispatch_async(_dispatch_io_fds_lockq, ^{
					_dispatch_object_debug(channel, "%s", __func__);
					_dispatch_channel_debug("stop cleanup after close",
							channel);
					dispatch_fd_entry_t fdi;
					uintptr_t hash = DIO_HASH(channel->fd);
					TAILQ_FOREACH(fdi, &_dispatch_io_fds[hash], fd_list) {
						if (fdi->fd == channel->fd) {
							_dispatch_fd_entry_cleanup_operations(fdi, channel);
							break;
						}
					}
					_dispatch_release(channel);
				});
			}
			_dispatch_release(channel);
		});
	});
}

void
dispatch_io_close(dispatch_io_t channel, unsigned long flags)
{
	if (flags & DISPATCH_IO_STOP) {
		// Don't stop an already stopped channel
		if (channel->atomic_flags & DIO_STOPPED) {
			return;
		}
		return _dispatch_io_stop(channel);
	}
	// Don't close an already closed or stopped channel
	if (channel->atomic_flags & (DIO_CLOSED|DIO_STOPPED)) {
		return;
	}
	_dispatch_retain(channel);
	dispatch_async(channel->queue, ^{
		dispatch_async(channel->barrier_queue, ^{
			_dispatch_object_debug(channel, "%s", __func__);
			_dispatch_channel_debug("close", channel);
			if (!(channel->atomic_flags & (DIO_CLOSED|DIO_STOPPED))) {
				(void)os_atomic_or2o(channel, atomic_flags, DIO_CLOSED,
						relaxed);
				dispatch_fd_entry_t fd_entry = channel->fd_entry;
				if (fd_entry) {
					if (fd_entry->path_data) {
						fd_entry->path_data->channel = NULL;
					}
					channel->fd_entry = NULL;
					_dispatch_fd_entry_release(fd_entry);
				}
			}
			_dispatch_release(channel);
		});
	});
}

void
dispatch_io_barrier(dispatch_io_t channel, dispatch_block_t barrier)
{
	_dispatch_retain(channel);
	dispatch_async(channel->queue, ^{
		dispatch_queue_t io_q = channel->do_targetq;
		dispatch_queue_t barrier_queue = channel->barrier_queue;
		dispatch_group_t barrier_group = channel->barrier_group;
		dispatch_async(barrier_queue, ^{
			dispatch_suspend(barrier_queue);
			dispatch_group_notify(barrier_group, io_q, ^{
				dispatch_thread_context_s io_ctxt = {
					.dtc_key = _dispatch_io_key,
					.dtc_io_in_barrier = channel,
				};

				_dispatch_object_debug(channel, "%s", __func__);
				_dispatch_thread_context_push(&io_ctxt);
				barrier();
				_dispatch_thread_context_pop(&io_ctxt);
				dispatch_resume(barrier_queue);
				_dispatch_release(channel);
			});
		});
	});
}

void
dispatch_io_barrier_f(dispatch_io_t channel, void *context,
		dispatch_function_t barrier)
{
	return dispatch_io_barrier(channel, ^{ barrier(context); });
}

void
dispatch_io_read(dispatch_io_t channel, off_t offset, size_t length,
		dispatch_queue_t queue, dispatch_io_handler_t handler)
{
	_dispatch_retain(channel);
	_dispatch_retain(queue);
	dispatch_async(channel->queue, ^{
		dispatch_operation_t op;
		op = _dispatch_operation_create(DOP_DIR_READ, channel, offset,
				length, dispatch_data_empty, queue, handler);
		if (op) {
			dispatch_queue_t barrier_q = channel->barrier_queue;
			dispatch_async(barrier_q, ^{
				_dispatch_operation_enqueue(op, DOP_DIR_READ,
						dispatch_data_empty);
			});
		}
		_dispatch_release(channel);
		_dispatch_release(queue);
	});
}

void
dispatch_io_read_f(dispatch_io_t channel, off_t offset, size_t length,
		dispatch_queue_t queue, void *context,
		dispatch_io_handler_function_t handler)
{
	return dispatch_io_read(channel, offset, length, queue,
			^(bool done, dispatch_data_t d, int error){
		handler(context, done, d, error);
	});
}

void
dispatch_io_write(dispatch_io_t channel, off_t offset, dispatch_data_t data,
		dispatch_queue_t queue, dispatch_io_handler_t handler)
{
	_dispatch_io_data_retain(data);
	_dispatch_retain(channel);
	_dispatch_retain(queue);
	dispatch_async(channel->queue, ^{
		dispatch_operation_t op;
		op = _dispatch_operation_create(DOP_DIR_WRITE, channel, offset,
				dispatch_data_get_size(data), data, queue, handler);
		if (op) {
			dispatch_queue_t barrier_q = channel->barrier_queue;
			dispatch_async(barrier_q, ^{
				_dispatch_operation_enqueue(op, DOP_DIR_WRITE, data);
				_dispatch_io_data_release(data);
			});
		} else {
			_dispatch_io_data_release(data);
		}
		_dispatch_release(channel);
		_dispatch_release(queue);
	});
}

void
dispatch_io_write_f(dispatch_io_t channel, off_t offset, dispatch_data_t data,
		dispatch_queue_t queue, void *context,
		dispatch_io_handler_function_t handler)
{
	return dispatch_io_write(channel, offset, data, queue,
			^(bool done, dispatch_data_t d, int error){
		handler(context, done, d, error);
	});
}

void
dispatch_read(dispatch_fd_t fd, size_t length, dispatch_queue_t queue,
		void (^handler)(dispatch_data_t, int))
{
	_dispatch_retain(queue);
	_dispatch_fd_entry_init_async(fd, ^(dispatch_fd_entry_t fd_entry) {
		// On barrier queue
		if (fd_entry->err) {
			int err = fd_entry->err;
			dispatch_async(queue, ^{
				_dispatch_fd_debug("convenience handler invoke", fd);
				handler(dispatch_data_empty, err);
			});
			_dispatch_release(queue);
			return;
		}
		// Safe to access fd_entry on barrier queue
		dispatch_io_t channel = fd_entry->convenience_channel;
		if (!channel) {
			channel = _dispatch_io_create(DISPATCH_IO_STREAM);
			channel->fd = fd;
			channel->fd_actual = fd;
			channel->fd_entry = fd_entry;
			dispatch_retain(fd_entry->barrier_queue);
			dispatch_retain(fd_entry->barrier_group);
			channel->barrier_queue = fd_entry->barrier_queue;
			channel->barrier_group = fd_entry->barrier_group;
			fd_entry->convenience_channel = channel;
		}
		__block dispatch_data_t deliver_data = dispatch_data_empty;
		__block int err = 0;
		dispatch_async(fd_entry->close_queue, ^{
			dispatch_async(queue, ^{
				_dispatch_fd_debug("convenience handler invoke", fd);
				handler(deliver_data, err);
				_dispatch_io_data_release(deliver_data);
			});
			_dispatch_release(queue);
		});
		dispatch_operation_t op =
			_dispatch_operation_create(DOP_DIR_READ, channel, 0,
					length, dispatch_data_empty,
					_dispatch_get_root_queue(DISPATCH_QOS_DEFAULT, false),
					^(bool done, dispatch_data_t data, int error) {
				if (data) {
					data = dispatch_data_create_concat(deliver_data, data);
					_dispatch_io_data_release(deliver_data);
					deliver_data = data;
				}
				if (done) {
					err = error;
				}
			});
		if (op) {
			_dispatch_operation_enqueue(op, DOP_DIR_READ, dispatch_data_empty);
		}
	});
}

void
dispatch_read_f(dispatch_fd_t fd, size_t length, dispatch_queue_t queue,
		void *context, void (*handler)(void *, dispatch_data_t, int))
{
	return dispatch_read(fd, length, queue, ^(dispatch_data_t d, int error){
		handler(context, d, error);
	});
}

void
dispatch_write(dispatch_fd_t fd, dispatch_data_t data, dispatch_queue_t queue,
		void (^handler)(dispatch_data_t, int))
{
	_dispatch_io_data_retain(data);
	_dispatch_retain(queue);
	_dispatch_fd_entry_init_async(fd, ^(dispatch_fd_entry_t fd_entry) {
		// On barrier queue
		if (fd_entry->err) {
			int err = fd_entry->err;
			dispatch_async(queue, ^{
				_dispatch_fd_debug("convenience handler invoke", fd);
				handler(NULL, err);
			});
			_dispatch_release(queue);
			return;
		}
		// Safe to access fd_entry on barrier queue
		dispatch_io_t channel = fd_entry->convenience_channel;
		if (!channel) {
			channel = _dispatch_io_create(DISPATCH_IO_STREAM);
			channel->fd = fd;
			channel->fd_actual = fd;
			channel->fd_entry = fd_entry;
			dispatch_retain(fd_entry->barrier_queue);
			dispatch_retain(fd_entry->barrier_group);
			channel->barrier_queue = fd_entry->barrier_queue;
			channel->barrier_group = fd_entry->barrier_group;
			fd_entry->convenience_channel = channel;
		}
		__block dispatch_data_t deliver_data = NULL;
		__block int err = 0;
		dispatch_async(fd_entry->close_queue, ^{
			dispatch_async(queue, ^{
				_dispatch_fd_debug("convenience handler invoke", fd);
				handler(deliver_data, err);
				if (deliver_data) {
					_dispatch_io_data_release(deliver_data);
				}
			});
			_dispatch_release(queue);
		});
		dispatch_operation_t op =
			_dispatch_operation_create(DOP_DIR_WRITE, channel, 0,
					dispatch_data_get_size(data), data,
					_dispatch_get_root_queue(DISPATCH_QOS_DEFAULT, false),
					^(bool done, dispatch_data_t d, int error) {
				if (done) {
					if (d) {
						_dispatch_io_data_retain(d);
						deliver_data = d;
					}
					err = error;
				}
			});
		if (op) {
			_dispatch_operation_enqueue(op, DOP_DIR_WRITE, data);
		}
		_dispatch_io_data_release(data);
	});
}

void
dispatch_write_f(dispatch_fd_t fd, dispatch_data_t data, dispatch_queue_t queue,
		void *context, void (*handler)(void *, dispatch_data_t, int))
{
	return dispatch_write(fd, data, queue, ^(dispatch_data_t d, int error){
		handler(context, d, error);
	});
}

#pragma mark -
#pragma mark dispatch_operation_t

static dispatch_operation_t
_dispatch_operation_create(dispatch_op_direction_t direction,
		dispatch_io_t channel, off_t offset, size_t length,
		dispatch_data_t data, dispatch_queue_t queue,
		dispatch_io_handler_t handler)
{
	// On channel queue
	dispatch_assert(direction < DOP_DIR_MAX);
	// Safe to call _dispatch_io_get_error() with channel->fd_entry since
	// that can only be NULL if atomic_flags are set rdar://problem/8362514
	int err = _dispatch_io_get_error(NULL, channel, false);
	if (err || !length) {
		_dispatch_io_data_retain(data);
		_dispatch_retain(queue);
		dispatch_async(channel->barrier_queue, ^{
			dispatch_async(queue, ^{
				dispatch_data_t d = data;
				if (direction == DOP_DIR_READ && err) {
					d = NULL;
				} else if (direction == DOP_DIR_WRITE && !err) {
					d = NULL;
				}
				_dispatch_channel_debug("IO handler invoke: err %d", channel,
						err);
				handler(true, d, err);
				_dispatch_io_data_release(data);
			});
			_dispatch_release(queue);
		});
		return NULL;
	}
	dispatch_operation_t op = _dispatch_object_alloc(DISPATCH_VTABLE(operation),
			sizeof(struct dispatch_operation_s));
	_dispatch_channel_debug("operation create: %p", channel, op);
	op->do_next = DISPATCH_OBJECT_LISTLESS;
	op->do_xref_cnt = -1; // operation object is not exposed externally
	op->op_q = dispatch_queue_create_with_target("com.apple.libdispatch-io.opq",
			NULL, queue);
	op->active = false;
	op->direction = direction;
	op->offset = offset + channel->f_ptr;
	op->length = length;
	op->handler = _dispatch_io_Block_copy(handler);
	_dispatch_retain(channel);
	op->channel = channel;
	op->params = channel->params;
	// Take a snapshot of the priority of the channel queue. The actual I/O
	// for this operation will be performed at this priority
	dispatch_queue_t targetq = op->channel->do_targetq;
	while (fastpath(targetq->do_targetq)) {
		targetq = targetq->do_targetq;
	}
	op->do_targetq = targetq;
	_dispatch_object_debug(op, "%s", __func__);
	return op;
}

void
_dispatch_operation_dispose(dispatch_operation_t op,
		DISPATCH_UNUSED bool *allow_free)
{
	_dispatch_object_debug(op, "%s", __func__);
	_dispatch_op_debug("dispose", op);
	// Deliver the data if there's any
	if (op->fd_entry) {
		_dispatch_operation_deliver_data(op, DOP_DONE);
		dispatch_group_leave(op->fd_entry->barrier_group);
		_dispatch_fd_entry_release(op->fd_entry);
	}
	if (op->channel) {
		_dispatch_release(op->channel);
	}
	if (op->timer) {
		dispatch_release(op->timer);
	}
	// For write operations, op->buf is owned by op->buf_data
	if (op->buf && op->direction == DOP_DIR_READ) {
		free(op->buf);
	}
	if (op->buf_data) {
		_dispatch_io_data_release(op->buf_data);
	}
	if (op->data) {
		_dispatch_io_data_release(op->data);
	}
	if (op->op_q) {
		dispatch_release(op->op_q);
	}
	Block_release(op->handler);
	_dispatch_op_debug("disposed", op);
}

static void
_dispatch_operation_enqueue(dispatch_operation_t op,
		dispatch_op_direction_t direction, dispatch_data_t data)
{
	// Called from the barrier queue
	_dispatch_io_data_retain(data);
	// If channel is closed or stopped, then call the handler immediately
	int err = _dispatch_io_get_error(NULL, op->channel, false);
	if (err) {
		dispatch_io_handler_t handler = op->handler;
		dispatch_async(op->op_q, ^{
			dispatch_data_t d = data;
			if (direction == DOP_DIR_READ && err) {
				d = NULL;
			} else if (direction == DOP_DIR_WRITE && !err) {
				d = NULL;
			}
			handler(true, d, err);
			_dispatch_io_data_release(data);
		});
		_dispatch_op_debug("release -> %d, err %d", op, op->do_ref_cnt, err);
		_dispatch_release(op);
		return;
	}
	// Finish operation init
	op->fd_entry = op->channel->fd_entry;
	_dispatch_fd_entry_retain(op->fd_entry);
	dispatch_group_enter(op->fd_entry->barrier_group);
	dispatch_disk_t disk = op->fd_entry->disk;
	if (!disk) {
		dispatch_stream_t stream = op->fd_entry->streams[direction];
		dispatch_async(stream->dq, ^{
			_dispatch_stream_enqueue_operation(stream, op, data);
			_dispatch_io_data_release(data);
		});
	} else {
		dispatch_async(disk->pick_queue, ^{
			_dispatch_disk_enqueue_operation(disk, op, data);
			_dispatch_io_data_release(data);
		});
	}
}

static bool
_dispatch_operation_should_enqueue(dispatch_operation_t op,
		dispatch_queue_t tq, dispatch_data_t data)
{
	// On stream queue or disk queue
	_dispatch_op_debug("enqueue", op);
	_dispatch_io_data_retain(data);
	op->data = data;
	int err = _dispatch_io_get_error(op, NULL, true);
	if (err) {
		op->err = err;
		// Final release
		_dispatch_op_debug("release -> %d, err %d", op, op->do_ref_cnt, err);
		_dispatch_release(op);
		return false;
	}
	if (op->params.interval) {
		dispatch_resume(_dispatch_operation_timer(tq, op));
	}
	return true;
}

static dispatch_source_t
_dispatch_operation_timer(dispatch_queue_t tq, dispatch_operation_t op)
{
	// On stream queue or pick queue
	if (op->timer) {
		return op->timer;
	}
	dispatch_source_t timer = dispatch_source_create(
			DISPATCH_SOURCE_TYPE_TIMER, 0, 0, tq);
	dispatch_source_set_timer(timer,
			dispatch_time(DISPATCH_TIME_NOW, (int64_t)op->params.interval),
			op->params.interval, 0);
	dispatch_source_set_event_handler(timer, ^{
		// On stream queue or pick queue
		if (dispatch_source_testcancel(timer)) {
			// Do nothing. The operation has already completed
			return;
		}
		dispatch_op_flags_t flags = DOP_DEFAULT;
		if (op->params.interval_flags & DISPATCH_IO_STRICT_INTERVAL) {
			// Deliver even if there is less data than the low-water mark
			flags |= DOP_DELIVER;
		}
		// If the operation is active, dont deliver data
		if ((op->active) && (flags & DOP_DELIVER)) {
			op->flags = flags;
		} else {
			_dispatch_operation_deliver_data(op, flags);
		}
	});
	op->timer = timer;
	return op->timer;
}

#pragma mark -
#pragma mark dispatch_fd_entry_t

#if DISPATCH_USE_GUARDED_FD_CHANGE_FDGUARD
static void
_dispatch_fd_entry_guard(dispatch_fd_entry_t fd_entry)
{
	guardid_t guard = fd_entry;
	const unsigned int guard_flags = GUARD_CLOSE;
	int err, fd_flags = 0;
	_dispatch_io_syscall_switch_noerr(err,
		change_fdguard_np(fd_entry->fd, NULL, 0, &guard, guard_flags,
				&fd_flags),
		case 0:
			fd_entry->guard_flags = guard_flags;
			fd_entry->orig_fd_flags = fd_flags;
			break;
		case EPERM: break;
		default: (void)dispatch_assume_zero(err); break;
	);
}

static void
_dispatch_fd_entry_unguard(dispatch_fd_entry_t fd_entry)
{
	if (!fd_entry->guard_flags) {
		return;
	}
	guardid_t guard = fd_entry;
	int err, fd_flags = fd_entry->orig_fd_flags;
	_dispatch_io_syscall_switch(err,
		change_fdguard_np(fd_entry->fd, &guard, fd_entry->guard_flags, NULL, 0,
				&fd_flags),
		default: (void)dispatch_assume_zero(err); break;
	);
}
#else
static inline void
_dispatch_fd_entry_guard(dispatch_fd_entry_t fd_entry) { (void)fd_entry; }
static inline void
_dispatch_fd_entry_unguard(dispatch_fd_entry_t fd_entry) { (void)fd_entry; }
#endif // DISPATCH_USE_GUARDED_FD

static inline int
_dispatch_fd_entry_guarded_open(dispatch_fd_entry_t fd_entry, const char *path,
		int oflag, mode_t mode) {
#if DISPATCH_USE_GUARDED_FD
	guardid_t guard = (uintptr_t)fd_entry;
	const unsigned int guard_flags = GUARD_CLOSE | GUARD_DUP |
			GUARD_SOCKET_IPC | GUARD_FILEPORT;
	int fd = guarded_open_np(path, &guard, guard_flags, oflag | O_CLOEXEC,
			mode);
	if (fd != -1) {
		fd_entry->guard_flags = guard_flags;
		return fd;
	}
	errno = 0;
#else
	(void)fd_entry;
#endif
	return open(path, oflag, mode);
}

static inline int
_dispatch_fd_entry_guarded_close(dispatch_fd_entry_t fd_entry, int fd) {
#if DISPATCH_USE_GUARDED_FD
	if (fd_entry->guard_flags) {
		guardid_t guard = (uintptr_t)fd_entry;
		return guarded_close_np(fd, &guard);
	} else
#else
	(void)fd_entry;
#endif
	{
		return close(fd);
	}
}

static inline void
_dispatch_fd_entry_retain(dispatch_fd_entry_t fd_entry) {
	dispatch_suspend(fd_entry->close_queue);
}

static inline void
_dispatch_fd_entry_release(dispatch_fd_entry_t fd_entry) {
	dispatch_resume(fd_entry->close_queue);
}

static void
_dispatch_fd_entry_init_async(dispatch_fd_t fd,
		dispatch_fd_entry_init_callback_t completion_callback)
{
	static dispatch_once_t _dispatch_io_fds_lockq_pred;
	dispatch_once_f(&_dispatch_io_fds_lockq_pred, NULL,
			_dispatch_io_fds_lockq_init);
	dispatch_async(_dispatch_io_fds_lockq, ^{
		dispatch_fd_entry_t fd_entry = NULL;
		// Check to see if there is an existing entry for the given fd
		uintptr_t hash = DIO_HASH(fd);
		TAILQ_FOREACH(fd_entry, &_dispatch_io_fds[hash], fd_list) {
			if (fd_entry->fd == fd) {
				// Retain the fd_entry to ensure it cannot go away until the
				// stat() has completed
				_dispatch_fd_entry_retain(fd_entry);
				break;
			}
		}
		if (!fd_entry) {
			// If we did not find an existing entry, create one
			fd_entry = _dispatch_fd_entry_create_with_fd(fd, hash);
		}
		_dispatch_fd_entry_debug("init", fd_entry);
		dispatch_async(fd_entry->barrier_queue, ^{
			_dispatch_fd_entry_debug("init completion", fd_entry);
			completion_callback(fd_entry);
			// stat() is complete, release reference to fd_entry
			_dispatch_fd_entry_release(fd_entry);
		});
	});
}

static dispatch_fd_entry_t
_dispatch_fd_entry_create(dispatch_queue_t q)
{
	dispatch_fd_entry_t fd_entry;
	fd_entry = _dispatch_calloc(1ul, sizeof(struct dispatch_fd_entry_s));
	// Use target queue to ensure that no concurrent lookups are going on when
	// the close queue is running
	fd_entry->close_queue = dispatch_queue_create_with_target(
			"com.apple.libdispatch-io.closeq", NULL, q);
	// Suspend the cleanup queue until closing
	_dispatch_fd_entry_retain(fd_entry);
	return fd_entry;
}

static dispatch_fd_entry_t
_dispatch_fd_entry_create_with_fd(dispatch_fd_t fd, uintptr_t hash)
{
	// On fds lock queue
	dispatch_fd_entry_t fd_entry = _dispatch_fd_entry_create(
			_dispatch_io_fds_lockq);
	_dispatch_fd_entry_debug("create: fd %d", fd_entry, fd);
	fd_entry->fd = fd;
	TAILQ_INSERT_TAIL(&_dispatch_io_fds[hash], fd_entry, fd_list);
	fd_entry->barrier_queue = dispatch_queue_create(
			"com.apple.libdispatch-io.barrierq", NULL);
	fd_entry->barrier_group = dispatch_group_create();
	dispatch_async(fd_entry->barrier_queue, ^{
		_dispatch_fd_entry_debug("stat", fd_entry);
		int err, orig_flags, orig_nosigpipe = -1;
		struct stat st;
		_dispatch_io_syscall_switch(err,
			fstat(fd, &st),
			default: fd_entry->err = err; return;
		);
		fd_entry->stat.dev = st.st_dev;
		fd_entry->stat.mode = st.st_mode;
		_dispatch_fd_entry_guard(fd_entry);
		_dispatch_io_syscall_switch(err,
			orig_flags = fcntl(fd, F_GETFL),
			default: (void)dispatch_assume_zero(err); break;
		);
#if DISPATCH_USE_SETNOSIGPIPE // rdar://problem/4121123
		if (S_ISFIFO(st.st_mode)) {
			_dispatch_io_syscall_switch(err,
				orig_nosigpipe = fcntl(fd, F_GETNOSIGPIPE),
				default: (void)dispatch_assume_zero(err); break;
			);
			if (orig_nosigpipe != -1) {
				_dispatch_io_syscall_switch(err,
					orig_nosigpipe = fcntl(fd, F_SETNOSIGPIPE, 1),
					default:
						orig_nosigpipe = -1;
						(void)dispatch_assume_zero(err);
						break;
				);
			}
		}
#endif
		if (S_ISREG(st.st_mode)) {
			if (orig_flags != -1) {
				_dispatch_io_syscall_switch(err,
					fcntl(fd, F_SETFL, orig_flags & ~O_NONBLOCK),
					default:
						orig_flags = -1;
						(void)dispatch_assume_zero(err);
						break;
				);
			}
			dev_t dev = (dev_t)major(st.st_dev);
			// We have to get the disk on the global dev queue. The
			// barrier queue cannot continue until that is complete
			dispatch_suspend(fd_entry->barrier_queue);
			dispatch_once_f(&_dispatch_io_devs_lockq_pred, NULL,
					_dispatch_io_devs_lockq_init);
			dispatch_async(_dispatch_io_devs_lockq, ^{
				_dispatch_disk_init(fd_entry, dev);
				dispatch_resume(fd_entry->barrier_queue);
			});
		} else {
			if (orig_flags != -1) {
				_dispatch_io_syscall_switch(err,
					fcntl(fd, F_SETFL, orig_flags | O_NONBLOCK),
					default:
						orig_flags = -1;
						(void)dispatch_assume_zero(err);
						break;
				);
			}

			_dispatch_stream_init(fd_entry,
					_dispatch_get_root_queue(DISPATCH_QOS_DEFAULT, false));
		}
		fd_entry->orig_flags = orig_flags;
		fd_entry->orig_nosigpipe = orig_nosigpipe;
	});
	// This is the first item run when the close queue is resumed, indicating
	// that all channels associated with this entry have been closed and that
	// all operations associated with this entry have been freed
	dispatch_async(fd_entry->close_queue, ^{
		if (!fd_entry->disk) {
			_dispatch_fd_entry_debug("close queue cleanup", fd_entry);
			dispatch_op_direction_t dir;
			for (dir = 0; dir < DOP_DIR_MAX; dir++) {
				_dispatch_stream_dispose(fd_entry, dir);
			}
		} else {
			dispatch_disk_t disk = fd_entry->disk;
			dispatch_async(_dispatch_io_devs_lockq, ^{
				_dispatch_release(disk);
			});
		}
		// Remove this entry from the global fd list
		TAILQ_REMOVE(&_dispatch_io_fds[hash], fd_entry, fd_list);
	});
	// If there was a source associated with this stream, disposing of the
	// source cancels it and suspends the close queue. Freeing the fd_entry
	// structure must happen after the source cancel handler has finished
	dispatch_async(fd_entry->close_queue, ^{
		_dispatch_fd_entry_debug("close queue release", fd_entry);
		dispatch_release(fd_entry->close_queue);
		_dispatch_fd_entry_debug("barrier queue release", fd_entry);
		dispatch_release(fd_entry->barrier_queue);
		_dispatch_fd_entry_debug("barrier group release", fd_entry);
		dispatch_release(fd_entry->barrier_group);
		if (fd_entry->orig_flags != -1) {
			_dispatch_io_syscall(
				fcntl(fd, F_SETFL, fd_entry->orig_flags)
			);
		}
#if DISPATCH_USE_SETNOSIGPIPE // rdar://problem/4121123
		if (fd_entry->orig_nosigpipe != -1) {
			_dispatch_io_syscall(
				fcntl(fd, F_SETNOSIGPIPE, fd_entry->orig_nosigpipe)
			);
		}
#endif
		_dispatch_fd_entry_unguard(fd_entry);
		if (fd_entry->convenience_channel) {
			fd_entry->convenience_channel->fd_entry = NULL;
			dispatch_release(fd_entry->convenience_channel);
		}
		free(fd_entry);
	});
	return fd_entry;
}

static dispatch_fd_entry_t
_dispatch_fd_entry_create_with_path(dispatch_io_path_data_t path_data,
		dev_t dev, mode_t mode)
{
	// On devs lock queue
	dispatch_fd_entry_t fd_entry = _dispatch_fd_entry_create(
			path_data->channel->queue);
	_dispatch_fd_entry_debug("create: path %s", fd_entry, path_data->path);
	if (S_ISREG(mode)) {
		_dispatch_disk_init(fd_entry, (dev_t)major(dev));
	} else {
			_dispatch_stream_init(fd_entry,
					_dispatch_get_root_queue(DISPATCH_QOS_DEFAULT, false));
	}
	fd_entry->fd = -1;
	fd_entry->orig_flags = -1;
	fd_entry->path_data = path_data;
	fd_entry->stat.dev = dev;
	fd_entry->stat.mode = mode;
	fd_entry->barrier_queue = dispatch_queue_create(
			"com.apple.libdispatch-io.barrierq", NULL);
	fd_entry->barrier_group = dispatch_group_create();
	// This is the first item run when the close queue is resumed, indicating
	// that the channel associated with this entry has been closed and that
	// all operations associated with this entry have been freed
	dispatch_async(fd_entry->close_queue, ^{
		_dispatch_fd_entry_debug("close queue cleanup", fd_entry);
		if (!fd_entry->disk) {
			dispatch_op_direction_t dir;
			for (dir = 0; dir < DOP_DIR_MAX; dir++) {
				_dispatch_stream_dispose(fd_entry, dir);
			}
		}
		if (fd_entry->fd != -1) {
			_dispatch_fd_entry_guarded_close(fd_entry, fd_entry->fd);
		}
		if (fd_entry->path_data->channel) {
			// If associated channel has not been released yet, mark it as
			// no longer having an fd_entry (for stop after close).
			// It is safe to modify channel since we are on close_queue with
			// target queue the channel queue
			fd_entry->path_data->channel->fd_entry = NULL;
		}
	});
	dispatch_async(fd_entry->close_queue, ^{
		_dispatch_fd_entry_debug("close queue release", fd_entry);
		dispatch_release(fd_entry->close_queue);
		dispatch_release(fd_entry->barrier_queue);
		dispatch_release(fd_entry->barrier_group);
		free(fd_entry->path_data);
		free(fd_entry);
	});
	return fd_entry;
}

static int
_dispatch_fd_entry_open(dispatch_fd_entry_t fd_entry, dispatch_io_t channel)
{
	if (!(fd_entry->fd == -1 && fd_entry->path_data)) {
		return 0;
	}
	if (fd_entry->err) {
		return fd_entry->err;
	}
	int fd = -1;
	int oflag = fd_entry->disk ? fd_entry->path_data->oflag & ~O_NONBLOCK :
			fd_entry->path_data->oflag | O_NONBLOCK;
open:
	fd = _dispatch_fd_entry_guarded_open(fd_entry, fd_entry->path_data->path,
			oflag, fd_entry->path_data->mode);
	if (fd == -1) {
		int err = errno;
		if (err == EINTR) {
			goto open;
		}
		(void)os_atomic_cmpxchg2o(fd_entry, err, 0, err, relaxed);
		return err;
	}
	if (!os_atomic_cmpxchg2o(fd_entry, fd, -1, fd, relaxed)) {
		// Lost the race with another open
		_dispatch_fd_entry_guarded_close(fd_entry, fd);
	} else {
		channel->fd_actual = fd;
	}
	_dispatch_object_debug(channel, "%s", __func__);
	return 0;
}

static void
_dispatch_fd_entry_cleanup_operations(dispatch_fd_entry_t fd_entry,
		dispatch_io_t channel)
{
	if (fd_entry->disk) {
		if (channel) {
			_dispatch_retain(channel);
		}
		_dispatch_fd_entry_retain(fd_entry);
		dispatch_async(fd_entry->disk->pick_queue, ^{
			_dispatch_disk_cleanup_inactive_operations(fd_entry->disk, channel);
			_dispatch_fd_entry_release(fd_entry);
			if (channel) {
				_dispatch_release(channel);
			}
		});
	} else {
		dispatch_op_direction_t direction;
		for (direction = 0; direction < DOP_DIR_MAX; direction++) {
			dispatch_stream_t stream = fd_entry->streams[direction];
			if (!stream) {
				continue;
			}
			if (channel) {
				_dispatch_retain(channel);
			}
			_dispatch_fd_entry_retain(fd_entry);
			dispatch_async(stream->dq, ^{
				_dispatch_stream_cleanup_operations(stream, channel);
				_dispatch_fd_entry_release(fd_entry);
				if (channel) {
					_dispatch_release(channel);
				}
			});
		}
	}
}

#pragma mark -
#pragma mark dispatch_stream_t/dispatch_disk_t

static void
_dispatch_stream_init(dispatch_fd_entry_t fd_entry, dispatch_queue_t tq)
{
	dispatch_op_direction_t direction;
	for (direction = 0; direction < DOP_DIR_MAX; direction++) {
		dispatch_stream_t stream;
		stream = _dispatch_calloc(1ul, sizeof(struct dispatch_stream_s));
		stream->dq = dispatch_queue_create_with_target(
				"com.apple.libdispatch-io.streamq", NULL, tq);
		dispatch_set_context(stream->dq, stream);
		TAILQ_INIT(&stream->operations[DISPATCH_IO_RANDOM]);
		TAILQ_INIT(&stream->operations[DISPATCH_IO_STREAM]);
		fd_entry->streams[direction] = stream;
	}
}

static void
_dispatch_stream_dispose(dispatch_fd_entry_t fd_entry,
		dispatch_op_direction_t direction)
{
	// On close queue
	dispatch_stream_t stream = fd_entry->streams[direction];
	if (!stream) {
		return;
	}
	dispatch_assert(TAILQ_EMPTY(&stream->operations[DISPATCH_IO_STREAM]));
	dispatch_assert(TAILQ_EMPTY(&stream->operations[DISPATCH_IO_RANDOM]));
	if (stream->source) {
		// Balanced by source cancel handler:
		_dispatch_fd_entry_retain(fd_entry);
		dispatch_source_cancel(stream->source);
		dispatch_resume(stream->source);
		dispatch_release(stream->source);
	}
	dispatch_set_context(stream->dq, NULL);
	dispatch_release(stream->dq);
	free(stream);
}

static void
_dispatch_disk_init(dispatch_fd_entry_t fd_entry, dev_t dev)
{
	// On devs lock queue
	dispatch_disk_t disk;
	// Check to see if there is an existing entry for the given device
	uintptr_t hash = DIO_HASH(dev);
	TAILQ_FOREACH(disk, &_dispatch_io_devs[hash], disk_list) {
		if (disk->dev == dev) {
			_dispatch_retain(disk);
			goto out;
		}
	}
	// Otherwise create a new entry
	size_t pending_reqs_depth = dispatch_io_defaults.max_pending_io_reqs;
	disk = _dispatch_object_alloc(DISPATCH_VTABLE(disk),
			sizeof(struct dispatch_disk_s) +
			(pending_reqs_depth * sizeof(dispatch_operation_t)));
	disk->do_next = DISPATCH_OBJECT_LISTLESS;
	disk->do_xref_cnt = -1;
	disk->advise_list_depth = pending_reqs_depth;
	disk->do_targetq = _dispatch_get_root_queue(DISPATCH_QOS_DEFAULT, false);
	disk->dev = dev;
	TAILQ_INIT(&disk->operations);
	disk->cur_rq = TAILQ_FIRST(&disk->operations);
	char label[45];
	snprintf(label, sizeof(label), "com.apple.libdispatch-io.deviceq.%d",
			(int)dev);
	disk->pick_queue = dispatch_queue_create(label, NULL);
	TAILQ_INSERT_TAIL(&_dispatch_io_devs[hash], disk, disk_list);
out:
	fd_entry->disk = disk;
	TAILQ_INIT(&fd_entry->stream_ops);
}

void
_dispatch_disk_dispose(dispatch_disk_t disk, DISPATCH_UNUSED bool *allow_free)
{
	uintptr_t hash = DIO_HASH(disk->dev);
	TAILQ_REMOVE(&_dispatch_io_devs[hash], disk, disk_list);
	dispatch_assert(TAILQ_EMPTY(&disk->operations));
	size_t i;
	for (i=0; i<disk->advise_list_depth; ++i) {
		dispatch_assert(!disk->advise_list[i]);
	}
	dispatch_release(disk->pick_queue);
}

#pragma mark -
#pragma mark dispatch_stream_operations/dispatch_disk_operations

static inline bool
_dispatch_stream_operation_avail(dispatch_stream_t stream)
{
	return  !(TAILQ_EMPTY(&stream->operations[DISPATCH_IO_RANDOM])) ||
			!(TAILQ_EMPTY(&stream->operations[DISPATCH_IO_STREAM]));
}

static void
_dispatch_stream_enqueue_operation(dispatch_stream_t stream,
		dispatch_operation_t op, dispatch_data_t data)
{
	if (!_dispatch_operation_should_enqueue(op, stream->dq, data)) {
		return;
	}
	_dispatch_object_debug(op, "%s", __func__);
	bool no_ops = !_dispatch_stream_operation_avail(stream);
	TAILQ_INSERT_TAIL(&stream->operations[op->params.type], op, operation_list);
	if (no_ops) {
		dispatch_async_f(stream->dq, stream->dq,
				_dispatch_stream_queue_handler);
	}
}

static void
_dispatch_disk_enqueue_operation(dispatch_disk_t disk, dispatch_operation_t op,
		dispatch_data_t data)
{
	if (!_dispatch_operation_should_enqueue(op, disk->pick_queue, data)) {
		return;
	}
	_dispatch_object_debug(op, "%s", __func__);
	if (op->params.type == DISPATCH_IO_STREAM) {
		if (TAILQ_EMPTY(&op->fd_entry->stream_ops)) {
			TAILQ_INSERT_TAIL(&disk->operations, op, operation_list);
		}
		TAILQ_INSERT_TAIL(&op->fd_entry->stream_ops, op, stream_list);
	} else {
		TAILQ_INSERT_TAIL(&disk->operations, op, operation_list);
	}
	_dispatch_disk_handler(disk);
}

static void
_dispatch_stream_complete_operation(dispatch_stream_t stream,
		dispatch_operation_t op)
{
	// On stream queue
	_dispatch_object_debug(op, "%s", __func__);
	_dispatch_op_debug("complete: stream %p", op, stream);
	TAILQ_REMOVE(&stream->operations[op->params.type], op, operation_list);
	if (op == stream->op) {
		stream->op = NULL;
	}
	if (op->timer) {
		dispatch_source_cancel(op->timer);
	}
	// Final release will deliver any pending data
	_dispatch_op_debug("release -> %d (stream complete)", op, op->do_ref_cnt);
	_dispatch_release(op);
}

static void
_dispatch_disk_complete_operation(dispatch_disk_t disk, dispatch_operation_t op)
{
	// On pick queue
	_dispatch_object_debug(op, "%s", __func__);
	_dispatch_op_debug("complete: disk %p", op, disk);
	// Current request is always the last op returned
	if (disk->cur_rq == op) {
		disk->cur_rq = TAILQ_PREV(op, dispatch_disk_operations_s,
				operation_list);
	}
	if (op->params.type == DISPATCH_IO_STREAM) {
		// Check if there are other pending stream operations behind it
		dispatch_operation_t op_next = TAILQ_NEXT(op, stream_list);
		TAILQ_REMOVE(&op->fd_entry->stream_ops, op, stream_list);
		if (op_next) {
			TAILQ_INSERT_TAIL(&disk->operations, op_next, operation_list);
		}
	}
	TAILQ_REMOVE(&disk->operations, op, operation_list);
	if (op->timer) {
		dispatch_source_cancel(op->timer);
	}
	// Final release will deliver any pending data
	_dispatch_op_debug("release -> %d (disk complete)", op, op->do_ref_cnt);
	_dispatch_release(op);
}

static dispatch_operation_t
_dispatch_stream_pick_next_operation(dispatch_stream_t stream,
		dispatch_operation_t op)
{
	// On stream queue
	if (!op) {
		// On the first run through, pick the first operation
		if (!_dispatch_stream_operation_avail(stream)) {
			return op;
		}
		if (!TAILQ_EMPTY(&stream->operations[DISPATCH_IO_STREAM])) {
			op = TAILQ_FIRST(&stream->operations[DISPATCH_IO_STREAM]);
		} else if (!TAILQ_EMPTY(&stream->operations[DISPATCH_IO_RANDOM])) {
			op = TAILQ_FIRST(&stream->operations[DISPATCH_IO_RANDOM]);
		}
		return op;
	}
	if (op->params.type == DISPATCH_IO_STREAM) {
		// Stream operations need to be serialized so continue the current
		// operation until it is finished
		return op;
	}
	// Get the next random operation (round-robin)
	if (op->params.type == DISPATCH_IO_RANDOM) {
		op = TAILQ_NEXT(op, operation_list);
		if (!op) {
			op = TAILQ_FIRST(&stream->operations[DISPATCH_IO_RANDOM]);
		}
		return op;
	}
	return NULL;
}

static dispatch_operation_t
_dispatch_disk_pick_next_operation(dispatch_disk_t disk)
{
	// On pick queue
	dispatch_operation_t op;
	if (!TAILQ_EMPTY(&disk->operations)) {
		if (disk->cur_rq == NULL) {
			op = TAILQ_FIRST(&disk->operations);
		} else {
			op = disk->cur_rq;
			do {
				op = TAILQ_NEXT(op, operation_list);
				if (!op) {
					op = TAILQ_FIRST(&disk->operations);
				}
				// TODO: more involved picking algorithm rdar://problem/8780312
			} while (op->active && op != disk->cur_rq);
		}
		if (!op->active) {
			disk->cur_rq = op;
			return op;
		}
	}
	return NULL;
}

static void
_dispatch_stream_cleanup_operations(dispatch_stream_t stream,
		dispatch_io_t channel)
{
	// On stream queue
	dispatch_operation_t op, tmp;
	__typeof__(*stream->operations) *operations;
	operations = &stream->operations[DISPATCH_IO_RANDOM];
	TAILQ_FOREACH_SAFE(op, operations, operation_list, tmp) {
		if (!channel || op->channel == channel) {
			_dispatch_stream_complete_operation(stream, op);
		}
	}
	operations = &stream->operations[DISPATCH_IO_STREAM];
	TAILQ_FOREACH_SAFE(op, operations, operation_list, tmp) {
		if (!channel || op->channel == channel) {
			_dispatch_stream_complete_operation(stream, op);
		}
	}
	if (stream->source_running && !_dispatch_stream_operation_avail(stream)) {
		dispatch_suspend(stream->source);
		stream->source_running = false;
	}
}

static inline void
_dispatch_disk_cleanup_specified_operations(dispatch_disk_t disk,
		dispatch_io_t channel, bool inactive_only)
{
	// On pick queue
	dispatch_operation_t op, tmp;
	TAILQ_FOREACH_SAFE(op, &disk->operations, operation_list, tmp) {
		if (inactive_only && op->active) continue;
		if (!channel || op->channel == channel) {
			_dispatch_op_debug("cleanup: disk %p", op, disk);
			_dispatch_disk_complete_operation(disk, op);
		}
	}
}

static void
_dispatch_disk_cleanup_operations(dispatch_disk_t disk, dispatch_io_t channel)
{
	_dispatch_disk_cleanup_specified_operations(disk, channel, false);
}

static void
_dispatch_disk_cleanup_inactive_operations(dispatch_disk_t disk,
		dispatch_io_t channel)
{
	_dispatch_disk_cleanup_specified_operations(disk, channel, true);
}

#pragma mark -
#pragma mark dispatch_stream_handler/dispatch_disk_handler

static dispatch_source_t
_dispatch_stream_source(dispatch_stream_t stream, dispatch_operation_t op)
{
	// On stream queue
	if (stream->source) {
		return stream->source;
	}
	dispatch_fd_t fd = op->fd_entry->fd;
	_dispatch_op_debug("stream source create", op);
	dispatch_source_t source = NULL;
	if (op->direction == DOP_DIR_READ) {
		source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ,
				(uintptr_t)fd, 0, stream->dq);
	} else if (op->direction == DOP_DIR_WRITE) {
		source = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE,
				(uintptr_t)fd, 0, stream->dq);
	} else {
		dispatch_assert(op->direction < DOP_DIR_MAX);
		return NULL;
	}
	dispatch_set_context(source, stream);
	dispatch_source_set_event_handler_f(source,
			_dispatch_stream_source_handler);
	// Close queue must not run user cleanup handlers until sources are fully
	// unregistered
	dispatch_queue_t close_queue = op->fd_entry->close_queue;
	dispatch_source_set_mandatory_cancel_handler(source, ^{
		_dispatch_op_debug("stream source cancel", op);
		dispatch_resume(close_queue);
	});
	stream->source = source;
	return stream->source;
}

static void
_dispatch_stream_source_handler(void *ctx)
{
	// On stream queue
	dispatch_stream_t stream = (dispatch_stream_t)ctx;
	dispatch_suspend(stream->source);
	stream->source_running = false;
	return _dispatch_stream_handler(stream);
}

static void
_dispatch_stream_queue_handler(void *ctx)
{
	// On stream queue
	dispatch_stream_t stream = (dispatch_stream_t)dispatch_get_context(ctx);
	if (!stream) {
		// _dispatch_stream_dispose has been called
		return;
	}
	return _dispatch_stream_handler(stream);
}

static void
_dispatch_stream_handler(void *ctx)
{
	// On stream queue
	dispatch_stream_t stream = (dispatch_stream_t)ctx;
	dispatch_operation_t op;
pick:
	op = _dispatch_stream_pick_next_operation(stream, stream->op);
	if (!op) {
		_dispatch_debug("no operation found: stream %p", stream);
		return;
	}
	int err = _dispatch_io_get_error(op, NULL, true);
	if (err) {
		op->err = err;
		_dispatch_stream_complete_operation(stream, op);
		goto pick;
	}
	stream->op = op;
	_dispatch_op_debug("stream handler", op);
	dispatch_fd_entry_t fd_entry = op->fd_entry;
	_dispatch_fd_entry_retain(fd_entry);
	// For performance analysis
	if (!op->total && dispatch_io_defaults.initial_delivery) {
		// Empty delivery to signal the start of the operation
		_dispatch_op_debug("initial delivery", op);
		_dispatch_operation_deliver_data(op, DOP_DELIVER);
	}
	// TODO: perform on the operation target queue to get correct priority
	int result = _dispatch_operation_perform(op);
	dispatch_op_flags_t flags = ~0u;
	switch (result) {
	case DISPATCH_OP_DELIVER:
		flags = DOP_DEFAULT;
		// Fall through
	case DISPATCH_OP_DELIVER_AND_COMPLETE:
		flags = (flags != DOP_DEFAULT) ? DOP_DELIVER | DOP_NO_EMPTY :
				DOP_DEFAULT;
		_dispatch_operation_deliver_data(op, flags);
		// Fall through
	case DISPATCH_OP_COMPLETE:
		if (flags != DOP_DEFAULT) {
			_dispatch_stream_complete_operation(stream, op);
		}
		if (_dispatch_stream_operation_avail(stream)) {
			dispatch_async_f(stream->dq, stream->dq,
					_dispatch_stream_queue_handler);
		}
		break;
	case DISPATCH_OP_COMPLETE_RESUME:
		_dispatch_stream_complete_operation(stream, op);
		// Fall through
	case DISPATCH_OP_RESUME:
		if (_dispatch_stream_operation_avail(stream)) {
			stream->source_running = true;
			dispatch_resume(_dispatch_stream_source(stream, op));
		}
		break;
	case DISPATCH_OP_ERR:
		_dispatch_stream_cleanup_operations(stream, op->channel);
		break;
	case DISPATCH_OP_FD_ERR:
		_dispatch_fd_entry_retain(fd_entry);
		dispatch_async(fd_entry->barrier_queue, ^{
			_dispatch_fd_entry_cleanup_operations(fd_entry, NULL);
			_dispatch_fd_entry_release(fd_entry);
		});
		break;
	default:
		break;
	}
	_dispatch_fd_entry_release(fd_entry);
	return;
}

static void
_dispatch_disk_handler(void *ctx)
{
	// On pick queue
	dispatch_disk_t disk = (dispatch_disk_t)ctx;
	if (disk->io_active) {
		return;
	}
	_dispatch_disk_debug("disk handler", disk);
	dispatch_operation_t op;
	size_t i = disk->free_idx, j = disk->req_idx;
	if (j <= i) {
		j += disk->advise_list_depth;
	}
	while (i <= j) {
		if ((!disk->advise_list[i%disk->advise_list_depth]) &&
				(op = _dispatch_disk_pick_next_operation(disk))) {
			int err = _dispatch_io_get_error(op, NULL, true);
			if (err) {
				op->err = err;
				_dispatch_disk_complete_operation(disk, op);
				continue;
			}
			_dispatch_retain(op);
			_dispatch_op_debug("retain -> %d", op, op->do_ref_cnt + 1);
			disk->advise_list[i%disk->advise_list_depth] = op;
			op->active = true;
			_dispatch_op_debug("activate: disk %p", op, disk);
			_dispatch_object_debug(op, "%s", __func__);
		} else {
			// No more operations to get
			break;
		}
		i++;
	}
	disk->free_idx = (i%disk->advise_list_depth);
	op = disk->advise_list[disk->req_idx];
	if (op) {
		disk->io_active = true;
		_dispatch_op_debug("async perform: disk %p", op, disk);
		dispatch_async_f(op->do_targetq, disk, _dispatch_disk_perform);
	}
}

static void
_dispatch_disk_perform(void *ctxt)
{
	dispatch_disk_t disk = ctxt;
	_dispatch_disk_debug("disk perform", disk);
	size_t chunk_size = dispatch_io_defaults.chunk_size;
	dispatch_operation_t op;
	size_t i = disk->advise_idx, j = disk->free_idx;
	if (j <= i) {
		j += disk->advise_list_depth;
	}
	do {
		op = disk->advise_list[i%disk->advise_list_depth];
		if (!op) {
			// Nothing more to advise, must be at free_idx
			dispatch_assert(i%disk->advise_list_depth == disk->free_idx);
			break;
		}
		if (op->direction == DOP_DIR_WRITE) {
			// TODO: preallocate writes ? rdar://problem/9032172
			continue;
		}
		if (op->fd_entry->fd == -1 && _dispatch_fd_entry_open(op->fd_entry,
				op->channel)) {
			continue;
		}
		// For performance analysis
		if (!op->total && dispatch_io_defaults.initial_delivery) {
			// Empty delivery to signal the start of the operation
			_dispatch_op_debug("initial delivery", op);
			_dispatch_operation_deliver_data(op, DOP_DELIVER);
		}
		// Advise two chunks if the list only has one element and this is the
		// first advise on the operation
		if ((j-i) == 1 && !disk->advise_list[disk->free_idx] &&
				!op->advise_offset) {
			chunk_size *= 2;
		}
		_dispatch_operation_advise(op, chunk_size);
	} while (++i < j);
	disk->advise_idx = i%disk->advise_list_depth;
	op = disk->advise_list[disk->req_idx];
	int result = _dispatch_operation_perform(op);
	disk->advise_list[disk->req_idx] = NULL;
	disk->req_idx = (++disk->req_idx)%disk->advise_list_depth;
	_dispatch_op_debug("async perform completion: disk %p", op, disk);
	dispatch_async(disk->pick_queue, ^{
		_dispatch_op_debug("perform completion", op);
		switch (result) {
		case DISPATCH_OP_DELIVER:
			_dispatch_operation_deliver_data(op, DOP_DEFAULT);
			break;
		case DISPATCH_OP_COMPLETE:
			_dispatch_disk_complete_operation(disk, op);
			break;
		case DISPATCH_OP_DELIVER_AND_COMPLETE:
			_dispatch_operation_deliver_data(op, DOP_DELIVER | DOP_NO_EMPTY);
			_dispatch_disk_complete_operation(disk, op);
			break;
		case DISPATCH_OP_ERR:
			_dispatch_disk_cleanup_operations(disk, op->channel);
			break;
		case DISPATCH_OP_FD_ERR:
			_dispatch_disk_cleanup_operations(disk, NULL);
			break;
		default:
			dispatch_assert(result);
			break;
		}
		_dispatch_op_debug("deactivate: disk %p", op, disk);
		op->active = false;
		disk->io_active = false;
		_dispatch_disk_handler(disk);
		// Balancing the retain in _dispatch_disk_handler. Note that op must be
		// released at the very end, since it might hold the last reference to
		// the disk
		_dispatch_op_debug("release -> %d (disk perform complete)", op,
				op->do_ref_cnt);
		_dispatch_release(op);
	});
}

#pragma mark -
#pragma mark dispatch_operation_perform

static void
_dispatch_operation_advise(dispatch_operation_t op, size_t chunk_size)
{
	_dispatch_op_debug("advise", op);
	if (_dispatch_io_get_error(op, NULL, true)) return;
#if defined(__linux__) || defined(__FreeBSD__)
	// linux does not support fcntl (F_RDAVISE)
	// define necessary datastructure and use readahead
	struct radvisory {
		off_t ra_offset;
		int   ra_count;
	};
#endif
	int err;
	struct radvisory advise;
	// No point in issuing a read advise for the next chunk if we are already
	// a chunk ahead from reading the bytes
	if (op->advise_offset > (off_t)(((size_t)op->offset + op->total) +
			chunk_size + PAGE_SIZE)) {
		return;
	}
	_dispatch_object_debug(op, "%s", __func__);
	advise.ra_count = (int)chunk_size;
	if (!op->advise_offset) {
		op->advise_offset = op->offset;
		// If this is the first time through, align the advised range to a
		// page boundary
		size_t pg_fraction = ((size_t)op->offset + chunk_size) % PAGE_SIZE;
		advise.ra_count += (int)(pg_fraction ? PAGE_SIZE - pg_fraction : 0);
	}
	advise.ra_offset = op->advise_offset;
	op->advise_offset += advise.ra_count;
#if defined(__linux__)
	_dispatch_io_syscall_switch(err,
			readahead(op->fd_entry->fd, advise.ra_offset, (size_t)advise.ra_count),
		case EINVAL: break; // fd does refer to a non-supported filetype
		default: (void)dispatch_assume_zero(err); break;
	);
#else
	_dispatch_io_syscall_switch(err,
		fcntl(op->fd_entry->fd, F_RDADVISE, &advise),
		case EFBIG: break; // advised past the end of the file rdar://10415691
		case ENOTSUP: break; // not all FS support radvise rdar://13484629
		// TODO: set disk status on error
		default: (void)dispatch_assume_zero(err); break;
	);
#endif
}

static int
_dispatch_operation_perform(dispatch_operation_t op)
{
	_dispatch_op_debug("perform", op);
	int err = _dispatch_io_get_error(op, NULL, true);
	if (err) {
		goto error;
	}
	_dispatch_object_debug(op, "%s", __func__);
	if (!op->buf) {
		size_t max_buf_siz = op->params.high;
		size_t chunk_siz = dispatch_io_defaults.chunk_size;
		if (op->direction == DOP_DIR_READ) {
			// If necessary, create a buffer for the ongoing operation, large
			// enough to fit chunk_size but at most high-water
			size_t data_siz = dispatch_data_get_size(op->data);
			if (data_siz) {
				dispatch_assert(data_siz < max_buf_siz);
				max_buf_siz -= data_siz;
			}
			if (max_buf_siz > chunk_siz) {
				max_buf_siz = chunk_siz;
			}
			if (op->length < SIZE_MAX) {
				op->buf_siz = op->length - op->total;
				if (op->buf_siz > max_buf_siz) {
					op->buf_siz = max_buf_siz;
				}
			} else {
				op->buf_siz = max_buf_siz;
			}
			op->buf = valloc(op->buf_siz);
			_dispatch_op_debug("buffer allocated", op);
		} else if (op->direction == DOP_DIR_WRITE) {
			// Always write the first data piece, if that is smaller than a
			// chunk, accumulate further data pieces until chunk size is reached
			if (chunk_siz > max_buf_siz) {
				chunk_siz = max_buf_siz;
			}
			op->buf_siz = 0;
			dispatch_data_apply(op->data,
					^(dispatch_data_t region DISPATCH_UNUSED,
					size_t offset DISPATCH_UNUSED,
					const void* buf DISPATCH_UNUSED, size_t len) {
				size_t siz = op->buf_siz + len;
				if (!op->buf_siz || siz <= chunk_siz) {
					op->buf_siz = siz;
				}
				return (bool)(siz < chunk_siz);
			});
			if (op->buf_siz > max_buf_siz) {
				op->buf_siz = max_buf_siz;
			}
			dispatch_data_t d;
			d = dispatch_data_create_subrange(op->data, 0, op->buf_siz);
			op->buf_data = dispatch_data_create_map(d, (const void**)&op->buf,
					NULL);
			_dispatch_io_data_release(d);
			_dispatch_op_debug("buffer mapped", op);
		}
	}
	if (op->fd_entry->fd == -1) {
		err = _dispatch_fd_entry_open(op->fd_entry, op->channel);
		if (err) {
			goto error;
		}
	}
	void *buf = op->buf + op->buf_len;
	size_t len = op->buf_siz - op->buf_len;
	off_t off = (off_t)((size_t)op->offset + op->total);
	ssize_t processed = -1;
syscall:
	if (op->direction == DOP_DIR_READ) {
		if (op->params.type == DISPATCH_IO_STREAM) {
			processed = read(op->fd_entry->fd, buf, len);
		} else if (op->params.type == DISPATCH_IO_RANDOM) {
			processed = pread(op->fd_entry->fd, buf, len, off);
		}
	} else if (op->direction == DOP_DIR_WRITE) {
		if (op->params.type == DISPATCH_IO_STREAM) {
			processed = write(op->fd_entry->fd, buf, len);
		} else if (op->params.type == DISPATCH_IO_RANDOM) {
			processed = pwrite(op->fd_entry->fd, buf, len, off);
		}
	}
	// Encountered an error on the file descriptor
	if (processed == -1) {
		err = errno;
		if (err == EINTR) {
			goto syscall;
		}
		goto error;
	}
	// EOF is indicated by two handler invocations
	if (processed == 0) {
		_dispatch_op_debug("performed: EOF", op);
		return DISPATCH_OP_DELIVER_AND_COMPLETE;
	}
	op->buf_len += (size_t)processed;
	op->total += (size_t)processed;
	if (op->total == op->length) {
		// Finished processing all the bytes requested by the operation
		return DISPATCH_OP_COMPLETE;
	} else {
		// Deliver data only if we satisfy the filters
		return DISPATCH_OP_DELIVER;
	}
error:
	if (err == EAGAIN || err == EWOULDBLOCK) {
		// For disk based files with blocking I/O we should never get EAGAIN
		dispatch_assert(!op->fd_entry->disk);
		_dispatch_op_debug("performed: EAGAIN/EWOULDBLOCK", op);
		if (op->direction == DOP_DIR_READ && op->total &&
				op->channel == op->fd_entry->convenience_channel) {
			// Convenience read with available data completes on EAGAIN
			return DISPATCH_OP_COMPLETE_RESUME;
		}
		return DISPATCH_OP_RESUME;
	}
	_dispatch_op_debug("performed: err %d", op, err);
	op->err = err;
	switch (err) {
	case ECANCELED:
		return DISPATCH_OP_ERR;
	case EBADF:
		(void)os_atomic_cmpxchg2o(op->fd_entry, err, 0, err, relaxed);
		return DISPATCH_OP_FD_ERR;
	default:
		return DISPATCH_OP_COMPLETE;
	}
}

static void
_dispatch_operation_deliver_data(dispatch_operation_t op,
		dispatch_op_flags_t flags)
{
	// Either called from stream resp. pick queue or when op is finalized
	dispatch_data_t data = NULL;
	int err = 0;
	size_t undelivered = op->undelivered + op->buf_len;
	bool deliver = (flags & (DOP_DELIVER|DOP_DONE)) ||
			(op->flags & DOP_DELIVER);
	op->flags = DOP_DEFAULT;
	if (!deliver) {
		// Don't deliver data until low water mark has been reached
		if (undelivered >= op->params.low) {
			deliver = true;
		} else if (op->buf_len < op->buf_siz) {
			// Request buffer is not yet used up
			_dispatch_op_debug("buffer data: undelivered %zu", op, undelivered);
			return;
		}
	} else {
		err = op->err;
		if (!err && (op->channel->atomic_flags & DIO_STOPPED)) {
			err = ECANCELED;
			op->err = err;
		}
	}
	// Deliver data or buffer used up
	if (op->direction == DOP_DIR_READ) {
		if (op->buf_len) {
			void *buf = op->buf;
			data = dispatch_data_create(buf, op->buf_len, NULL,
					DISPATCH_DATA_DESTRUCTOR_FREE);
			op->buf = NULL;
			op->buf_len = 0;
			dispatch_data_t d = dispatch_data_create_concat(op->data, data);
			_dispatch_io_data_release(op->data);
			_dispatch_io_data_release(data);
			data = d;
		} else {
			data = op->data;
		}
		op->data = deliver ? dispatch_data_empty : data;
	} else if (op->direction == DOP_DIR_WRITE) {
		if (deliver) {
			data = dispatch_data_create_subrange(op->data, op->buf_len,
					op->length);
		}
		if (op->buf_data && op->buf_len == op->buf_siz) {
			_dispatch_io_data_release(op->buf_data);
			op->buf_data = NULL;
			op->buf = NULL;
			op->buf_len = 0;
			// Trim newly written buffer from head of unwritten data
			dispatch_data_t d;
			if (deliver) {
				_dispatch_io_data_retain(data);
				d = data;
			} else {
				d = dispatch_data_create_subrange(op->data, op->buf_siz,
						op->length);
			}
			_dispatch_io_data_release(op->data);
			op->data = d;
		}
	} else {
		dispatch_assert(op->direction < DOP_DIR_MAX);
		return;
	}
	if (!deliver || ((flags & DOP_NO_EMPTY) && !dispatch_data_get_size(data))) {
		op->undelivered = undelivered;
		_dispatch_op_debug("buffer data: undelivered %zu", op, undelivered);
		return;
	}
	op->undelivered = 0;
	_dispatch_object_debug(op, "%s", __func__);
	_dispatch_op_debug("deliver data", op);
	dispatch_op_direction_t direction = op->direction;
	dispatch_io_handler_t handler = op->handler;
	dispatch_fd_entry_t fd_entry = op->fd_entry;
	_dispatch_fd_entry_retain(fd_entry);
	dispatch_io_t channel = op->channel;
	_dispatch_retain(channel);
	// Note that data delivery may occur after the operation is freed
	dispatch_async(op->op_q, ^{
		bool done = (flags & DOP_DONE);
		dispatch_data_t d = data;
		if (done) {
			if (direction == DOP_DIR_READ && err) {
				if (dispatch_data_get_size(d)) {
					_dispatch_op_debug("IO handler invoke", op);
					handler(false, d, 0);
				}
				d = NULL;
			} else if (direction == DOP_DIR_WRITE && !err) {
				d = NULL;
			}
		}
		_dispatch_op_debug("IO handler invoke: err %d", op, err);
		handler(done, d, err);
		_dispatch_release(channel);
		_dispatch_fd_entry_release(fd_entry);
		_dispatch_io_data_release(data);
	});
}

#pragma mark -
#pragma mark dispatch_io_debug

static size_t
_dispatch_io_debug_attr(dispatch_io_t channel, char* buf, size_t bufsiz)
{
	dispatch_queue_t target = channel->do_targetq;
	return dsnprintf(buf, bufsiz, "type = %s, fd = 0x%x, %sfd_entry = %p, "
			"queue = %p, target = %s[%p], barrier_queue = %p, barrier_group = "
			"%p, err = 0x%x, low = 0x%zx, high = 0x%zx, interval%s = %llu ",
			channel->params.type == DISPATCH_IO_STREAM ? "stream" : "random",
			channel->fd_actual, channel->atomic_flags & DIO_STOPPED ?
			"stopped, " : channel->atomic_flags & DIO_CLOSED ? "closed, " : "",
			channel->fd_entry, channel->queue, target && target->dq_label ?
			target->dq_label : "", target, channel->barrier_queue,
			channel->barrier_group, channel->err, channel->params.low,
			channel->params.high, channel->params.interval_flags &
			DISPATCH_IO_STRICT_INTERVAL ? "(strict)" : "",
			(unsigned long long) channel->params.interval);
}

size_t
_dispatch_io_debug(dispatch_io_t channel, char* buf, size_t bufsiz)
{
	size_t offset = 0;
	offset += dsnprintf(&buf[offset], bufsiz - offset, "%s[%p] = { ",
			dx_kind(channel), channel);
	offset += _dispatch_object_debug_attr(channel, &buf[offset],
			bufsiz - offset);
	offset += _dispatch_io_debug_attr(channel, &buf[offset], bufsiz - offset);
	offset += dsnprintf(&buf[offset], bufsiz - offset, "}");
	return offset;
}

static size_t
_dispatch_operation_debug_attr(dispatch_operation_t op, char* buf,
		size_t bufsiz)
{
	dispatch_queue_t target = op->do_targetq;
	dispatch_queue_t oqtarget = op->op_q ? op->op_q->do_targetq : NULL;
	return dsnprintf(buf, bufsiz, "type = %s %s, fd = 0x%x, fd_entry = %p, "
			"channel = %p, queue = %p -> %s[%p], target = %s[%p], "
			"offset = %lld, length = %zu, done = %zu, undelivered = %zu, "
			"flags = %u, err = 0x%x, low = 0x%zx, high = 0x%zx, "
			"interval%s = %llu ", op->params.type == DISPATCH_IO_STREAM ?
			"stream" : "random", op->direction == DOP_DIR_READ ? "read" :
			"write", op->fd_entry ? op->fd_entry->fd : -1, op->fd_entry,
			op->channel, op->op_q, oqtarget && oqtarget->dq_label ?
			oqtarget->dq_label : "", oqtarget, target && target->dq_label ?
			target->dq_label : "", target, (long long)op->offset, op->length,
			op->total, op->undelivered + op->buf_len, op->flags, op->err,
			op->params.low, op->params.high, op->params.interval_flags &
			DISPATCH_IO_STRICT_INTERVAL ? "(strict)" : "",
			(unsigned long long)op->params.interval);
}

size_t
_dispatch_operation_debug(dispatch_operation_t op, char* buf, size_t bufsiz)
{
	size_t offset = 0;
	offset += dsnprintf(&buf[offset], bufsiz - offset, "%s[%p] = { ",
			dx_kind(op), op);
	offset += _dispatch_object_debug_attr(op, &buf[offset], bufsiz - offset);
	offset += _dispatch_operation_debug_attr(op, &buf[offset], bufsiz - offset);
	offset += dsnprintf(&buf[offset], bufsiz - offset, "}");
	return offset;
}
