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;
}
Exemple #2
0
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);
    }
}