private boolean isJoinEmpty() { List<Job> realJobs = new ArrayList<Job>(); synchronized (jobs) { if (jobs.isEmpty()) { return true; } for (JobInfo jobInfo : jobs.values()) { if (!jobInfo.isActive()) continue; Job job = jobInfo.job; Set<String> names = getSuperClassNames(job); // Locate thread Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces(); boolean toContinue = false; for (Map.Entry<Thread, StackTraceElement[]> thread : traces.entrySet()) { Context ctx = ContextManagement.makeContext(thread.getValue()); for (String name : names) { if (ctx.contains(name, "run") || ctx.contains(name, "runInUIThread")) { // Job already running if (ctx.contains("org.eclipse.swt.widgets.Display", "sleep")) { // Job are showing dialog. Skip waiting for such // job. toContinue = true; break; } } } } if (toContinue) { continue; } realJobs.add(job); } } if (realJobs.size() == 1) { Job job = realJobs.iterator().next(); if (job.belongsTo(getFamilyAutoBuild())) { // Check for modal dialogs are visible int flags = TeslaSWTAccess.getJobFlags(job); // Job is alone and blocked if (flags == 0x08) { return true; } } } return realJobs.isEmpty(); }
public boolean isEmpty(Context context, Q7WaitInfoRoot info) { // Filter already executed UI jobs with async finish status. List<Job> realJobs = new ArrayList<Job>(); long current = System.currentTimeMillis(); boolean wasInStepMode = false; List<Job> jobsInUI = new ArrayList<Job>(); synchronized (jobs) { // Remove all canceled jobs removeCanceledJobs(); if (jobs.isEmpty()) { return logReturnResult(true, realJobs, jobsInUI, info); } for (JobInfo jobInfo : jobs.values()) { if (!jobInfo.isActive()) continue; Job job = jobInfo.job; IJobCollector[] collectors = JobCollectorExtensions.getDefault().getCollectors(); boolean allowSkip = true; for (IJobCollector ext : collectors) { if (ext.noSkipMode(job)) { allowSkip = false; break; } } if (allowSkip) { continue; } // SWTTeslaActivator.debugLog("Waiting job:" + job.getName() + // ": " // + job.getClass().getName()); long jobStartTime = jobInfo.startingTime; if (job.getClass().getName().contains("org.eclipse.debug.internal.ui.DebugUIPlugin$")) { // It looks like background launching job. Thread thread = job.getThread(); if (thread == null) { SWTTeslaActivator.logToReport("Active job " + job.getName() + " has no thread"); jobInfo.done(false); } Context ctx = ContextManagement.makeContext(thread.getStackTrace()); // If Autobuild job is active and on lock and there is Modal // Dialog in main thread, // lets' skip job from important for us. if (ctx.contains("java.util.concurrent.locks.LockSupport", "park") || ctx.contains("java.lang.Object", "wait")) { // We are waiting some stuff, let's check if main thread // have a MessageDialog and if so skip this job right // now. if (context.contains("org.eclipse.jface.dialogs.MessageDialogWithToggle", "open") || context.contains("org.eclipse.jface.dialogs.MessageDialog", "open")) { // Skip job from processing since it in lock and // waits for a dialog. SWTTeslaActivator.logToReport( "Active job " + job.getName() + " has skipped since it in lock state and Message dialog are active"); continue; } } } if (jobInfo.checkForTimeout) { if (jobStartTime + TeslaLimits.getStepModeEnableTimeout() < current && job.getState() == Job.RUNNING && stepModeNext < current) { // Job is sleepping to long time already. // Check for job are slepping // String name = job.getClass().getName(); // Locate thread Thread thread = job.getThread(); if (thread == null) { SWTTeslaActivator.logToReport("Active job " + job.getName() + " has no thread"); jobInfo.done(false); } Context ctx = ContextManagement.makeContext(thread.getStackTrace()); // if (ctx.contains( // "org.eclipse.jface.operation.ModalContext$ModalContextThread", // "block")) { // // Skip model context, since it could // continue; // } if (ctx.contains("java.lang.Thread", "sleep") || ctx.contains("java.lang.Object", "wait") || ctx.contains("java.util.concurrent.locks.LockSupport", "park")) { /* * Job are in Thread.sleep(), lets allow one * operation. */ if (!jobInfo.jobInStepMode) { // Print step information SWTTeslaActivator.logToReport( "---->>> Begin step mode for Job: " + getCurrentReportNodeName() + " <<---\n(skipping)" + getJobMessage(jobInfo)); } jobInfo.jobInStepMode = true; wasInStepMode = true; continue; } } long timeout = TeslaLimits.getJobTimeout(); if (job.belongsTo(getFamilyAutoBuild())) { timeout = TeslaLimits.getAutoBuildJobTimeout(); } if (jobInfo.jobInStepMode) { timeout = TeslaLimits.getStepModeTimeout(); } if (job.getClass().getName().contains("org.eclipse.debug.internal.ui.DebugUIPlugin")) { timeout = TeslaLimits.getDebugJobTimeout(); } if (jobStartTime + timeout < current) { if (context != null && TeslaEventManager.getManager().isJobInSyncExec(job, context)) { // Remove from stop waited jobs if called sync // exec jobInfo.checkForTimeout = false; } else { printJobTimeoutLogEntry(job); continue; } } } if (context != null) { if (isAsyncSupported()) { // If we are executed from async finished job lets // filter it if (JobsManager.getInstance().isFinishedAsyncJob(job)) { if (context.containsClass(job.getClass().getName())) { jobsInUI.add(job); continue; } } } if (isSyncSupported()) { // Check for any other job running Display.sleep() if (context.contains(Display.class.getName(), "sleep")) { if (TeslaEventManager.getManager().isJobInSyncExec(job, context)) { // If and only if job is already in synchronizer Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces(); Set<String> names = getSuperClassNames(job); Thread jobThread = null; Context jobContext = null; for (Map.Entry<Thread, StackTraceElement[]> thread : traces.entrySet()) { Context ctx = ContextManagement.makeContext(thread.getValue()); for (String name : names) { if (ctx.contains("org.eclipse.core.internal.jobs.Worker", "run") && ctx.contains(name, "run")) { jobThread = thread.getKey(); jobContext = ctx; } } } if (jobThread != null && jobContext != null) { if (jobContext.contains("org.eclipse.ui.internal.UISynchronizer", "syncExec") && jobContext.contains("org.eclipse.ui.internal.Semaphore", "acquire")) { if (!SWTUIPlayer.hasRunnables(RWTUtils.findDisplay())) { // also check what sync exec are on // current stack trace List<Context> execs = TeslaEventManager.getManager().getSyncExecs(); boolean toContinue = true; for (Context context2 : execs) { StackTraceElement[] stackTrace = context2.getStackTrace(); String className = null; for (int i = 0; i < stackTrace.length; i++) { if (stackTrace[i].getClassName().equals("org.eclipse.swt.widgets.Display") && stackTrace[i].getMethodName().equals("syncExec")) { className = stackTrace[i + 1].getClassName(); break; } } if (!context.containsClass(className)) { toContinue = false; } } if (toContinue) { jobsInUI.add(job); continue; } } } } } } } } if (jobInfo.isActive()) realJobs.add(job); } } if (!jobsInUI.isEmpty()) { if (realJobs.size() == 1 && realJobs.get(0).belongsTo(getFamilyAutoBuild())) { realJobs.clear(); } } if (realJobs.size() == 1) { Job job = realJobs.iterator().next(); if (job.belongsTo(getFamilyAutoBuild())) { // Check for modal dialogs are visible int flags = TeslaSWTAccess.getJobFlags(job); // Job is alone and blocked if ((flags & 0xFF) == 0x08) { return logReturnResult(true, realJobs, jobsInUI, info); } final Display display = RWTUtils.findDisplay(); final boolean value[] = {false}; display.syncExec( new Runnable() { public void run() { Shell[] shells = display.getShells(); for (Shell shell : shells) { if (isModal(shell)) { value[0] = true; } } } }); if (value[0]) { return logReturnResult(true, realJobs, jobsInUI, info); } if (job.getState() != Job.NONE) { return logReturnResult(false, realJobs, jobsInUI, info); } return logReturnResult(true, realJobs, jobsInUI, info); } } if (wasInStepMode && realJobs.isEmpty()) { stepModeNext = current + TeslaLimits.getStepModeStepTime(); } return logReturnResult(realJobs.isEmpty(), realJobs, jobsInUI, info); }