1 /* 2 * Copyright (c) 1998-2000, 2009 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 /* 29 * Copyright (c) 1998 Apple Computer, Inc. All rights reserved. 30 * 31 * HISTORY 32 * 1998-7-13 Godfrey van der Linden(gvdl) 33 * Created. 34 * ]*/ 35 36 #define IOKIT_ENABLE_SHARED_PTR 37 38 #include <IOKit/IOLib.h> 39 40 #include <IOKit/IOEventSource.h> 41 #include <IOKit/IOWorkLoop.h> 42 #include <libkern/Block.h> 43 44 #define super OSObject 45 46 OSDefineMetaClassAndAbstractStructors(IOEventSource, OSObject) 47 48 OSMetaClassDefineReservedUnused(IOEventSource, 0); 49 OSMetaClassDefineReservedUnused(IOEventSource, 1); 50 OSMetaClassDefineReservedUnused(IOEventSource, 2); 51 OSMetaClassDefineReservedUnused(IOEventSource, 3); 52 OSMetaClassDefineReservedUnused(IOEventSource, 4); 53 OSMetaClassDefineReservedUnused(IOEventSource, 5); 54 OSMetaClassDefineReservedUnused(IOEventSource, 6); 55 OSMetaClassDefineReservedUnused(IOEventSource, 7); 56 57 bool 58 IOEventSource::checkForWork() 59 { 60 return false; 61 } 62 63 /* inline function implementations */ 64 65 #if IOKITSTATS 66 67 #define IOStatisticsRegisterCounter() \ 68 do { \ 69 reserved->counter = IOStatistics::registerEventSource(inOwner); \ 70 } while (0) 71 72 #define IOStatisticsUnregisterCounter() \ 73 do { \ 74 if (reserved) \ 75 IOStatistics::unregisterEventSource(reserved->counter); \ 76 } while (0) 77 78 #define IOStatisticsOpenGate() \ 79 do { \ 80 IOStatistics::countOpenGate(reserved->counter); \ 81 } while (0) 82 83 #define IOStatisticsCloseGate() \ 84 do { \ 85 IOStatistics::countCloseGate(reserved->counter); \ 86 } while (0) 87 88 #else 89 90 #define IOStatisticsRegisterCounter() 91 #define IOStatisticsUnregisterCounter() 92 #define IOStatisticsOpenGate() 93 #define IOStatisticsCloseGate() 94 95 #endif /* IOKITSTATS */ 96 97 void 98 IOEventSource::signalWorkAvailable() 99 { 100 workLoop->signalWorkAvailable(); 101 } 102 103 void 104 IOEventSource::openGate() 105 { 106 IOStatisticsOpenGate(); 107 workLoop->openGate(); 108 } 109 110 void 111 IOEventSource::closeGate() 112 { 113 workLoop->closeGate(); 114 IOStatisticsCloseGate(); 115 } 116 117 bool 118 IOEventSource::tryCloseGate() 119 { 120 bool res; 121 if ((res = workLoop->tryCloseGate())) { 122 IOStatisticsCloseGate(); 123 } 124 return res; 125 } 126 127 int 128 IOEventSource::sleepGate(void *event, UInt32 type) 129 { 130 int res; 131 IOStatisticsOpenGate(); 132 res = workLoop->sleepGate(event, type); 133 IOStatisticsCloseGate(); 134 return res; 135 } 136 137 int 138 IOEventSource::sleepGate(void *event, AbsoluteTime deadline, UInt32 type) 139 { 140 int res; 141 IOStatisticsOpenGate(); 142 res = workLoop->sleepGate(event, deadline, type); 143 IOStatisticsCloseGate(); 144 return res; 145 } 146 147 void 148 IOEventSource::wakeupGate(void *event, bool oneThread) 149 { 150 workLoop->wakeupGate(event, oneThread); 151 } 152 153 154 bool 155 IOEventSource::init(OSObject *inOwner, 156 Action inAction) 157 { 158 if (!inOwner) { 159 return false; 160 } 161 162 owner = inOwner; 163 164 if (!super::init()) { 165 return false; 166 } 167 168 (void) setAction(inAction); 169 enabled = true; 170 171 if (!reserved) { 172 reserved = IONew(ExpansionData, 1); 173 if (!reserved) { 174 return false; 175 } 176 } 177 178 IOStatisticsRegisterCounter(); 179 180 return true; 181 } 182 183 void 184 IOEventSource::free( void ) 185 { 186 IOStatisticsUnregisterCounter(); 187 188 if ((kActionBlock & flags) && actionBlock) { 189 Block_release(actionBlock); 190 } 191 192 if (reserved) { 193 IODelete(reserved, ExpansionData, 1); 194 } 195 196 super::free(); 197 } 198 199 void 200 IOEventSource::setRefcon(void *newrefcon) 201 { 202 refcon = newrefcon; 203 } 204 205 void * 206 IOEventSource::getRefcon() const 207 { 208 return refcon; 209 } 210 211 IOEventSource::Action 212 IOEventSource::getAction() const 213 { 214 if (kActionBlock & flags) { 215 return NULL; 216 } 217 return action; 218 } 219 220 IOEventSource::ActionBlock 221 IOEventSource::getActionBlock(ActionBlock) const 222 { 223 if (kActionBlock & flags) { 224 return actionBlock; 225 } 226 return NULL; 227 } 228 229 void 230 IOEventSource::setAction(Action inAction) 231 { 232 if ((kActionBlock & flags) && actionBlock) { 233 Block_release(actionBlock); 234 } 235 action = inAction; 236 flags &= ~kActionBlock; 237 } 238 239 void 240 IOEventSource::setActionBlock(ActionBlock block) 241 { 242 if ((kActionBlock & flags) && actionBlock) { 243 Block_release(actionBlock); 244 } 245 actionBlock = Block_copy(block); 246 flags |= kActionBlock; 247 } 248 249 IOEventSource * 250 IOEventSource::getNext() const 251 { 252 return eventChainNext; 253 }; 254 255 void 256 IOEventSource::setNext(IOEventSource *inNext) 257 { 258 eventChainNext = inNext; 259 } 260 261 void 262 IOEventSource::enable() 263 { 264 enabled = true; 265 if (workLoop) { 266 return signalWorkAvailable(); 267 } 268 } 269 270 void 271 IOEventSource::disable() 272 { 273 enabled = false; 274 } 275 276 bool 277 IOEventSource::isEnabled() const 278 { 279 return enabled; 280 } 281 282 void 283 IOEventSource::setWorkLoop(IOWorkLoop *inWorkLoop) 284 { 285 if (!inWorkLoop) { 286 disable(); 287 } 288 workLoop = inWorkLoop; 289 } 290 291 IOWorkLoop * 292 IOEventSource::getWorkLoop() const 293 { 294 return workLoop; 295 } 296 297 bool 298 IOEventSource::onThread() const 299 { 300 return (workLoop != NULL) && workLoop->onThread(); 301 } 302