/******************************************************************************* * Copyright (c) 2012 Google, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Google, Inc. - initial API and implementation *******************************************************************************/ package com.windowtester.runtime.swt.internal.idle; import java.lang.reflect.Field; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import com.windowtester.internal.debug.LogHandler; import com.windowtester.runtime.internal.OS; /** * An idler strategy for Linux. */ public class LinuxIdler extends SWTIdler { /** * Determine if the UI thread is idle * * @see com.windowtester.runtime.condition.ICondition#test() */ public boolean isIdle() { if (true) return true; final Display display = getDisplay(); Thread thread = display.getThread(); // If the current thread *is* the UI thread // then return true if there are no more events to dispatch if (thread == Thread.currentThread()) return !display.readAndDispatch(); // Otherwise add an async runner to check for events to dispatch boolean checkNow = false; synchronized (lock) { if (!isIdle) { // If the asyncExec call to display.readAndDispatch() takes more // than 5 seconds, then it may not return until a dialog is closed // so queue another asyncExec call to display.readAndDispatch() if (!isChecking || (checkStart > 0 && System.currentTimeMillis() - checkStart > 5000)) { //Linux fix case 38523 if (OS.isLinux()) { if (checkStart > 0 && System.currentTimeMillis() - checkStart > 10000) { synchronized (lock) { isIdle = true; isChecking = false; checkStart = 0; return isIdle; } } } isChecking = true; checkNow = true; } } } if (checkNow) { synchronized (lock) { checkStart = System.currentTimeMillis(); } Event[] queue = null; try { Field queueField = display.getClass().getDeclaredField( "eventQueue"); queueField.setAccessible(true); queue = (Event[]) queueField.get(display); } catch (IllegalArgumentException e) { LogHandler.log(e); } catch (SecurityException e) { LogHandler.log(e); } catch (IllegalAccessException e) { LogHandler.log(e); } catch (NoSuchFieldException e) { LogHandler.log(e); } boolean processedEvent = false; if (queue == null) { processedEvent = false; synchronized (lock) { isIdle = !processedEvent; isChecking = false; checkStart = 0; } }else { display.asyncExec(new Runnable() { public void run() { boolean processedEvent = display.readAndDispatch(); synchronized (lock) { isIdle = !processedEvent; isChecking = false; checkStart = 0; } } }); } } synchronized (lock) { return isIdle; } } /** * Use the receiver to wait until the UI thread is idle */ public void waitForIdle() { if (true) return; Display display = getDisplay(); long startedWaiting = System.currentTimeMillis(); while (!isIdle() && withinWaitThreshold(startedWaiting)) { if (display.getThread() != Thread.currentThread()) { try { Thread.sleep(100); } catch (InterruptedException e) { // ignored } } } } private boolean withinWaitThreshold(long startedWaiting) { //Linux fix case 38523 //In the linux case we have a timeout for the wait if (!OS.isLinux()) return true; return true; //pq: what's the point of this test? } }