#define registryTable() fPropertyTable
#endif
+#define DEBUG_FREE 1
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct s_lock_t {
WLOCK;
fPropertyTable = old->getPropertyTable();
- old->fPropertyTable = 0;
+ fPropertyTable->retain();
#ifdef IOREGSPLITTABLES
fRegistryTable = old->fRegistryTable;
- old->fRegistryTable = 0;
+ old->fRegistryTable = OSDictionary::withDictionary( fRegistryTable );
#endif /* IOREGSPLITTABLES */
+ old->registryTable()->removeObject( plane->keys[ kParentSetIndex ] );
+ old->registryTable()->removeObject( plane->keys[ kChildSetIndex ] );
+
all = getParentSetReference( plane );
if( all) for( index = 0;
(next = (IORegistryEntry *) all->getObject(index));
void IORegistryEntry::free( void )
{
-#ifdef DEBUG
- OSArray * links;
- const OSSymbol * key;
- const IORegistryPlane * plane;
- OSCollectionIterator * iter;
-
- if( registryTable()) {
- iter = OSCollectionIterator::withCollection( gIORegistryPlanes );
- if( iter) {
- while( (key = (const OSSymbol *) iter->getNextObject())) {
- if( 0 == (plane = (const IORegistryPlane *)
- OSDynamicCast( IORegistryPlane,
- gIORegistryPlanes->getObject( key ))))
- continue;
- if( (links = getParentSetReference( plane ))
- || (links = getChildSetReference( plane )) ) {
-
- IOLog("%s: Still attached in %s at free()\n",
- getName(), plane->nameKey->getCStringNoCopy());
- }
- }
- iter->release();
+#if DEBUG_FREE
+#define msg ": attached at free()"
+ char buf[ strlen(msg) + 40 ];
+
+ if( registryTable() && gIOServicePlane) {
+ if( getParentSetReference( gIOServicePlane )
+ || getChildSetReference( gIOServicePlane )) {
+
+ strncpy( buf, getName(), 32);
+ buf[32] = 0;
+ strcat( buf, msg );
+ IOPanic( buf );
}
}
#endif
{ \
OSObject * obj = getProperty( aKey ); \
\
- if ( (0 == obj) && (options & kIORegistryIterateRecursively) ) { \
+ if ( (0 == obj) && plane && (options & kIORegistryIterateRecursively) ) { \
IORegistryEntry * entry = (IORegistryEntry *) this; \
IORegistryIterator * iter; \
iter = IORegistryIterator::iterateOver( entry, plane, options ); \
\
- while ( (0 == obj) && (entry = iter->getNextObject()) ) { \
- obj = entry->getProperty( aKey ); \
+ if(iter) { \
+ while ( (0 == obj) && (entry = iter->getNextObject()) ) { \
+ obj = entry->getProperty( aKey ); \
+ } \
+ iter->release(); \
+ } \
+ } \
+ \
+ return( obj ); \
+}
+
+#define wrap5(type,constant) \
+OSObject * \
+IORegistryEntry::copyProperty( type * aKey, \
+ const IORegistryPlane * plane, \
+ IOOptionBits options ) constant \
+{ \
+ OSObject * obj = copyProperty( aKey ); \
+ \
+ if ( (0 == obj) && plane && (options & kIORegistryIterateRecursively) ) { \
+ IORegistryEntry * entry = (IORegistryEntry *) this; \
+ IORegistryIterator * iter; \
+ iter = IORegistryIterator::iterateOver( entry, plane, options ); \
+ \
+ if(iter) { \
+ while ( (0 == obj) && (entry = iter->getNextObject()) ) { \
+ obj = entry->copyProperty( aKey ); \
+ } \
+ iter->release(); \
} \
- iter->release(); \
} \
\
return( obj ); \
wrap4(const OSString, const) // getProperty() w/plane definition
wrap4(const char, const) // getProperty() w/plane definition
+wrap5(const OSSymbol, const) // copyProperty() w/plane definition
+wrap5(const OSString, const) // copyProperty() w/plane definition
+wrap5(const char, const) // copyProperty() w/plane definition
+
+
bool
IORegistryEntry::setProperty( const OSSymbol * aKey, OSObject * anObject)
{
{
const char * str;
const char * result = 0;
- int num1, num2;
+ u_quad_t num1, num2;
char c1, c2;
str = getLocation( plane );
if( str) {
c2 = str[0];
do {
- num1 = strtoul( cmp, (char **) &cmp, 16 );
+ num1 = strtouq( cmp, (char **) &cmp, 16 );
if( c2) {
- num2 = strtoul( str, (char **) &str, 16 );
+ num2 = strtouq( str, (char **) &str, 16 );
c2 = str[0];
} else
num2 = 0;
unsigned int index;
const char * path;
const char * cmp = 0;
+ char c;
size_t len;
const char * str;
if( strncmp( str, cmp, len ))
continue;
cmp += len;
- if( *cmp != '@' )
- break;
+
+ c = *cmp;
+ if( (c == 0) || (c == '/') || (c == ':'))
+ break;
+ if( c != '@')
+ continue;
}
cmp++;
if( (cmp = entry->matchPathLocation( cmp, plane )))
return( iter );
}
-IORegistryEntry * IORegistryEntry::getParentEntry( const IORegistryPlane * plane ) const
+IORegistryEntry * IORegistryEntry::copyParentEntry( const IORegistryPlane * plane ) const
{
IORegistryEntry * entry = 0;
OSArray * links;
RLOCK;
- if( (links = getParentSetReference( plane )))
+ if( (links = getParentSetReference( plane ))) {
entry = (IORegistryEntry *) links->getObject( 0 );
+ entry->retain();
+ }
UNLOCK;
return( entry);
}
+IORegistryEntry * IORegistryEntry::getParentEntry( const IORegistryPlane * plane ) const
+{
+ IORegistryEntry * entry;
+
+ entry = copyParentEntry( plane );
+ if( entry)
+ entry->release();
+
+ return( entry );
+}
+
OSArray * IORegistryEntry::getChildSetReference( const IORegistryPlane * plane ) const
{
if( plane)
}
-IORegistryEntry * IORegistryEntry::getChildEntry(
+IORegistryEntry * IORegistryEntry::copyChildEntry(
const IORegistryPlane * plane ) const
{
IORegistryEntry * entry = 0;
RLOCK;
- if( (links = getChildSetReference( plane )))
+ if( (links = getChildSetReference( plane ))) {
entry = (IORegistryEntry *) links->getObject( 0 );
+ entry->retain();
+ }
UNLOCK;
return( entry);
}
+IORegistryEntry * IORegistryEntry::getChildEntry(
+ const IORegistryPlane * plane ) const
+{
+ IORegistryEntry * entry;
+
+ entry = copyChildEntry( plane );
+ if( entry)
+ entry->release();
+
+ return( entry );
+}
+
void IORegistryEntry::applyToChildren( IORegistryEntryApplierFunction applier,
void * context,
const IORegistryPlane * plane ) const
OSDefineMetaClassAndStructors(IORegistryIterator, OSIterator)
+enum { kIORegistryIteratorInvalidFlag = 0x80000000 };
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
IORegistryIterator *
create->where = &create->start;
create->start.current = root;
create->plane = plane;
- create->options = options;
+ create->options = options & ~kIORegistryIteratorInvalidFlag;
} else {
create->release();
bool ok;
IORegCursor * next;
- ok = true;
next = where;
RLOCK;
+
+ ok = (0 == (kIORegistryIteratorInvalidFlag & options));
+
while( ok && next) {
if( where->iter)
ok = where->iter->isValid();
}
where->current = root;
+ options &= ~kIORegistryIteratorInvalidFlag;
}
void IORegistryIterator::free( void )
if( where->current)
where->current->release();
- if( where->iter)
+ if( where->iter) {
+
next = (IORegistryEntry *) where->iter->getNextObject();
- if( next)
- next->retain();
+ if( next)
+ next->retain();
+ else if( !where->iter->isValid())
+ options |= kIORegistryIteratorInvalidFlag;
+ }
where->current = next;
return( done);
}
-OSMetaClassDefineReservedUnused(IORegistryEntry, 0);
-OSMetaClassDefineReservedUnused(IORegistryEntry, 1);
-OSMetaClassDefineReservedUnused(IORegistryEntry, 2);
-OSMetaClassDefineReservedUnused(IORegistryEntry, 3);
-OSMetaClassDefineReservedUnused(IORegistryEntry, 4);
+OSMetaClassDefineReservedUsed(IORegistryEntry, 0);
+OSMetaClassDefineReservedUsed(IORegistryEntry, 1);
+OSMetaClassDefineReservedUsed(IORegistryEntry, 2);
+OSMetaClassDefineReservedUsed(IORegistryEntry, 3);
+OSMetaClassDefineReservedUsed(IORegistryEntry, 4);
+
OSMetaClassDefineReservedUnused(IORegistryEntry, 5);
OSMetaClassDefineReservedUnused(IORegistryEntry, 6);
OSMetaClassDefineReservedUnused(IORegistryEntry, 7);