VirtualBox

Changeset 11278 in vbox for trunk/src/libs/xpcom18a4/xpcom


Ignore:
Timestamp:
Aug 8, 2008 9:01:27 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
34371
Message:

xpcom/PL_DHashTableEnumerate: New fix/workaround for the IPC code deleting hash table entries during enumeartion - prevent ChangeTable from doing anything while someone is enumerating the hashtable. The previous fix had sideeffects and could cause entries to be skipped.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/xpcom18a4/xpcom/ds/pldhash.c

    r11276 r11278  
    436436    PLDHashMoveEntry moveEntry;
    437437
     438#ifdef VBOX /* HACK ALERT! generation == PR_UINT32_MAX during enumeration. */
     439    PR_ASSERT(table->generation != PR_UINT32_MAX);
     440    if (table->generation == PR_UINT32_MAX)
     441        return PR_FALSE;
     442#endif
     443
    438444    /* Look, but don't touch, until we succeed in getting new entry store. */
    439445    oldLog2 = PL_DHASH_BITS - table->hashShift;
     
    454460    table->removedCount = 0;
    455461    table->generation++;
     462#ifdef VBOX /* HACK ALERT! generation == PR_UINT32_MAX during enumeration. */
     463    if (table->generation == PR_UINT32_MAX)
     464        table->generation++;
     465#endif
    456466
    457467    /* Assign the new entry store to table. */
     
    564574            size = PL_DHASH_TABLE_SIZE(table);
    565575            if (size > PL_DHASH_MIN_SIZE &&
     576#ifdef VBOX /* HACK ALERT! generation == PR_UINT32_MAX during enumeration. */
     577            /** @todo This is where IPC screws up, avoid the assertion in ChangeTable until it's fixed. */
     578                table->generation != PR_UINT32_MAX &&
     579#endif
    566580                table->entryCount <= MIN_LOAD(table, size)) {
    567581                METER(table->stats.shrinks++);
     
    607621    PLDHashEntryHdr *entry;
    608622    PLDHashOperator op;
    609 #ifdef VBOX
     623#ifdef VBOX /* HACK ALERT! generation == PR_UINT32_MAX during enumeration. */
    610624    PRUint32 generation;
    611     char *entryStore;
    612 
     625
     626    /*
     627     * The hack! Set generation to PR_UINT32_MAX during the enumeration so
     628     * we can prevent ChangeTable from being called.
     629     *
     630     * This happens during ipcDConnectService::OnClientStateChange()
     631     * / ipcDConnectService::DeleteInstance() now when running
     632     * java clienttest list hostinfo and vboxwebsrv crashes. It's quite
     633     * likely that the IPC code isn't following the rules here, but it
     634     * looks more difficult to fix that just hacking this hash code.
     635     */
    613636    generation = table->generation;
    614     entryStore = table->entryStore;
    615 #endif
     637    table->generation = PR_UINT32_MAX;
     638#endif /* VBOX */
    616639    entryAddr = table->entryStore;
    617640    entrySize = table->entrySize;
     
    624647        if (ENTRY_IS_LIVE(entry)) {
    625648            op = etor(table, entry, i++, arg);
    626 #ifdef VBOX
    627             /*
    628              * Adjust pointers if entryStore was reallocated as a result
    629              * of an add or remove performed by the enumerator. It is
    630              * probably not supposed to do this, but since it does we'll
    631              * simply deal with it.
    632              *
    633              * This happens during ipcDConnectService::OnClientStateChange()
    634              * / ipcDConnectService::DeleteInstance() now.
    635              *
    636              * On second thought, this isn't a really good solution since
    637              * the entries may be reordered...
    638              */
    639             if (generation != table->generation)
    640             {
    641                 entryAddr += table->entryStore - entryStore;
    642                 entryStore = table->entryStore;
    643                 entry = (PLDHashEntryHdr *)entryAddr;
    644                 capacity = PL_DHASH_TABLE_SIZE(table);
    645                 entryLimit = table->entryStore + capacity * entrySize;
    646             }
    647 
     649#ifdef VBOX /* HACK ALERT! generation == PR_UINT32_MAX during enumeration. */
     650            PR_ASSERT(table->generation == PR_UINT32_MAX);
    648651#endif
    649652            if (op & PL_DHASH_REMOVE) {
     
    657660        entryAddr += entrySize;
    658661    }
     662#ifdef VBOX /* HACK ALERT! generation == PR_UINT32_MAX during enumeration. */
     663    table->generation = generation;
     664#endif
    659665
    660666    /*
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette