void SipTransactionList::removeOldTransactions(long oldTransaction, long oldInviteTransaction) { SipTransaction** transactionsToBeDeleted = NULL; int deleteCount = 0; int busyCount = 0; # ifdef TIME_LOG OsTimeLog gcTimes; gcTimes.addEvent("start"); # endif lock(); int numTransactions = mTransactions.entries(); if(numTransactions > 0) { UtlHashBagIterator iterator(mTransactions); SipTransaction* transactionFound = NULL; long transTime; // Pull all of the transactions to be deleted out of the list while((transactionFound = (SipTransaction*) iterator())) { if(transactionFound->isBusy()) busyCount++; transTime = transactionFound->getTimeStamp(); // Invites need to be kept longer than other transactions if(((!transactionFound->isMethod(SIP_INVITE_METHOD) && transTime < oldTransaction) || transTime < oldInviteTransaction) && ! transactionFound->isBusy()) { // Remove it from the list mTransactions.removeReference(transactionFound); OsSysLog::add(FAC_SIP, PRI_DEBUG, "removing transaction %p\n",transactionFound); // Make sure we have a pointer array to hold it if(transactionsToBeDeleted == NULL) { transactionsToBeDeleted = new SipTransaction*[numTransactions]; } // Put it in the pointer array transactionsToBeDeleted[deleteCount] = transactionFound; deleteCount++; // Make sure the events waiting for the transaction // to be available are signaled before we delete // any of the transactions or we end up with // incomplete transaction trees (i.e. deleted branches) transactionFound->signalAllAvailable(); transactionFound = NULL; } } } unlock(); // We do not need the lock if the transactions have been // removed from the list if ( deleteCount || busyCount ) // do not log 'doing nothing when nothing to do', even at debug level { OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipTransactionList::removeOldTransactions deleting %d of %d transactions (%d busy)\n", deleteCount , numTransactions, busyCount); } // Delete the transactions in the array if (transactionsToBeDeleted) { # ifdef TIME_LOG gcTimes.addEvent("start delete"); # endif for(int txIndex = 0; txIndex < deleteCount; txIndex++) { delete transactionsToBeDeleted[txIndex]; # ifdef TIME_LOG gcTimes.addEvent("transaction deleted"); # endif } # ifdef TIME_LOG gcTimes.addEvent("finish delete"); # endif /* while((transactionFound = (SipTransaction*) iterator())) { transactionFound->stopTimers(); } */ delete[] transactionsToBeDeleted; transactionsToBeDeleted = NULL; } # ifdef TIME_LOG UtlString timeString; gcTimes.getLogString(timeString); OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipTransactionList::removeOldTransactions " "%s", timeString.data() ); # endif }
void SipTransactionList::removeOldTransactions(long oldTransaction, long oldInviteTransaction) { SipTransaction** transactionsToBeDeleted = NULL; int deleteCount = 0; int busyCount = 0; # ifdef TIME_LOG OsTimeLog gcTimes; gcTimes.addEvent("start"); # endif lock(); # ifdef TIME_LOG gcTimes.addEvent("locked"); # endif int numTransactions = mTransactions.entries(); if(numTransactions > 0) { UtlHashBagIterator iterator(mTransactions); SipTransaction* transactionFound = NULL; long transTime; // Pull all of the transactions to be deleted out of the list while ((transactionFound = (SipTransaction*) iterator())) { if(transactionFound->isBusy()) { busyCount++; } else { transTime = transactionFound->getTimeStamp(); // Invites need to be kept longer than other transactions if ( transTime < ( transactionFound->isMethod(SIP_INVITE_METHOD) ? oldInviteTransaction : oldTransaction ) ) { #ifdef TRANSACTION_MATCH_DEBUG Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipTransactionList::removeOldTransactions " " removing %p", transactionFound ); #endif // Remove it from the list mTransactions.removeReference(transactionFound); // Make sure we have a pointer array to hold it if(transactionsToBeDeleted == NULL) { transactionsToBeDeleted = new SipTransaction*[numTransactions]; } // Put it in the pointer array transactionsToBeDeleted[deleteCount] = transactionFound; deleteCount++; // Make sure the events waiting for the transaction // to be available are signaled before we delete // any of the transactions or we end up with // incomplete transaction trees (i.e. deleted branches) // :TODO: move to the actual deletion loop so we're not holding the lock? -SDL transactionFound->signalAllAvailable(); } } } } # ifdef TIME_LOG gcTimes.addEvent("scan done"); # endif // We do not need the lock now that the transactions have been // removed from the list unlock(); if ( deleteCount || busyCount ) // do not log 'doing nothing when nothing to do', even at debug { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipTransactionList::removeOldTransactions" " deleting %d of %d transactions (%d busy)", deleteCount , numTransactions, busyCount ); } // Delete the transactions in the array if (transactionsToBeDeleted) { # ifdef TIME_LOG gcTimes.addEvent("start delete"); # endif for(int txIndex = 0; txIndex < deleteCount; txIndex++) { delete transactionsToBeDeleted[txIndex]; } # ifdef TIME_LOG gcTimes.addEvent("finish delete"); # endif delete[] transactionsToBeDeleted; } # ifdef TIME_LOG UtlString timeString; gcTimes.getLogString(timeString); Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipTransactionList::removeOldTransactions " "%s", timeString.data() ); # endif }