1/* 2 * Copyright (c) 2009-2013 Apple Inc. All rights reserved. 3 * 4 * @APPLE_APACHE_LICENSE_HEADER_START@ 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * @APPLE_APACHE_LICENSE_HEADER_END@ 19 */ 20 21/* 22 * IMPORTANT: This header file describes INTERNAL interfaces to libdispatch 23 * which are subject to change in future releases of Mac OS X. Any applications 24 * relying on these interfaces WILL break. 25 */ 26 27#ifndef __DISPATCH_IO_INTERNAL__ 28#define __DISPATCH_IO_INTERNAL__ 29 30#ifndef __DISPATCH_INDIRECT__ 31#error "Please #include <dispatch/dispatch.h> instead of this file directly." 32#include <dispatch/base.h> // for HeaderDoc 33#endif 34 35#define _DISPATCH_IO_LABEL_SIZE 16 36 37#if TARGET_OS_EMBEDDED // rdar://problem/9032036 38#define DIO_MAX_CHUNK_PAGES 128u // 512kB chunk size 39#else 40#define DIO_MAX_CHUNK_PAGES 256u // 1024kB chunk size 41#endif 42 43#define DIO_DEFAULT_LOW_WATER_CHUNKS 1u // default low-water mark 44#define DIO_MAX_PENDING_IO_REQS 6u // Pending I/O read advises 45 46typedef unsigned int dispatch_op_direction_t; 47enum { 48 DOP_DIR_READ = 0, 49 DOP_DIR_WRITE, 50 DOP_DIR_MAX, 51 DOP_DIR_IGNORE = UINT_MAX, 52}; 53 54typedef unsigned int dispatch_op_flags_t; 55#define DOP_DEFAULT 0u // check conditions to determine delivery 56#define DOP_DELIVER 1u // always deliver operation 57#define DOP_DONE 2u // operation is done (implies deliver) 58#define DOP_STOP 4u // operation interrupted by chan stop (implies done) 59#define DOP_NO_EMPTY 8u // don't deliver empty data 60 61// dispatch_io_t atomic_flags 62#define DIO_CLOSED 1u // channel has been closed 63#define DIO_STOPPED 2u // channel has been stopped (implies closed) 64 65DISPATCH_DECL_INTERNAL(dispatch_operation); 66DISPATCH_DECL_INTERNAL(dispatch_disk); 67 68struct dispatch_stream_s { 69 dispatch_queue_t dq; 70 dispatch_source_t source; 71 dispatch_operation_t op; 72 bool source_running; 73 TAILQ_HEAD(, dispatch_operation_s) operations[2]; 74}; 75 76typedef struct dispatch_stream_s *dispatch_stream_t; 77 78struct dispatch_io_path_data_s { 79 dispatch_io_t channel; 80 int oflag; 81 mode_t mode; 82 size_t pathlen; 83 char path[]; 84}; 85 86typedef struct dispatch_io_path_data_s *dispatch_io_path_data_t; 87 88struct dispatch_stat_s { 89 dev_t dev; 90 mode_t mode; 91}; 92 93DISPATCH_CLASS_DECL(disk); 94struct dispatch_disk_s { 95 DISPATCH_STRUCT_HEADER(disk); 96 dev_t dev; 97 TAILQ_HEAD(dispatch_disk_operations_s, dispatch_operation_s) operations; 98 dispatch_operation_t cur_rq; 99 dispatch_queue_t pick_queue; 100 101 size_t free_idx; 102 size_t req_idx; 103 size_t advise_idx; 104 bool io_active; 105 int err; 106 TAILQ_ENTRY(dispatch_disk_s) disk_list; 107 size_t advise_list_depth; 108 dispatch_operation_t advise_list[]; 109}; 110 111struct dispatch_fd_entry_s { 112 dispatch_fd_t fd; 113 dispatch_io_path_data_t path_data; 114 int orig_flags, orig_nosigpipe, err; 115#if DISPATCH_USE_GUARDED_FD_CHANGE_FDGUARD 116 int orig_fd_flags; 117#endif 118#if DISPATCH_USE_GUARDED_FD 119 unsigned int guard_flags; 120#endif 121 struct dispatch_stat_s stat; 122 dispatch_stream_t streams[2]; 123 dispatch_disk_t disk; 124 dispatch_queue_t close_queue, barrier_queue; 125 dispatch_group_t barrier_group; 126 dispatch_io_t convenience_channel; 127 TAILQ_HEAD(, dispatch_operation_s) stream_ops; 128 TAILQ_ENTRY(dispatch_fd_entry_s) fd_list; 129}; 130 131typedef struct dispatch_fd_entry_s *dispatch_fd_entry_t; 132 133typedef struct dispatch_io_param_s { 134 dispatch_io_type_t type; // STREAM OR RANDOM 135 size_t low; 136 size_t high; 137 uint64_t interval; 138 unsigned long interval_flags; 139} dispatch_io_param_s; 140 141DISPATCH_CLASS_DECL(operation); 142struct dispatch_operation_s { 143 DISPATCH_STRUCT_HEADER(operation); 144 dispatch_queue_t op_q; 145 dispatch_op_direction_t direction; // READ OR WRITE 146 dispatch_io_param_s params; 147 off_t offset; 148 size_t length; 149 int err; 150 dispatch_io_handler_t handler; 151 dispatch_io_t channel; 152 dispatch_fd_entry_t fd_entry; 153 dispatch_source_t timer; 154 bool active; 155 off_t advise_offset; 156 void* buf; 157 dispatch_op_flags_t flags; 158 size_t buf_siz, buf_len, undelivered, total; 159 dispatch_data_t buf_data, data; 160 TAILQ_ENTRY(dispatch_operation_s) operation_list; 161 // the request list in the fd_entry stream_ops 162 TAILQ_ENTRY(dispatch_operation_s) stream_list; 163}; 164 165DISPATCH_CLASS_DECL(io); 166struct dispatch_io_s { 167 DISPATCH_STRUCT_HEADER(io); 168 dispatch_queue_t queue, barrier_queue; 169 dispatch_group_t barrier_group; 170 dispatch_io_param_s params; 171 dispatch_fd_entry_t fd_entry; 172 unsigned int atomic_flags; 173 dispatch_fd_t fd, fd_actual; 174 off_t f_ptr; 175 int err; // contains creation errors only 176}; 177 178void _dispatch_io_set_target_queue(dispatch_io_t channel, dispatch_queue_t dq); 179size_t _dispatch_io_debug(dispatch_io_t channel, char* buf, size_t bufsiz); 180void _dispatch_io_dispose(dispatch_io_t channel); 181size_t _dispatch_operation_debug(dispatch_operation_t op, char* buf, 182 size_t bufsiz); 183void _dispatch_operation_dispose(dispatch_operation_t operation); 184void _dispatch_disk_dispose(dispatch_disk_t disk); 185 186#endif // __DISPATCH_IO_INTERNAL__ 187