Enumeration modules = getModules().elements();
while (modules.hasMoreElements())
{
RecoveryModule m = (RecoveryModule) modules.nextElement();
// we need to ensure we use the class loader context of the recovery module while we are executing
// its methods
ClassLoader cl = switchClassLoader(m);
try {
m.periodicWorkFirstPass();
} finally {
restoreClassLoader(cl);
}
if (tsLogger.arjLogger.isDebugEnabled())
{
tsLogger.arjLogger.debug( DebugLevel.FUNCTIONS,
VisibilityLevel.VIS_PUBLIC,
FacilityCode.FAC_CRASH_RECOVERY,
" " );
}
}
// take the lock again so we can do a backoff wait on it
synchronized (_stateLock) {
// we have to wait for a bit to avoid catching (too many)
// transactions etc. that are really progressing quite happily
doBackoffWait();
// we carry on scanning even if scanning is SUSPENDED because the suspending thread
// might be waiting on us to complete and we don't want to risk deadlocking it by waiting
// here for a resume.
// if we have been TERMINATED we bail out now
// n.b. if we give up here the caller is responsible for clearing the active scan
if (getMode() == Mode.TERMINATED) {
if (tsLogger.arjLogger.isDebugEnabled())
{
tsLogger.arjLogger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PUBLIC,
FacilityCode.FAC_CRASH_RECOVERY, "PeriodicRecovery: scan TERMINATED at phase 1");
}
return;
}
}
// move on to phase 2
if (tsLogger.arjLoggerI18N.isDebugEnabled())
{
tsLogger.arjLoggerI18N.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PRIVATE, FacilityCode.FAC_CRASH_RECOVERY,
"com.arjuna.ats.internal.arjuna.recovery.PeriodicRecovery_15", new Object[] {_theTimestamper.format(new Date())});
}
modules = _recoveryModules.elements();
while (modules.hasMoreElements())
{
RecoveryModule m = (RecoveryModule) modules.nextElement();
ClassLoader cl = switchClassLoader(m);
try {
m.periodicWorkSecondPass();
} finally {
restoreClassLoader(cl);
}
if (tsLogger.arjLogger.isDebugEnabled())