darwin-xnu/iokit/Kernel/IOCommandPool.cpp
<<
>>
Prefs
   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
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.