*
* @APPLE_LICENSE_HEADER_START@
*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
*
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
-/*
- * Copyright (c) 1991-1999 Apple Computer, Inc. All rights reserved.
- *
- * HISTORY
- *
- * 29-Jan-91 Portions from IODevice.m, Doug Mitchell at NeXT, Created.
- * 18-Jun-98 start IOKit objc
- * 10-Nov-98 start iokit cpp
- * 25-Feb-99 sdouglas, add threads and locks to ensure deadlock
- *
- */
#include <IOKit/system.h>
#include <IOKit/IOPlatformExpert.h>
#include <IOKit/IOMessage.h>
#include <IOKit/IOLib.h>
-#include <IOKit/IOKitKeys.h>
+#include <IOKit/IOKitKeysPrivate.h>
#include <IOKit/IOBSD.h>
#include <IOKit/IOUserClient.h>
#include <IOKit/IOWorkLoop.h>
const OSSymbol * gIOCommandPoolSizeKey;
+const OSSymbol * gIOConsoleUsersKey;
+const OSSymbol * gIOConsoleSessionUIDKey;
+const OSSymbol * gIOConsoleUsersSeedKey;
+
static int gIOResourceGenerationCount;
const OSSymbol * gIOServiceKey;
static OSArray * gIOStopProviderList;
static OSArray * gIOFinalizeList;
+static SInt32 gIOConsoleUsersSeed;
+static OSData * gIOConsoleUsersSeedValue;
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#define LOCKREADNOTIFY() \
kIOTerminatedNotification );
gIOServiceKey = OSSymbol::withCStringNoCopy( kIOServiceClass);
+ gIOConsoleUsersKey = OSSymbol::withCStringNoCopy( kIOConsoleUsersKey);
+ gIOConsoleSessionUIDKey = OSSymbol::withCStringNoCopy( kIOConsoleSessionUIDKey);
+ gIOConsoleUsersSeedKey = OSSymbol::withCStringNoCopy( kIOConsoleUsersSeedKey);
+ gIOConsoleUsersSeedValue = OSData::withBytesNoCopy(&gIOConsoleUsersSeed, sizeof(gIOConsoleUsersSeed));
+
gNotificationLock = IORecursiveLockAlloc();
assert( gIOServicePlane && gIODeviceMemoryKey
&& gIOProviderClassKey && gIONameMatchKey && gIONameMatchedKey
&& gIOMatchCategoryKey && gIODefaultMatchCategoryKey
&& gIOPublishNotification && gIOMatchedNotification
- && gIOTerminatedNotification && gIOServiceKey );
+ && gIOTerminatedNotification && gIOServiceKey
+ && gIOConsoleUsersKey && gIOConsoleSessionUIDKey
+ && gIOConsoleUsersSeedKey && gIOConsoleUsersSeedValue);
gJobsLock = IOLockAlloc();
gJobs = OSOrderedSet::withCapacity( 10 );
* Register instance - publish it for matching
*/
-void IOService::registerService( IOOptionBits options = 0 )
+void IOService::registerService( IOOptionBits options )
{
char * pathBuf;
const char * path;
startMatching( options );
}
-void IOService::startMatching( IOOptionBits options = 0 )
+void IOService::startMatching( IOOptionBits options )
{
IOService * provider;
UInt32 prevBusy = 0;
}
_IOServiceJob * _IOServiceJob::startJob( IOService * nub, int type,
- IOOptionBits options = 0 )
+ IOOptionBits options )
{
_IOServiceJob * job;
* Stacking change
*/
-bool IOService::lockForArbitration( bool isSuccessRequired = true )
+bool IOService::lockForArbitration( bool isSuccessRequired )
{
bool found;
bool success;
// send a message to a client or interested party of this service
IOReturn IOService::messageClient( UInt32 type, OSObject * client,
- void * argument = 0, vm_size_t argSize = 0 )
+ void * argument, vm_size_t argSize )
{
IOReturn ret;
IOService * service;
UNLOCKNOTIFY();
if( copyArray) {
for( index = 0;
- (next = array->getObject( index ));
+ (next = copyArray->getObject( index ));
index++) {
(*applier)(next, context);
}
// send a message to all clients
IOReturn IOService::messageClients( UInt32 type,
- void * argument = 0, vm_size_t argSize = 0 )
+ void * argument, vm_size_t argSize )
{
MessageClientsContext context;
return( ok );
}
-bool IOService::terminatePhase1( IOOptionBits options = 0 )
+bool IOService::terminatePhase1( IOOptionBits options )
{
IOService * victim;
IOService * client;
return( true );
}
-void IOService::scheduleTerminatePhase2( IOOptionBits options = 0 )
+void IOService::scheduleTerminatePhase2( IOOptionBits options )
{
AbsoluteTime deadline;
int waitResult;
gIOTerminateWork++;
do {
- terminateWorker( options );
+ while( gIOTerminateWork )
+ terminateWorker( options );
wait = (0 != (__state[1] & kIOServiceBusyStateMask));
if( wait) {
// wait for the victim to go non-busy
} else
thread_cancel_timer();
}
- } while( wait && (waitResult != THREAD_TIMED_OUT));
+ } while(gIOTerminateWork || (wait && (waitResult != THREAD_TIMED_OUT)));
- gIOTerminateThread = 0;
- IOLockWakeup( gJobsLock, (event_t) &gIOTerminateThread, /* one-thread */ false);
+ gIOTerminateThread = 0;
+ IOLockWakeup( gJobsLock, (event_t) &gIOTerminateThread, /* one-thread */ false);
} else {
// ! kIOServiceSynchronous
gIOTerminatePhase2List->setObject( this );
- if( 0 == gIOTerminateWork++)
- gIOTerminateThread = IOCreateThread( &terminateThread, (void *) options );
+ if( 0 == gIOTerminateWork++) {
+ if( !gIOTerminateThread)
+ gIOTerminateThread = IOCreateThread( &terminateThread, (void *) options );
+ else
+ IOLockWakeup(gJobsLock, (event_t) &gIOTerminateWork, /* one-thread */ false );
+ }
}
IOLockUnlock( gJobsLock );
{
IOLockLock( gJobsLock );
- terminateWorker( (IOOptionBits) arg );
+ while (gIOTerminateWork)
+ terminateWorker( (IOOptionBits) arg );
gIOTerminateThread = 0;
IOLockWakeup( gJobsLock, (event_t) &gIOTerminateThread, /* one-thread */ false);
return( true );
}
-#undef tailQ(o)
-#undef headQ(o)
+#undef tailQ
+#undef headQ
/*
* Terminate
return( ok );
}
-bool IOService::terminate( IOOptionBits options = 0 )
+bool IOService::terminate( IOOptionBits options )
{
options |= kIOServiceTerminate;
}
bool IOService::open( IOService * forClient,
- IOOptionBits options = 0,
- void * arg = 0 )
+ IOOptionBits options,
+ void * arg )
{
bool ok;
ServiceOpenMessageContext context;
}
void IOService::close( IOService * forClient,
- IOOptionBits options = 0 )
+ IOOptionBits options )
{
bool wasClosed;
bool last = false;
}
}
-bool IOService::isOpen( const IOService * forClient = 0 ) const
+bool IOService::isOpen( const IOService * forClient ) const
{
IOService * self = (IOService *) this;
bool ok;
checkResources();
// stall for any driver resources
service->checkResources();
+
+ AbsoluteTime startTime;
+ AbsoluteTime endTime;
+ UInt64 nano;
+
+ if (kIOLogStart & gIOKitDebug)
+ clock_get_uptime(&startTime);
+ ok = service->start(this);
- ok = service->start( this );
+ if (kIOLogStart & gIOKitDebug)
+ {
+ clock_get_uptime(&endTime);
+
+ if (CMP_ABSOLUTETIME(&endTime, &startTime) > 0)
+ {
+ SUB_ABSOLUTETIME(&endTime, &startTime);
+ absolutetime_to_nanoseconds(endTime, &nano);
+ if (nano > 500000000ULL)
+ IOLog("%s::start took %ld ms\n", service->getName(), (UInt32)(nano / 1000000ULL));
+ }
+ }
if( !ok)
service->detach( this );
}
return( gIOResources );
}
-void IOService::publishResource( const char * key, OSObject * value = 0 )
+void IOService::publishResource( const char * key, OSObject * value )
{
const OSSymbol * sym;
}
}
-void IOService::publishResource( const OSSymbol * key, OSObject * value = 0 )
+void IOService::publishResource( const OSSymbol * key, OSObject * value )
{
if( 0 == value)
value = (OSObject *) gIOServiceKey;
gIOResources->setProperty( key, value);
+ if( IORecursiveLockHaveLock( gNotificationLock))
+ return;
+
gIOResourceGenerationCount++;
gIOResources->registerService();
}
}
IOReturn IOService::waitForState( UInt32 mask, UInt32 value,
- mach_timespec_t * timeout = 0 )
+ mach_timespec_t * timeout )
{
bool wait;
int waitResult = THREAD_AWAKENED;
return( kIOReturnSuccess );
}
-IOReturn IOService::waitQuiet( mach_timespec_t * timeout = 0 )
+IOReturn IOService::waitQuiet( mach_timespec_t * timeout )
{
return( waitForState( kIOServiceBusyStateMask, 0, timeout ));
}
// internal - call with gNotificationLock
OSObject * IOService::getExistingServices( OSDictionary * matching,
- IOOptionBits inState, IOOptionBits options = 0 )
+ IOOptionBits inState, IOOptionBits options )
{
OSObject * current = 0;
OSIterator * iter;
((OSSet *)current)->setObject( service );
else
current = OSSet::withObjects(
- & (const OSObject *) service, 1, 1 );
+ (const OSObject **) &service, 1, 1 );
}
}
} while( !service && !iter->isValid());
IONotifier * IOService::setNotification(
const OSSymbol * type, OSDictionary * matching,
IOServiceNotificationHandler handler, void * target, void * ref,
- SInt32 priority = 0 )
+ SInt32 priority )
{
_IOServiceNotifier * notify = 0;
OSOrderedSet * set;
IONotifier * IOService::addNotification(
const OSSymbol * type, OSDictionary * matching,
IOServiceNotificationHandler handler,
- void * target, void * ref = 0,
- SInt32 priority = 0 )
+ void * target, void * ref,
+ SInt32 priority )
{
OSIterator * existing;
_IOServiceNotifier * notify;
}
IOService * IOService::waitForService( OSDictionary * matching,
- mach_timespec_t * timeout = 0 )
+ mach_timespec_t * timeout )
{
IONotifier * notify = 0;
// priority doesn't help us much since we need a thread wakeup
*/
OSDictionary * IOService::serviceMatching( const OSString * name,
- OSDictionary * table = 0 )
+ OSDictionary * table )
{
if( !table)
table = OSDictionary::withCapacity( 2 );
}
OSDictionary * IOService::serviceMatching( const char * name,
- OSDictionary * table = 0 )
+ OSDictionary * table )
{
const OSString * str;
}
OSDictionary * IOService::nameMatching( const OSString * name,
- OSDictionary * table = 0 )
+ OSDictionary * table )
{
if( !table)
table = OSDictionary::withCapacity( 2 );
}
OSDictionary * IOService::nameMatching( const char * name,
- OSDictionary * table = 0 )
+ OSDictionary * table )
{
const OSString * str;
}
OSDictionary * IOService::resourceMatching( const OSString * str,
- OSDictionary * table = 0 )
+ OSDictionary * table )
{
table = serviceMatching( gIOResourcesKey, table );
if( table)
}
OSDictionary * IOService::resourceMatching( const char * name,
- OSDictionary * table = 0 )
+ OSDictionary * table )
{
const OSSymbol * str;
return( kIOReturnBadArgument);
while( (key = OSDynamicCast(OSSymbol, iter->getNextObject()))) {
+
+ if (gIOConsoleUsersKey == key)
+ {
+ IORegistryEntry::getRegistryRoot()->setProperty(key, dict->getObject(key));
+ OSIncrementAtomic( &gIOConsoleUsersSeed );
+ publishResource( gIOConsoleUsersSeedKey, gIOConsoleUsersSeedValue );
+ continue;
+ }
+
publishResource( key, dict->getObject(key) );
}
}
IOMemoryMap * IOService::mapDeviceMemoryWithIndex( unsigned int index,
- IOOptionBits options = 0 )
+ IOOptionBits options )
{
IODeviceMemory * range;
IOMemoryMap * map;