OSCollection * OSOrderedSet::copyCollection(OSDictionary *cycleDict) { bool allocDict = !cycleDict; OSCollection *ret = 0; OSOrderedSet *newSet = 0; if (allocDict) { cycleDict = OSDictionary::withCapacity(16); if (!cycleDict) return 0; } do { // Check for a cycle ret = super::copyCollection(cycleDict); if (ret) continue; // Duplicate the set with no contents newSet = OSOrderedSet::withCapacity(capacity, ordering, orderingRef); if (!newSet) continue; // Insert object into cycle Dictionary cycleDict->setObject((const OSSymbol *) this, newSet); newSet->capacityIncrement = capacityIncrement; // Now copy over the contents to the new duplicate for (unsigned int i = 0; i < count; i++) { OSObject *obj = EXT_CAST(array[i].obj); OSCollection *coll = OSDynamicCast(OSCollection, obj); if (coll) { OSCollection *newColl = coll->copyCollection(cycleDict); if (newColl) { obj = newColl; // Rely on cycleDict ref for a bit newColl->release(); } else goto abortCopy; }; newSet->setLastObject(obj); }; ret = newSet; newSet = 0; } while (false); abortCopy: if (newSet) newSet->release(); if (allocDict) cycleDict->release(); return ret; }
void IOCatalogue::ping(thread_call_param_t arg, thread_call_param_t) { IOCatalogue * self = (IOCatalogue *) arg; OSOrderedSet * set; OSDictionary * table; int newLimit; set = OSOrderedSet::withCapacity( 1 ); IOLockLock( &self->lock ); for( newLimit = 0; newLimit < kDriversPerIter; newLimit++) { table = (OSDictionary *) self->array->getObject( hackLimit + newLimit ); if( table) { set->setLastObject( table ); OSSymbol * sym = (OSSymbol *) table->getObject(gIOClassKey); kprintf("enabling %s\n", sym->getCStringNoCopy()); } else { newLimit--; break; } } IOService::catalogNewDrivers( set ); hackLimit += newLimit; self->generation++; IOLockUnlock( &self->lock ); if( kDriversPerIter == newLimit) { AbsoluteTime deadline; clock_interval_to_deadline(500, kMillisecondScale); thread_call_func_delayed(ping, this, deadline); } }