1/* 2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22 23/* 24 * 25 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 26 * 27 * HISTORY 28 * 29 * 2001-01-17 gvdl Re-implement on IOCommandGate::commandSleep 30 * 10/9/2000 CJS Created IOCommandPool class and implementation 31 * 32 */ 33 34#include <IOKit/IOCommandPool.h> 35 36#define super OSObject 37OSDefineMetaClassAndStructors(IOCommandPool, OSObject); 38OSMetaClassDefineReservedUnused(IOCommandPool, 0); 39OSMetaClassDefineReservedUnused(IOCommandPool, 1); 40OSMetaClassDefineReservedUnused(IOCommandPool, 2); 41OSMetaClassDefineReservedUnused(IOCommandPool, 3); 42OSMetaClassDefineReservedUnused(IOCommandPool, 4); 43OSMetaClassDefineReservedUnused(IOCommandPool, 5); 44OSMetaClassDefineReservedUnused(IOCommandPool, 6); 45OSMetaClassDefineReservedUnused(IOCommandPool, 7); 46 47//-------------------------------------------------------------------------- 48// withWorkLoop - primary initializer and factory method 49//-------------------------------------------------------------------------- 50 51IOCommandPool *IOCommandPool:: 52withWorkLoop(IOWorkLoop *inWorkLoop) 53{ 54 IOCommandPool * me = new IOCommandPool; 55 56 if (me && !me->initWithWorkLoop(inWorkLoop)) { 57 me->release(); 58 return 0; 59 } 60 61 return me; 62} 63 64 65bool IOCommandPool:: 66initWithWorkLoop(IOWorkLoop *inWorkLoop) 67{ 68 assert(inWorkLoop); 69 70 if (!super::init()) 71 return false; 72 73 queue_init(&fQueueHead); 74 75 fSerializer = IOCommandGate::commandGate(this); 76 assert(fSerializer); 77 if (!fSerializer) 78 return false; 79 80 if (kIOReturnSuccess != inWorkLoop->addEventSource(fSerializer)) 81 return false; 82 83 return true; 84} 85 86//-------------------------------------------------------------------------- 87// commandPool & init - obsolete initializer and factory method 88//-------------------------------------------------------------------------- 89 90IOCommandPool *IOCommandPool:: 91commandPool(IOService * inOwner, IOWorkLoop *inWorkLoop, UInt32 inSize) 92{ 93 IOCommandPool * me = new IOCommandPool; 94 95 if (me && !me->init(inOwner, inWorkLoop, inSize)) { 96 me->release(); 97 return 0; 98 } 99 100 return me; 101} 102 103bool IOCommandPool:: 104init(IOService */* inOwner */, IOWorkLoop *inWorkLoop, UInt32 /* inSize */) 105{ 106 return initWithWorkLoop(inWorkLoop); 107} 108 109 110//-------------------------------------------------------------------------- 111// free - free all allocated resources 112//-------------------------------------------------------------------------- 113 114void 115IOCommandPool::free(void) 116{ 117 if (fSerializer) { 118 // remove our event source from owner's workloop 119 IOWorkLoop *wl = fSerializer->getWorkLoop(); 120 if (wl) 121 wl->removeEventSource(fSerializer); 122 123 fSerializer->release(); 124 fSerializer = 0; 125 } 126 127 // Tell our superclass to cleanup too 128 super::free(); 129} 130 131 132//-------------------------------------------------------------------------- 133// getCommand - Gets a command from the pool. Pass true in 134// blockForCommand if you want your thread to sleep 135// waiting for resources 136//-------------------------------------------------------------------------- 137 138IOCommand * 139IOCommandPool::getCommand(bool blockForCommand) 140{ 141 IOReturn result = kIOReturnSuccess; 142 IOCommand *command = 0; 143 144 result = fSerializer->runAction((IOCommandGate::Action) 145 &IOCommandPool::gatedGetCommand, 146 (void *) &command, (void *) blockForCommand); 147 if (kIOReturnSuccess == result) 148 return command; 149 else 150 return 0; 151} 152 153 154//-------------------------------------------------------------------------- 155// gatedGetCommand - Static callthrough function 156// (on safe side of command gate) 157//-------------------------------------------------------------------------- 158 159IOReturn IOCommandPool:: 160gatedGetCommand(IOCommand **command, bool blockForCommand) 161{ 162 while (queue_empty(&fQueueHead)) { 163 if (!blockForCommand) 164 return kIOReturnNoResources; 165 166 fSleepers++; 167 fSerializer->commandSleep(&fSleepers, THREAD_UNINT); 168 } 169 170 queue_remove_first(&fQueueHead, 171 *command, IOCommand *, fCommandChain); 172 return kIOReturnSuccess; 173} 174 175 176//-------------------------------------------------------------------------- 177// returnCommand - Returns command to the pool. 178//-------------------------------------------------------------------------- 179 180void IOCommandPool:: 181returnCommand(IOCommand *command) 182{ 183 (void) fSerializer->runAction((IOCommandGate::Action) 184 &IOCommandPool::gatedReturnCommand, (void *) command); 185} 186 187 188//-------------------------------------------------------------------------- 189// gatedReturnCommand - Callthrough function 190// (on safe side of command gate) 191//-------------------------------------------------------------------------- 192 193IOReturn IOCommandPool:: 194gatedReturnCommand(IOCommand *command) 195{ 196 queue_enter(&fQueueHead, command, IOCommand *, fCommandChain); 197 if (fSleepers) { 198 fSerializer->commandWakeup(&fSleepers, /* oneThread */ true); 199 fSleepers--; 200 } 201 return kIOReturnSuccess; 202} 203

