Exemple #1
0
void AppleGPIO::unregisterWithParent(void)
{
	// grab the mutex
	IOLockLock(fAmRegisteredLock);

	if (!fAmRegistered)
	{
		DLOG("AppleGPIO::unregisterWithParent not registered!!\n");
		IOLockUnlock(fAmRegisteredLock);
		return;
	}

	if (fParent->callPlatformFunction(kSymGPIOParentUnregister, false,
			(void *)fGPIOID, (void *)getProvider(),
			(void *)&sGPIOEventOccured,	(void *)this) == kIOReturnSuccess)
	{
		fAmRegistered = false;
	}
	else
	{
		DLOG("AppleGPIO::unregisterWithParent failed to unregister\n");
	}

	// release the mutex
	IOLockUnlock(fAmRegisteredLock);
}
Exemple #2
0
bool AppleGPIO::registerWithParent(void)
{
	bool result;

	// grab the mutex
	IOLockLock(fAmRegisteredLock);

	// don't register twice
	if (fAmRegistered)
	{
		DLOG("AppleGPIO::registerWithParent already registered!!\n");
		IOLockUnlock(fAmRegisteredLock);
		return(true);
	}

	// register for notification from parent
	if (fParent->callPlatformFunction(kSymGPIOParentRegister, false,
			(void *)fGPIOID, (void *)getProvider(),
			(void *)&sGPIOEventOccured, (void *)this) == kIOReturnSuccess)
	{
		fAmRegistered = true;
		result = true;
	}
	else
	{
		DLOG("AppleGPIO::registerWithParent registration attempt failed\n");
		result = false;
	}

	// release mutex
	IOLockUnlock(fAmRegisteredLock);
	return(result);
}
void
SCSIPressurePathManager::ExecuteCommand ( SCSITaskIdentifier request )
{
	
	SCSITargetDevicePath *		path		= NULL;
	PortBandwidthGlobals *		bw			= NULL;
	UInt32						numPaths	= 0;
	
	IOLockLock ( fLock );
	
	numPaths = fPathSet->getCount ( );
	
	if ( numPaths == 0 )
	{
		
		IOLockUnlock ( fLock );
		PathTaskCallback ( request );
		return;
		
	}
	
	bw = PortBandwidthGlobals::GetSharedInstance ( );
	path = bw->AllocateBandwidth ( fPathSet, GetRequestedDataTransferCount ( request ) );
	
	IOLockUnlock ( fLock );
	
	SetPathLayerReference ( request, ( void * ) path );
	path->GetInterface ( )->ExecuteCommand ( request );
	
}
errno_t	IOWebFilterClass::tl_data_in_func(void *cookie, socket_t so,
                                          const struct sockaddr *from, mbuf_t *data, mbuf_t *control,
                                          sflt_data_flag_t flags)
{
    SocketTracker *tracker = (SocketTracker*)cookie;

//    __asm__("int3");

    LOG(LOG_DEBUG, "I am in, %s, magic=%ld", tracker->proc_name, tracker->magic);

    if(tracker==NULL || data==NULL || (tracker->magic&(kSocketTrackerInvalid|kSocketTrackerDetach))!=0)
    {
        LOG(LOG_DEBUG, "in return process");
        return 0;
    }
    if(tracker->lock==NULL)
    {
        tracker->magic=kSocketTrackerInvalid;
        return 0;
    }

    IOLockLock(tracker->lock);
    mbuf_t head = *data;
    uint64_t len=0;

    if(head==NULL)
    {
        tracker->magic=kSocketTrackerInvalid;
        IOLockUnlock(tracker->lock);
        return 0;
    }

    while(head)
    {
        len += mbuf_len(head);
        head = mbuf_next(head);
    }

    if(len>sizeof(tracker->request_meg)-1)
    {
        tracker->magic=kSocketTrackerInvalid;
        IOLockUnlock(tracker->lock);
        return 0;
    }
    bzero(tracker->request_meg, sizeof(tracker->request_meg));
    mbuf_copydata(*data, 0, len, tracker->request_meg);

    //todo: sync to shared memory, record a new request
    if(_queue)
    {
        LOG(LOG_DEBUG, "enter queue");
        _queue->EnqueueTracker((DataArgs*)tracker);
    }

    IOLockUnlock(tracker->lock);
    return 0;
}
void
SCSIPressurePathManager::ActivatePath ( IOSCSIProtocolServices * interface )
{
	
	bool					result 	= false;
	SCSITargetDevicePath *	path	= NULL;
	
	STATUS_LOG ( ( "SCSIPressurePathManager::ActivatePath\n" ) );
	
	require_nonzero ( interface, ErrorExit );
	
	IOLockLock ( fLock );
	
	result = fInactivePathSet->member ( interface );
	if ( result == true )
	{
		
		path = fInactivePathSet->getObjectWithInterface ( interface );
		if ( path != NULL )
		{
			
			path->retain ( );
			path->Activate ( );
			fInactivePathSet->removeObject ( interface );
			fPathSet->setObject ( path );
			path->release ( );
			path = NULL;
			
		}
		
	}
	
	else
	{
		
		result = fPathSet->member ( interface );
		if ( result == false )
		{
			
			IOLockUnlock ( fLock );
			AddPath ( interface );
			goto Exit;
			
		}
		
	}
	
	IOLockUnlock ( fLock );
	
	
ErrorExit:
Exit:
	
	
	return;
	
}
void IOHIKeyboard::dispatchKeyboardEvent(unsigned int keyCode,
			 /* direction */ bool         goingDown,
                         /* timeStamp */ AbsoluteTime time)
// Description:	This method is the heart of event dispatching. The overlying
//		subclass invokes this method with each event. We then
//		get the event xlated and dispatched using a _keyMap instance.
//		The event structure passed in by reference should not be freed.
{
    IOHIKeyboardMapper	* theKeyMap;
    KeyboardReserved *tempReservedStruct = GetKeyboardReservedStructEventForService(this); 
	
    IOLockLock( _deviceLock);

    _lastEventTime = time;

    // Post the event to the HID Manager
    if (tempReservedStruct)
    {
        if (tempReservedStruct->keyboardNub )
        {
            tempReservedStruct->keyboardNub->postKeyboardEvent(keyCode, goingDown);
        }
        
        if (tempReservedStruct->isSeized)
        {
            IOLockUnlock( _deviceLock);
            return;
        }
    }


    if (tempReservedStruct) tempReservedStruct->dispatchEventCalled = true;

    if (_keyMap)  _keyMap->translateKeyCode(keyCode,
			  /* direction */ goingDown,
			  /* keyBits */   _keyState);
			  
    // remember the keymap while we hold the lock
    theKeyMap = _keyMap;

    if (tempReservedStruct) tempReservedStruct->dispatchEventCalled = false;
	
    IOLockUnlock( _deviceLock);
	
	// outside the lock (because of possible recursion), give the
	// keymap a chance to do some post processing
	// since it is possible we will be entered reentrantly and 
	// release the keymap, we will add a retain here.
    if (theKeyMap)
	{
		theKeyMap->retain();
		theKeyMap->keyEventPostProcess();
		theKeyMap->release();
	}
}
IOReturn SPFramebuffer::disable() {
    IOLockLock(lock);
    if (!isEnabled) {
        IOLockUnlock(lock);
        return kIOReturnNotOpen;
    }
    isEnabled = false;
    connectChangeInterrupt(this, NULL);
    IOLockUnlock(lock);
    return kIOReturnSuccess;
}
IOReturn IOSharedInterruptController::unregisterInterrupt(IOService *nub,
							  int source)
{
  IOInterruptVectorNumber vectorNumber;
  IOInterruptVector *vector;
  IOInterruptState  interruptState;

  for (vectorNumber = 0; vectorNumber < kIOSharedInterruptControllerDefaultVectors; vectorNumber++) {
    vector = &vectors[vectorNumber];

    // Get the lock for this vector.
    IOLockLock(vector->interruptLock);

    // Return success if it is not already registered
    if (!vector->interruptRegistered
     || (vector->nub != nub) || (vector->source != source)) {
        IOLockUnlock(vector->interruptLock);
        continue;
    }

    // Soft disable the source and the controller too.
    disableInterrupt(nub, source);

    // Clear all the storage for the vector except for interruptLock.
    vector->interruptActive = 0;
    vector->interruptDisabledSoft = 0;
    vector->interruptDisabledHard = 0;
    vector->interruptRegistered = 0;
    vector->nub = 0;
    vector->source = 0;
    vector->handler = 0;
    vector->target = 0;
    vector->refCon = 0;

    interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
    vectorsRegistered--;
    IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);

    // Move along to the next one.
    IOLockUnlock(vector->interruptLock);
  }

  // Re-enable the controller if all vectors are enabled.
  if (vectorsEnabled == vectorsRegistered) {
    controllerDisabled = 0;
    provider->enableInterrupt(0);
  }

  return kIOReturnSuccess;
}
 static void free(IOLock*& lock) {
   IOLockLock(lock);
   IOLock* tmplock = lock;
   lock = NULL;
   IOLockUnlock(tmplock);
   IOLockFree(tmplock);
 }
Exemple #10
0
/*********************************************************************
* Is personality already in the catalog?
*********************************************************************/
OSOrderedSet *
IOCatalogue::findDrivers(
    OSDictionary * matching,
    SInt32 * generationCount)
{
    OSDictionary         * dict;
    OSOrderedSet         * set;

    UniqueProperties(matching);

    set = OSOrderedSet::withCapacity( 1, IOServiceOrdering,
                                      (void *)gIOProbeScoreKey );

    IOLockLock(lock);
    kernelTables->reset();
    while ( (dict = (OSDictionary *) kernelTables->getNextObject()) ) {

        /* This comparison must be done with only the keys in the
         * "matching" dict to enable general searches.
         */
        if ( dict->isEqualTo(matching, matching) )
            set->setObject(dict);
    }
    *generationCount = getGenerationCount();
    IOLockUnlock(lock);

    return set;
}
void IOHIKeyboard::free()
// Description:	Go Away. Be careful when freeing the lock.
{
    IOLock * lock = NULL;

    if ( _deviceLock )
    {
      lock = _deviceLock;
      IOLockLock( lock);
      _deviceLock = NULL;
    }

    if ( _keyMap ) {
        _keyMap->release();
    }

    if( _keyState )
        IOFree( _keyState, _keyStateSize);

    // RY: MENTAL NOTE Do this last
    if ( lock )
    {
      IOLockUnlock( lock);
      IOLockFree( lock);
    }
    
    super::free();
}
void IOAccelerationUserClient::stop( IOService * provider )
{
    IOAccelIDRecord * record;

    IOLockLock(gLock);

    while (!queue_empty( &fTaskList ))
    {
        queue_remove_first( &fTaskList,
                            record,
                            IOAccelIDRecord *,
                            task_link );

        if (--record->retain)
            record->task_link.next = 0;
        else
        {
            queue_remove(&gGlobalList,
                            record,
                            IOAccelIDRecord *,
                            glob_link);
            gTotalCount--;
            IODelete(record, IOAccelIDRecord, 1);
        }
    }
    IOLockUnlock(gLock);

    super::stop( provider );
}
void
IOFWUserAsyncStreamListener::deactivate()
{
	IOFWAsyncStreamListener::TurnOffNotification() ;
	
	IOLockLock(fLock) ;
	
	fBufferAvailable = 0 ;	// zzz do we need locking here to protect our data?
	fLastReadHeader = NULL ;	
	
	IOFWPacketHeader*	firstHeader = fLastWrittenHeader ;
	IOFWPacketHeader*	tempHeader ;

	if (fLastWrittenHeader)
	{
		while (fLastWrittenHeader->CommonHeader.next != firstHeader)
		{
			tempHeader = fLastWrittenHeader->CommonHeader.next ;
			delete fLastWrittenHeader ;
			fLastWrittenHeader = tempHeader ;	
		}
	
	}
		
	fWaitingForUserCompletion = false ;
	
	IOLockUnlock(fLock) ;
}
Exemple #14
0
int
Rules::DeactivateRule(UInt32 ruleId)
{
    int result = -1;

    IOLockLock(lock);
    Rule* workRule = this->root;
    while (workRule)
    {
        if(workRule->id == ruleId)
        {
            if(workRule->state == RuleStateInactive)
            {
                workRule->state = RuleStateActive;
                clock_get_uptime(&lastChangedTime);
                result = 0;
            }
            else
            {
                result = 1;//alredy inactive
            }
            break;
        }

        workRule = workRule->next;
    }

    IOLockUnlock(lock);
    return result;
}
Exemple #15
0
/******************************************************************************
 * ACPIDebug::PrintTraces
 ******************************************************************************/
void ACPIDebug::PrintTraces()
{
    IOLockLock(m_pLock);

    for (;;)
    {
        // see if there are any trace items in the RING
        UInt32 count = 0;
        if (kIOReturnSuccess != m_pDevice->evaluateInteger("COUN", &count))
        {
            IOLog("ACPIDebug: evaluateObject of COUN method failed\n");
            break;
            
        }
        if (!count)
            break;
        
        // gather the next item from RING and print it
        OSObject* debug;
        if (kIOReturnSuccess == m_pDevice->evaluateObject("FTCH", &debug) &&
            NULL != debug)
        {
            static char buf[2048];
            // got a valid object, format and print it...
            FormatDebugString(debug, buf, sizeof(buf)/sizeof(buf[0]));
            IOLog("ACPIDebug: %s\n", buf);
            debug->release();
        }
    }

    IOLockUnlock(m_pLock);
}
void BrcmPatchRAM::scheduleWork(unsigned int newWork)
{
    IOLockLock(mWorkLock);
    mWorkPending |= newWork;
    mWorkSource->interruptOccurred(0, 0, 0);
    IOLockUnlock(mWorkLock);
}
void BrcmPatchRAM::processWorkQueue(IOInterruptEventSource*, int)
{
    IOLockLock(mWorkLock);

    // start firmware loading process in a non-workloop thread
    if (mWorkPending & kWorkLoadFirmware)
    {
        DebugLog("_workPending kWorkLoadFirmare\n");
        mWorkPending &= ~kWorkLoadFirmware;
        retain();
        kern_return_t result = kernel_thread_start(&BrcmPatchRAM::uploadFirmwareThread, this, &mWorker);
        if (KERN_SUCCESS == result)
            DebugLog("Success creating firmware uploader thread\n");
        else
        {
            AlwaysLog("ERROR creating firmware uploader thread.\n");
            release();
        }
    }

    // firmware loading thread is finished
    if (mWorkPending & kWorkFinished)
    {
        DebugLog("_workPending kWorkFinished\n");
        mWorkPending &= ~kWorkFinished;
        thread_deallocate(mWorker);
        mWorker = 0;
        release();  // matching retain when thread created successfully
    }

    IOLockUnlock(mWorkLock);
}
Exemple #18
0
/* static */
void
OSMetaClass::printInstanceCounts()
{
    OSCollectionIterator * classes;
    OSSymbol             * className;
    OSMetaClass          * meta;

    IOLockLock(sAllClassesLock);
    classes = OSCollectionIterator::withCollection(sAllClassesDict);
    assert(classes);

    while( (className = (OSSymbol *)classes->getNextObject())) {
        meta = (OSMetaClass *)sAllClassesDict->getObject(className);
        assert(meta);

        printf("%24s count: %03d x 0x%03x = 0x%06x\n",
            className->getCStringNoCopy(),
            meta->getInstanceCount(),
            meta->getClassSize(),
            meta->getInstanceCount() * meta->getClassSize() );
    }
    printf("\n");
    classes->release();
    IOLockUnlock(sAllClassesLock);
    return;
}
Exemple #19
0
  // ------------------------------------------------------------
  GlobalLock::ScopedUnlock::ScopedUnlock(void)
  {
    lock_ = GlobalLock::lock_;
    if (! lock_) return;

    IOLockUnlock(lock_);
  }
Exemple #20
0
IOReturn I2CUserClient::userClientClose(void)
{
	IOReturn	ret = kIOReturnSuccess;

	DLOG("+I2CUserClient::userClientClose\n");

	// preliminary sanity check
	if (!fIsOpen)
	{
		// haven't been opened ?!
		return(kIOReturnError);
	}

	// grab the mutex
	IOLockLock(fIsOpenLock);

	// now that we hold the mutex, check again
	if (fIsOpen)
	{
		fIsOpen = false;
		ret = kIOReturnSuccess;
	}
	else
	{
		ret = kIOReturnError;
	}

	IOLockUnlock(fIsOpenLock);
	return(ret);
}
bool DldIODataQueue::waitForData()
{
    
    assert( preemption_enabled() );
    
    bool wait;
    
    IOLockLock( this->lock );
    {// start of the lock
        
        //
        // wait if the queue is empty
        //
        wait = ( this->dataQueue->head == this->dataQueue->tail );

        if( wait && THREAD_WAITING != assert_wait( this->dataQueue, THREAD_UNINT ) )
            wait = false;
        
    }// end of the lock
    IOLockUnlock( this->lock );
    
    if( wait )
        thread_block( THREAD_CONTINUE_NULL );
    
    return true;
}
Exemple #22
0
IOReturn I2CUserClient::userClientOpen(void)
{
	IOReturn	ret = kIOReturnSuccess;

	DLOG("+I2CUserClient::userClientOpen\n");

	// We do not enforce exclusive access to our provider (the actual
	// I2C interface), but we do enforce that our user-land client app
	// use open/close semantics when communicating with this user client
	// object.

	// preliminary sanity check
	if (fIsOpen)
	{
		// already open ?!
		return(kIOReturnError);
	}

	// grab the mutex
	IOLockLock(fIsOpenLock);

	// now that we hold the mutex, check again
	if (!fIsOpen)
	{
		fIsOpen = true;
		ret = kIOReturnSuccess;
	}
	else
	{
		ret = kIOReturnError;
	}

	IOLockUnlock(fIsOpenLock);
	return(ret);
}
Exemple #23
0
/* wait for the pet thread to finish a run */
void
kperf_pet_thread_wait(void)
{
	/* acquire the lock to ensure the thread is parked. */
	IOLockLock(pet_lock);
	IOLockUnlock(pet_lock);
}
Exemple #24
0
/* sleep indefinitely */
static void 
pet_idle(void)
{
	IOLockLock(pet_lock);
	IOLockSleep(pet_lock, &pet_actionid, THREAD_UNINT);
	IOLockUnlock(pet_lock);
}
void IOHIKeyboard::keyboardEvent(unsigned eventType,
	/* flags */              unsigned flags,
	/* keyCode */            unsigned keyCode,
	/* charCode */           unsigned charCode,
	/* charSet */            unsigned charSet,
	/* originalCharCode */   unsigned origCharCode,
	/* originalCharSet */    unsigned origCharSet)
// Description: We use this notification to set up our _keyRepeat timer
//		and to pass along the event to our owner. This method
//		will be called while the KeyMap object is processing
//		the key code we've sent it using deliverKey.
{
    KeyboardReserved *tempReservedStruct = GetKeyboardReservedStructEventForService(this); 
    
    if (tempReservedStruct && tempReservedStruct->dispatchEventCalled) 
    {
        IOLockUnlock(_deviceLock);
    }

    _keyboardEvent(	   this,
                           eventType,
    /* flags */            flags,
    /* keyCode */          keyCode,
    /* charCode */         charCode,
    /* charSet */          charSet,
    /* originalCharCode */ origCharCode,
    /* originalCharSet */  origCharSet,
    /* keyboardType */     _deviceType,
    /* repeat */           _isRepeat,
    /* atTime */           _lastEventTime);

    if (tempReservedStruct && tempReservedStruct->dispatchEventCalled) 
    {
        IOLockLock(_deviceLock);
    }


    if( keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_CAPS_LOCK) ||
        keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_NUM_LOCK) ||
        keyCode == _keyMap->getParsedSpecialKey(NX_POWER_KEY) ||
        keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_MUTE) ||
        keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_PLAY) ||
        keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_EJECT) ||
        keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_VIDMIRROR) ||
        keyCode == _keyMap->getParsedSpecialKey(NX_KEYTYPE_ILLUMINATION_TOGGLE))  
    {		
		//Don't repeat caps lock on ADB/USB.  0x39 is default ADB code.
		//    We are here because KeyCaps needs to see 0x39 as a real key,
		//    not just another modifier bit.

		if (_interfaceType == NX_EVS_DEVICE_INTERFACE_ADB)
		{
			return;
		}
    }

    // Set up key repeat operations here.
    setRepeat(eventType, keyCode);
}
SCSITargetDevicePath *
SCSIPressurePathManager::PortBandwidthGlobals::AllocateBandwidth (
						SCSIPathSet *	pathSet,
						UInt64			bytes )
{
	
	SCSITargetDevicePath *		path		= NULL;
	SCSITargetDevicePath *		result		= NULL;
	UInt32						numPaths	= 0;
	UInt32						index		= 0;
	UInt32						resultIndex	= 0;
	UInt64						bandwidth	= 0xFFFFFFFFFFFFFFFFULL;
	
	STATUS_LOG ( ( "+PortBandwidthGlobals::AllocateBandwidth\n" ) );
	
	// Grab the lock since we'll end up manipulating the table.
	IOLockLock ( fLock );
	
	// Assume we're using the first path.
	result 		= pathSet->getObject ( index );
	numPaths	= pathSet->getCount ( );
	
	// Loop over the passed in possible paths.
	for ( index = 0; index < numPaths; index++ )
	{
		
		UInt32	domainID = 0;
		
		STATUS_LOG ( ( "Getting a path at index = %ld\n", index ) );
		
		path = pathSet->getObject ( index );
		
		domainID = path->GetDomainIdentifier ( )->unsigned32BitValue ( );
		
		// Sanity check
		//check ( domainID < fCapacity );
		
		if ( fListHead[domainID] < bandwidth )
		{
			
			result 		= path;
			bandwidth 	= fListHead[domainID];
			resultIndex	= domainID;
			
		}
		
	}
	
	// Whichever path we chose, charge it with the bandwidth.
	fListHead[resultIndex] += bytes;
	
	// Done manipulating the table. Drop the lock.
	IOLockUnlock ( fLock );
	
	STATUS_LOG ( ( "-PortBandwidthGlobals::AllocateBandwidth\n" ) );
	
	return result;
	
}
void EMUUSBInputStream::GatherInputSamples() {
    
    debugIOLogRD("+GatherInputSamples %d", bufferOffset / multFactor);

    IOLockLock(mLock);
    while (gatherFromReadList() == kIOReturnSuccess);
    IOLockUnlock(mLock);
}
Exemple #28
0
IOReturn IOCatalogue::terminateDriversForModule(
    OSString * moduleName,
    bool unload)
{
    IOReturn ret;
    OSDictionary * dict;
    bool isLoaded = false;

    /* Check first if the kext currently has any linkage dependents;
     * in such a case the unload would fail so let's not terminate any
     * IOServices (since doing so typically results in a panic when there
     * are loaded dependencies). Note that we aren't locking the kext here
     * so it might lose or gain dependents by the time we call unloadModule();
     * I think that's ok, our unload can fail if a kext comes in on top of
     * this one even after we've torn down IOService objects. Conversely,
     * if we fail the unload here and then lose a library, the autounload
     * thread will get us in short order.
     */
    if (OSKext::isKextWithIdentifierLoaded(moduleName->getCStringNoCopy())) {

        isLoaded = true;

        if (!OSKext::canUnloadKextWithIdentifier(moduleName,
                /* checkClasses */ false)) {
            ret = kOSKextReturnInUse;
            goto finish;
        }
    }
    dict = OSDictionary::withCapacity(1);
    if (!dict) {
        ret = kIOReturnNoMemory;
        goto finish;
    }

    dict->setObject(gIOModuleIdentifierKey, moduleName);

    ret = _terminateDrivers(dict);

    /* No goto between IOLock calls!
     */
    IOLockLock(lock);
    if (kIOReturnSuccess == ret) {
        ret = _removeDrivers(array, dict);
    }
    kernelTables->reset();

    // Unload the module itself.
    if (unload && isLoaded && ret == kIOReturnSuccess) {
        ret = unloadModule(moduleName);
    }

    IOLockUnlock(lock);

    dict->release();

finish:
    return ret;
}
//
// false is returned when there are no entries left,
// the header of the retrurned enrty must not be changed
// and the entry must be provided as a parameter for 
// dequeueEntry when the entry is no longer needed
//
bool DldIODataQueue::dequeueDataInPlace( __out DldIODataQueueEntry** inPlaceEntry )
{
    DldIODataQueueEntry *  entry           = 0;
    
    assert( dataQueue );
    
    IOLockLock( this->lock );
    {// start of the lock
        
        UInt32                 newHeadOffset = 0;

        
        if( dataQueue->validDataHead != dataQueue->validDataTail ){
            
            DldIODataQueueEntry*   head;
            UInt32                 headOffset;
            
            headOffset = dataQueue->validDataHead;
            head = (DldIODataQueueEntry *)((char *)dataQueue->queue + headOffset);
            
            //
            // we wraped around to beginning, so read from there
            // either there was not even room for the header
            //
            if( (dataQueue->head +  DLD_DATA_QUEUE_ENTRY_HEADER_SIZE > dataQueue->queueSize) ||
               // or there was room for the header, but not for the data
               ((dataQueue->head + head->dataSize + DLD_DATA_QUEUE_ENTRY_HEADER_SIZE) > dataQueue->queueSize)) {
                
                entry = dataQueue->queue;
                newHeadOffset = entry->dataSize + DLD_DATA_QUEUE_ENTRY_HEADER_SIZE;
                // else it is at the end
                
            } else {
                
                entry = head;
                newHeadOffset = headOffset + entry->dataSize + DLD_DATA_QUEUE_ENTRY_HEADER_SIZE;
            }
            
        }// else if( dataQueue->validDataHead != dataQueue->validDataTail )
        

        if (entry) {
            
            assert( DLD_QUEUE_SIGNATURE == entry->signature );
            assert( false == entry->intermediate );
            
            *inPlaceEntry = entry;
            dataQueue->validDataHead = newHeadOffset;
            
        }
        
    }// end of the lock
    IOLockUnlock( this->lock );
    
    return ( NULL != entry );
}
void IOHIDEventQueue::setOptions(IOHIDQueueOptionsType flags) 
{
    if ( _lock )
        IOLockLock(_lock);

	_options = flags;

    if ( _lock )
        IOLockUnlock(_lock);
}