Comment 9 for bug 1430091

Revision history for this message
Tapan Karwa (tkarwa) wrote :

The sequence is:
1. Exporter gets an add or change. Exporter processes it and adds it to the queue as an 'update'.
2. The queue 'update' has not been processed yet and exporter gets a delete and does the following:

    } else if (state != NULL) {
        // Link deletes must preceed node deletes.
        state->ClearValid(); <<<<<< has been cleared
        if (!state->HasDependents()) { <<<<<< this is still true and so we skip the EnqueueDelete
            // enqueue delete.
            EnqueueDelete(node, state);
            if (state->update_list().empty()) {
                entry->ClearState(table, tinfo->id());
                delete state;
            }
        }
    }

We call ClearValid. But, HasDependents() returns true. So, we skip the enqueuing of the delete.
Now, the following code is executed on the queue side.

void IFMapUpdateSender::ProcessUpdate(IFMapUpdate *update,
                                      const BitSet &base_send_set) {
    LogAndCountSentUpdate(update, base_send_set);

    // Append the contents of the update-node to the message.
    message_->EncodeUpdate(update);
    // Clean up the node if everybody has seen it.
    update->AdvertiseReset(base_send_set);
    if (update->advertise().empty()) {
        queue_->Dequeue(update);
    }
    // Update may be freed.
    server_->exporter()->StateUpdateOnDequeue(update, base_send_set, << update points to an 'update' and not a 'delete'
                                              update->IsDelete());
}

Then, in StateUpdateOnDequeue()

        if (state->update_list().empty() && state->IsInvalid()) { <<<<<< both are true
            assert(state->advertised().empty());