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 46 typedef unsigned int dispatch_op_direction_t; 47 enum { 48 DOP_DIR_READ = 0, 49 DOP_DIR_WRITE, 50 DOP_DIR_MAX, 51 DOP_DIR_IGNORE = UINT_MAX, 52 }; 53 54 typedef 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 65 DISPATCH_DECL_INTERNAL(dispatch_operation); 66 DISPATCH_DECL_INTERNAL(dispatch_disk); 67 68 struct 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 76 typedef struct dispatch_stream_s *dispatch_stream_t; 77 78 struct 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 86 typedef struct dispatch_io_path_data_s *dispatch_io_path_data_t; 87 88 struct dispatch_stat_s { 89 dev_t dev; 90 mode_t mode; 91 }; 92 93 DISPATCH_CLASS_DECL(disk); 94 struct 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 111 struct 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 131 typedef struct dispatch_fd_entry_s *dispatch_fd_entry_t; 132 133 typedef 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 141 DISPATCH_CLASS_DECL(operation); 142 struct 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 165 DISPATCH_CLASS_DECL(io); 166 struct 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 178 void _dispatch_io_set_target_queue(dispatch_io_t channel, dispatch_queue_t dq); 179 size_t _dispatch_io_debug(dispatch_io_t channel, char* buf, size_t bufsiz); 180 void _dispatch_io_dispose(dispatch_io_t channel); 181 size_t _dispatch_operation_debug(dispatch_operation_t op, char* buf, 182 size_t bufsiz); 183 void _dispatch_operation_dispose(dispatch_operation_t operation); 184 void _dispatch_disk_dispose(dispatch_disk_t disk); 185 186 #endif // __DISPATCH_IO_INTERNAL__ 187