import org.tizen.emulator.manager.ui.dialog.MessageDialog;
import org.tizen.emulator.manager.ui.renewal.MainDialog;
import org.tizen.emulator.manager.vms.helper.WorkerLock;
+import org.tizen.emulator.manager.vms.monitor.RunningMonitor;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
private static boolean isWin = false;
private static boolean isWin8AndAbove = false;
private static boolean isLinux = false;
+
static {
if (System.getProperty("os.name").toLowerCase().indexOf("linux") > -1) { //$NON-NLS-1$ //$NON-NLS-2$
CheckVT.class, CheckGPU.class, CheckSDCard.class, CheckWebcam.class);
checkers.startWork();
+ RunningMonitor.initialize();
}
-
if (!SettingInfoFile.setMACaddr()) {
exitEmulatorManager(1);
}
-
if (isConsoleMode) {
EmulatorManager.startConsoleProcessor();
} else {
EMLogger.getLogger().log(Level.INFO, "Start Emulator Manager!!"); //$NON-NLS-1$
+
EmulatorManager.preare();
EmulatorManager.draw();
EmulatorManager.dispose();
}
-
} catch (Throwable e) {
e.printStackTrace();
import org.tizen.emulator.manager.ui.tabfolder.ProfileTabItem;
import org.tizen.emulator.manager.ui.widgets.ImageButton;
import org.tizen.emulator.manager.vms.VMProperty;
-import org.tizen.emulator.manager.vms.helper.CheckingRunningEmulator;
-import org.tizen.emulator.manager.vms.helper.RefreshWorker;
+import org.tizen.emulator.manager.vms.monitor.RunningMonitor;
public class MainDialog {
private static final String ICON_FILE_NAME = "res/em.ico"; //$NON-NLS-1$
}
public void open() {
- CheckingRunningEmulator.startCheckingThread();
shell.open();
SDKUpdateManager.checkUpdate();
while(!shell.isDisposed()) {
public static void refreshVMPropertyList(boolean isClear) {
ProfileList.settingVMPropertyList();
- // check vm socket connection
- RefreshWorker.refreshVMConnect();
- // check running emulator list
- CheckingRunningEmulator.refreshVMPropertyList();
+ RunningMonitor.refreshAll();
if (isClear) {
tabFolder.getSelection().draw();
import org.tizen.emulator.manager.tool.About;
import org.tizen.emulator.manager.ui.renewal.tableviewer.AbstractTableViewer;
import org.tizen.emulator.manager.ui.renewal.tableviewer.VMListTableViewer;
-import org.tizen.emulator.manager.vms.helper.CheckingRunningEmulator;
public class MainDialog {
private static final String ICON_FILE_NAME = "res/em.ico"; //$NON-NLS-1$
}
public void open() {
- CheckingRunningEmulator.startCheckingThread();
-
shell.open();
while(!shell.isDisposed()) {
if(!Display.getCurrent().readAndDispatch()) {
import org.tizen.emulator.manager.ui.renewal.widgets.CreateVMCombo;
import org.tizen.emulator.manager.ui.renewal.widgets.ImageButton;
import org.tizen.emulator.manager.vms.VMProperty;
-import org.tizen.emulator.manager.vms.helper.CheckingRunningEmulator;
-import org.tizen.emulator.manager.vms.helper.RefreshWorker;
+import org.tizen.emulator.manager.vms.monitor.RunningMonitor;
public class VMListTableViewer extends AbstractTableViewer {
private static final int BUTTON_WIDTH = 32;
// reloading emulator list from data directory
public void refreshVMPropertyList() {
ProfileList.settingVMPropertyList();
- CheckingRunningEmulator.refreshVMPropertyList();
- RefreshWorker.refreshVMConnect();
+ // refresh all VM state
+ RunningMonitor.refreshAll();
makeTableItem();
}
import org.tizen.emulator.manager.vms.VMProperty.FSImageType;
import org.tizen.emulator.manager.vms.helper.CheckingRunningEmulator;
import org.tizen.emulator.manager.vms.helper.HelperClass;
-import org.tizen.emulator.manager.vms.helper.VMSocket;
public class VMButton extends ImageButton {
private VMButton button = null;
if (prop != null) {
if (CheckingRunningEmulator.isRemote(prop) && prop.isRunning()) {
int webVMPort = 0;
- synchronized (VMSocket.list) {
- for (VMSocket s : VMSocket.list) {
+ /* FIXME
+ synchronized (ECSSocket.list) {
+ for (ECSSocket s : ECSSocket.list) {
if (s.getProperty() != null && s.getProperty().getName().equals(prop.getName())) {
webVMPort = s.getEcs_port() + 3;
}
}
}
+ */
if (webVMPort > 0) {
String ip = HelperClass.getLocalIPAddress(webVMPort-3);
button.setToolTipText(prop.getName() + Messages.getString("VMButton.RemoteToolTip.0") + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import javax.xml.bind.JAXBContext;
static private JAXBContext context = null;
static private String vmsConfigDirectory = ""; //$NON-NLS-1$
- private final List<VMProperty> propertiesList = new ArrayList<VMProperty>();
+ private final List<VMProperty> propertiesList =
+ Collections.synchronizedList(new ArrayList<VMProperty>());
private final ObjectFactory objectFactory = new ObjectFactory();
static {
loadProperties();
}
- public void loadProperties() {
+ private void loadProperties() {
synchronized (propertiesList) {
propertiesList.clear();
// traverse VMs...
return property;
}
}
+ }
- return null;
+ return null;
+ }
+
+ public VMProperty getProperty(Path childImagePath) {
+ synchronized (propertiesList) {
+ for (VMProperty property : propertiesList) {
+ Path path = Paths.get(property.getChildImagePath());
+ if (path.equals(childImagePath)) {
+ return property;
+ }
+ }
}
+
+ return null;
}
public VMProperty[] getProperties() {
import org.tizen.emulator.manager.resources.StringResources;
import org.tizen.emulator.manager.tool.PortHelper;
import org.tizen.emulator.manager.ui.dialog.MessageDialog;
-import org.tizen.emulator.manager.vms.helper.CheckingRunningEmulator;
-import org.tizen.emulator.manager.vms.helper.MonitoringEmulator;
import org.tizen.emulator.manager.vms.helper.VMLauncherException;
import org.tizen.emulator.manager.vms.helper.VMLogUtil;
import org.tizen.emulator.manager.vms.helper.VMWorkerException;
+import org.tizen.emulator.manager.vms.monitor.LaunchingMonitor;
import org.tizen.emulator.manager.vms.option.LaunchConfig;
import org.tizen.emulator.manager.vms.option.NetProxyOption;
import org.tizen.emulator.manager.vms.option.OPTION_KEY;
List<String> cmd = getCommand(property);
- CheckingRunningEmulator.addEmulator(property);
- MonitoringEmulator monitor = new MonitoringEmulator(property);
String emulatorPath = property.getPropertyValue().baseImage.getPlatform().getEmulatorPath();
+
Process process = launch(property.getName(), emulatorPath, cmd, path);
- if (process != null) {
- monitor.setProcess(process);
- monitor.start();
- if (wait) {
- try {
- monitor.join();
- } catch (InterruptedException e) {
- EMLogger.getLogger().warning(e.getMessage());
- }
- if (monitor.isSuccess()) {
- return true;
- } else {
- return false;
- }
- }
- return true;
- } else {
- CheckingRunningEmulator.removeEmulator(property, false);
- monitor.interrupt();
+ if (process == null) {
return false;
}
+
+ LaunchingMonitor monitor = new LaunchingMonitor(property, process);
+
+ if (!wait) {
+ monitor.asyncExecute(8); // timeout : 8 seconds
+
+ return true;
+ }
+
+ return monitor.execute();
}
private static void checkPortNumber() throws VMLauncherException {
return process;
}
-
-}
+}
\ No newline at end of file
import org.tizen.emulator.manager.plugin.ExtensionItem;
import org.tizen.emulator.manager.plugin.PluginStringResources;
import org.tizen.emulator.manager.resources.FilePathResources;
+import org.tizen.emulator.manager.vms.helper.CheckingRunningEmulator;
import org.tizen.emulator.manager.vms.helper.VMLogUtil;
import org.tizen.emulator.manager.vms.xml.EmulatorConfiguration;
public static final int MIN_DPI = 100;
public static final int MAX_DPI = 480;
+ public static enum State {
+ NOT_SET,
+ NOT_AVAILABLE,
+ BUSY,
+ READY,
+ LAUNCHING,
+ RUNNING,
+ }
+
private File propertyFile;
private long lastModified;
private VMPropertyConfiguration configuration;
private VMWorkerCommon worker;
private VMPropertyValue value = null;
- private boolean isRunning = false;
- // Is it possible to launch emulator or not?
- private boolean isAvailable = true;
+ private State state = State.READY;
private long lastLaunched;
return worker;
}
+ public State getState() {
+ return state;
+ }
+
+ public synchronized boolean setState(State state) {
+ if (this.state == State.BUSY) {
+ // pending state change
+ return false;
+ }
+
+ switch (state) {
+ case NOT_SET:
+ // can not enter here
+ assert true;
+ break;
+ case NOT_AVAILABLE:
+ break;
+ case BUSY:
+ assert this.state != State.RUNNING;
+ break;
+ case READY:
+ if (this.state == State.RUNNING) {
+ if (worker != null) {
+ worker.sendRemoteLog("stop"); //$NON-NLS-1$
+ }
+ }
+ break;
+ case LAUNCHING:
+ assert this.state == State.READY;
+ break;
+ case RUNNING:
+ assert this.state == State.LAUNCHING || this.state == State.READY;
+ if (worker != null) {
+ worker.sendRemoteLog("start"); //$NON-NLS-1$
+ }
+ break;
+ default:
+ break;
+ }
+
+ this.state = state;
+
+ CheckingRunningEmulator.notifyToStateListener(this);
+
+ return true;
+ }
+
public boolean isRunning() {
- return isRunning;
+ return this.state == State.RUNNING || this.state == State.LAUNCHING;
}
- public void setRunning(boolean isRunning) {
- this.isRunning = isRunning;
+
+ public boolean isAvailable() {
+ return this.state != State.NOT_AVAILABLE;
+ }
+
+ // TODO: not tested yet
+ public void setAvailable(boolean isAvailable) {
+ if (isAvailable) {
+ setState(State.READY);
+ } else {
+ setState(State.NOT_AVAILABLE);
+ }
}
// for plug-in source -> need to delete
return true;
}
- public boolean isAvailable() {
- return isAvailable;
- }
-
- public void setAvailable(boolean isAvailable) {
- this.isAvailable = isAvailable;
- }
-
public long getLastLaunchedTime() {
return lastLaunched;
}
import org.tizen.emulator.manager.logging.EMLogger;
import org.tizen.emulator.manager.resources.FilePathResources;
import org.tizen.emulator.manager.resources.StringResources;
-import org.tizen.emulator.manager.vms.helper.CheckingRunningEmulator;
import org.tizen.emulator.manager.vms.helper.QemuImgProc;
import org.tizen.emulator.manager.vms.helper.VMLauncherException;
import org.tizen.emulator.manager.vms.helper.VMWorkerException;
throw new VMWorkerException(""); //$NON-NLS-1$
} else {
// success to launch vm
- property.setRunning(true);
+// property.setRunning(true);
property.setLastLaunchedTime(new Date().getTime());
}
+ (useCompress ? " using compress." : "."));
// block other function while to create base image
- CheckingRunningEmulator.addEmulator(property);
+// CheckingRunningEmulator.addEmulator(property);
+ property.setState(VMProperty.State.BUSY);
} finally {
// lock.release
WorkerLock.release();
propertyLockFile.delete();
}
- CheckingRunningEmulator.removeEmulator(property, false);
+// CheckingRunningEmulator.removeEmulator(property, false);
+ property.setState(VMProperty.State.READY);
EMLogger.getLogger().info("Success to create base image."
+ StringResources.NEW_LINE
+ "Base image path: " + baseImagePath);
}
//
- if (CheckingRunningEmulator.isContains(property)) {
- throw new VMWorkerException("[" + property.getName() //$NON-NLS-1$
- + Messages.getString("VMWorkerCommon.WorkingError.1")); //$NON-NLS-1$
- }
-
if (checking(property)) {
- if (!EmulatorManager.isConsoleMode()) {
- CheckingRunningEmulator.connectToECS(property);
- }
throw new VMWorkerException("[" + property.getName() //$NON-NLS-1$
+ Messages.getString("VMWorkerCommon.WorkingError.1")); //$NON-NLS-1$
} else {
package org.tizen.emulator.manager.vms.helper;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.NoConnectionPendingException;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
-import java.nio.charset.Charset;
import java.util.ArrayList;
-import java.util.Iterator;
+import java.util.Collections;
import java.util.List;
-import org.eclipse.swt.widgets.Display;
-import org.tizen.ecp.msg.genmsg.ecs.Ecs.DeviceAns;
-import org.tizen.ecp.msg.genmsg.ecs.Ecs.Master;
-import org.tizen.ecp.msg.genmsg.ecs.EcsIds.Master_Type;
import org.tizen.emulator.manager.EmulatorManager;
import org.tizen.emulator.manager.EmulatorManager.ManagerModeType;
-import org.tizen.emulator.manager.Messages;
-import org.tizen.emulator.manager.logging.EMLogger;
-import org.tizen.emulator.manager.resources.StringResources;
-import org.tizen.emulator.manager.ui.dialog.MessageDialog;
-import org.tizen.emulator.manager.vms.EmulatorVMList;
import org.tizen.emulator.manager.vms.VMProperty;
-import org.tizen.emulator.manager.vms.VMWorkerCommon;
-import org.tizen.emulator.manager.vms.helper.VMSocketQueue.QueueObject;
-public class CheckingRunningEmulator {
- private static ArrayList<String> emList = new ArrayList<String> ();
-
- private static CheckingThread thread = null;
-
- // Decide whether popup-message display or not.
- private static List<String> LAUNCHED_VM_LIST = new ArrayList<String>();
- private static List<EmulatorStatusListener> listenerList = new ArrayList<EmulatorStatusListener>();
-
- public static void addLaunchedVMList(String vmName) {
- synchronized(LAUNCHED_VM_LIST) {
- LAUNCHED_VM_LIST.add(vmName);
- }
- }
-
- private static void removeLaunchedVMList(String vmName) {
- synchronized(LAUNCHED_VM_LIST) {
- LAUNCHED_VM_LIST.remove(vmName);
- }
- }
+public final class CheckingRunningEmulator {
+ private static List<EmulatorStatusListener> listenerList =
+ Collections.synchronizedList(new ArrayList<EmulatorStatusListener>());
public static void addRunningEmulatorListener(EmulatorStatusListener listener) {
listenerList.add(listener);
listenerList.remove(listener);
}
- public static boolean needPopupMessage(VMSocket vms) {
- if (vms.getProperty() != null) {
- String vmName = vms.getProperty().getName();
- String launched = null;
- synchronized(LAUNCHED_VM_LIST) {
- for (String s : LAUNCHED_VM_LIST) {
- if (s.equals(vmName)) {
- launched = s;
- }
- }
- if (launched != null) {
- removeLaunchedVMList(launched);
- return true;
- }
- }
- }
- return false;
-
- }
-
- public static synchronized void startCheckingThread() {
- if (EmulatorManager.isConsoleMode()) {
- return;
- }
-
- if (thread != null && thread.isAlive()) {
- return;
- }
-
- thread = new CheckingThread();
- thread.setName("checkEM"); //$NON-NLS-1$
- thread.setDaemon(true);
- thread.start();
- }
-
- public static Selector getSelector() {
- if (thread != null) {
- return thread.getSelector();
- }
- return null;
- }
-
-
- public static boolean addToRegisterQueue(VMSocket vmSocket, int ops){
- if (thread != null) {
- return thread.addToRegisterQueue(vmSocket, ops);
- }
- return false;
- }
-
- public static void addEmulator(VMProperty prop) {
- synchronized (emList) {
- if(!emList.contains(prop.getName())) {
- emList.add(prop.getName());
- }
- }
-
- setRunning(prop.getName(), true);
- }
-
- public static void removeEmulator(VMProperty prop, boolean isSuccess) {
- synchronized (emList) {
- emList.remove(prop.getName());
- }
- if (!isSuccess) {
- setRunning(prop.getName(), false);
- } else {
- addLaunchedVMList(prop.getName());
- boolean checkFinished;
- boolean isRunning = false;
- int count=1;
- VMSocket.ResultType res;
- do {
- res = connectToECS(prop);
- EMLogger.getLogger().info("Try connection #" + count + ", result: "+ res); //$NON-NLS-1$ //$NON-NLS-2$
-
- switch (res) {
- case ECS_NOT_READY:
- case IMAGEPATH_NOT_READY:
- checkFinished = false;
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- EMLogger.getLogger().warning(e.getMessage());
- }
- break;
-
- case LAUNCHED_VM_DETECTED:
- isRunning = true;
- checkFinished = true;
- break;
-
- case SOCK_CLOSED:
- default:
- checkFinished = true;
- }
-
- } while (!checkFinished && count++ < 10);
-
- if (isRunning) {
- VMWorkerCommon worker = prop.getWorker();
- if (worker != null) {
- worker.sendRemoteLog("start"); //$NON-NLS-1$
- }
-
- } else {
- setRunning(prop, false);
- EMLogger.getLogger().info("No response from VM (" + prop.getName() + ")."); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
- }
-
- // for to remove property after success connected ecs
- private static void removeEmulator(VMProperty prop) {
- synchronized (emList) {
- emList.remove(prop.getName());
- }
- }
-
- public static boolean isContains(String name) {
- synchronized (emList) {
- return emList.contains(name);
- }
- }
-
- public static boolean isContains(VMProperty prop) {
- synchronized (emList) {
- return emList.contains(prop.getName());
- }
- }
-
- public static VMSocket.ResultType connectToECS(VMProperty vm) {
-
- VMSocket.ResultType result = VMSocket.ResultType.SOCK_CLOSED;
- if(EmulatorManager.isConsoleMode()){
- return result;
- }
- boolean isHeartBeat = false;
- boolean isVMFound = false;
- boolean isEcsNotReady = false;
- boolean isImagepathNotReady = false;
- VMSocket currentVms = null;
-
- synchronized (VMSocket.list) {
- for (VMSocket s : VMSocket.list) {
- boolean needCheck = false;
- if (s.getSocket() == null || !s.getSocket().isConnected()) {
- needCheck = s.sendMessage();
-
- } else if (s.getSocket().isConnected()) {
- if (s.getProperty() != null && vm.getName().equals(s.getProperty().getName())) {
- EMLogger.getLogger().info("Socket already connected.. :" + s.getProperty().getName()); //$NON-NLS-1$
- s.disconnect();
- // Send request one more time.
- needCheck = s.sendMessage();
- }
- }
- if(needCheck){
- VMSocket.ResultType type = s.checkReceiveMessage(vm);
-
- switch(type){
- case LAUNCHED_VM_DETECTED:
- isVMFound = true;
- currentVms = s;
- break;
-
- case IMAGEPATH_NOT_READY:
- isImagepathNotReady = true;
- break;
-
- case SOCK_CLOSED:
- break;
-
- case HEARTBEAT:
- isHeartBeat = true;
- break;
- default:
- // TODO
- break;
- }
-
- if(isVMFound)
- break;
-
- } else {
- isEcsNotReady = true;
- }
- }
- }
-
- if (isVMFound) {
- setRunning(vm, true);
- CheckingRunningEmulator.removeEmulator(vm);
- result = VMSocket.ResultType.LAUNCHED_VM_DETECTED;
- // Check remote option.
- if (isRemote(vm)) {
-// runServer(currentVms);
- showInfoDialog(currentVms);
- }
-
- } else if (isImagepathNotReady) {
- result = VMSocket.ResultType.IMAGEPATH_NOT_READY;
-
- } else if (isEcsNotReady){
- result = VMSocket.ResultType.ECS_NOT_READY;
- }
-
- if (!isHeartBeat){
- // TODO
- }
-
- return result;
- }
-
- public static void setRunning(String vmName, boolean isRunning) {
- VMProperty prop = EmulatorVMList.getInstance().getProperty(vmName);
- setRunning(prop, isRunning);
- }
-
- public static void setRunning(VMProperty prop, boolean isRunning) {
- if (prop == null) {
- return;
- }
-
- prop.setRunning(isRunning);
-
+ public static void notifyToStateListener(VMProperty property) {
for (EmulatorStatusListener listener : listenerList ) {
- listener.changeEmulatorRunningStatus(prop);
- }
- }
-
- public static void refreshVMPropertyList() {
- for (VMProperty prop : (EmulatorVMList.getInstance().getProperties())) {
- if (emList.contains(prop.getName())) {
- prop.setRunning(true);
- }
- }
-
- for (VMSocket s : VMSocket.list){
- if (s.getProperty() != null) {
- for (VMProperty prop : (EmulatorVMList.getInstance().getProperties())) {
- if (prop.getName().equals(s.getProperty().getName())) {
- s.setProperty(prop);
- prop.setRunning(true);
- break;
- }
- }
- }
- }
- }
-
- public static class CheckingThread extends Thread {
- private Selector selector = null;
-
- private final VMSocketQueue registeringQueue = new VMSocketQueue();
-
- private void init() {
- try {
- selector = Selector.open();
- } catch (IOException e) {
- EMLogger.getLogger().warning(e.getMessage());
- selector = null;
- }
- }
-
- public Selector getSelector() {
- if (selector == null) {
- init();
- }
- return selector;
- }
-
-
- public boolean addToRegisterQueue(VMSocket vmSocket, int ops){
- if (getSelector() != null) {
- registeringQueue.add(vmSocket, ops);
- selector.wakeup();
- return true;
- }
- return false;
- }
-
- // register socket to selector
- public void registerSocket() {
- while(true) {
- QueueObject queueObject = registeringQueue.poll();
- if(queueObject == null) {
- return;
- }
-
- VMSocket vmSocket = queueObject.getVmSocket();
- int ops = queueObject.getOps();
- if (selector != null) {
- SocketChannel sc = vmSocket.getSocket();
- try {
- sc.configureBlocking(false);
- sc.register(selector, ops, vmSocket);
- } catch (Exception e) {
- EMLogger.getLogger().warning(e.getMessage());
- disconnect(vmSocket);
- }
- } else {
- disconnect(vmSocket);
- }
- }
- }
-
- @Override
- public void run() {
-
- for (VMSocket s : VMSocket.list) {
- if (s.getSocket() == null || !s.getSocket().isConnected()) {
- s.connect();
- }
- }
-
- while (true) {
- if (getSelector () != null) {
- try {
- selector.select();
- registerSocket();
- Iterator<SelectionKey> it = selector.selectedKeys().iterator();
- while(it.hasNext()) {
- SelectionKey key = it.next();
- if (key.isReadable()) {
- readBuffer(key);
- } else if (key.isConnectable()) {
- checkConnection(key);
- }
- it.remove();
- }
- } catch (IOException e) {
- EMLogger.getLogger().warning("Selector exception: " + e.getMessage()); //$NON-NLS-1$
-
- } catch (Exception e) {
- EMLogger.getLogger().warning(e.getClass().getName() + " : " + e.getMessage()); //$NON-NLS-1$
- }
- }
- }
- }
-
- private final ByteBuffer length = ByteBuffer.allocate(4);
- private final ByteBuffer buffer = ByteBuffer.allocate(4096);
- private int size = 0;
- private void readBuffer(SelectionKey key) {
- SocketChannel sc = (SocketChannel)key.channel();
- VMSocket vms = (VMSocket)key.attachment();
- length.clear();
- buffer.clear();
- try {
- size = sc.read(length);
- if (size == -1) {
- setVMExit(vms);
- return;
- }
-
- length.position(0);
- int len = length.getInt();
- buffer.limit(len);
- size = sc.read(buffer);
- if (size == -1) {
- setVMExit(vms);
- return;
- }
-
- buffer.flip();
- buffer.position(0);
- byte[] buff = new byte[len];
- buffer.get(buff);
- Master msg = Master.parseFrom(buff);
- if (msg.getType() == Master_Type.DEVICE_ANS) {
- DeviceAns ans = msg.getDeviceAns();
- if (ans.getCategory().equals("info")) { //$NON-NLS-1$
- String path = new String(ans.getData().toByteArray(),
- Charset.forName(System.getProperty("file.encoding")));
- EMLogger.getLogger().info("ecs response : " + path);
- settingProperty(path, vms);
- }
- } else if (msg.getType() == Master_Type.KEEPALIVE_REQ) {
- if (vms != null) {
- vms.sendKeepAliveAns();
- }
- }
- } catch (IOException e){
- EMLogger.getLogger().warning(e.getMessage());
- setVMExit(vms);
- } catch (IllegalArgumentException e) {
- EMLogger.getLogger().warning(e.getMessage());
- if (length != null) {
- EMLogger.getLogger().warning("Socket Msg length : " + length.getInt()); //$NON-NLS-1$
- }
- }
- }
-
- private void checkConnection(SelectionKey key) {
- SocketChannel sc = (SocketChannel)key.channel();
- VMSocket vms = (VMSocket)key.attachment();
- boolean isReady = false;
-
- if (sc.isConnected()) {
- isReady = addToRegisterQueue(vms, SelectionKey.OP_READ);
- } else {
- try {
- if (sc.finishConnect()) {
- // Connect success
- isReady = addToRegisterQueue(vms, SelectionKey.OP_READ);
- } else {
- // Connect pending.
- EMLogger.getLogger().info("Connection not completed yet : " + vms.getEcs_port()); //$NON-NLS-1$
- return;
- }
- } catch (NoConnectionPendingException e) {
- EMLogger.getLogger().warning("finishConnect error. " + e.getClass().getName() + " : " + e.getMessage());
- vms.reconnect();
- return;
-
- } catch (IOException e) { // Connection failed.
- isReady = false;
- } catch (Exception e) {
- EMLogger.getLogger().warning(e.getClass().getName() + " : " + e.getMessage()); //$NON-NLS-1$
- }
- }
-
- if (isReady) {
- vms.sendDeviceReq();
-
- } else {
- // EMLogger.getLogger().info("Connection fail : " + vms.getEcs_port());
- vms.disconnect();
- }
- }
-
- private static void setVMExit(VMSocket vms) {
- if (vms.getProperty() != null) {
- VMWorkerCommon worker = vms.getProperty().getWorker();
- if (worker != null) {
- worker.sendRemoteLog("stop"); //$NON-NLS-1$
- }
- }
- disconnect(vms);
- }
-
- public static void disconnect(VMSocket vms) {
- // disconnect
- if (vms != null) {
- if (vms.getProperty() != null) {
- CheckingRunningEmulator.setRunning(vms.getProperty(), false);
- }
- vms.disconnect();
- }
- }
-
- private void settingProperty(String path, VMSocket vms) {
- if (vms != null) {
- RefreshWorker.addToFinishedSet(vms.getEcs_port());
- }
-
- for (VMProperty prop : (EmulatorVMList.getInstance().getProperties())) {
- if (HelperClass.pathEquals(path, prop.getChildImagePath())) {
- if (vms != null) {
- vms.setProperty(prop);
- RefreshWorker.addToFinishedSet(vms.getEcs_port());
- }
- CheckingRunningEmulator.setRunning(prop, true);
- CheckingRunningEmulator.removeEmulator(prop);
-
- // Check remote option.
- if (isRemote(prop)) {
-// runServer(vms);
- showInfoDialog(vms);
- }
-
- break;
- }
- }
+ listener.changeEmulatorRunningStatus(property);
}
-
}
+ // FIXME
public static String OPTION_VIEWER = "viewer"; //$NON-NLS-1$
public static String OPTION_TYPE = "type"; //$NON-NLS-1$
public static String VAL_WEB = "Web"; //$NON-NLS-1$
}
return false;
}
-
- /*
- public static void runServer(VMSocket vms) {
- // Run web(Node) server (if not running)
- boolean nodeResult = WebEmulator.runWebServer();
-
- // Run emulator(spice) server (if not running)
- boolean spiceResult = WebEmulator.runEmulatorServer(vms);
-
- showInfoDialog(nodeResult, spiceResult, vms);
- }
- */
-
- public static void showInfoDialog(VMSocket vms) {
- if(needPopupMessage(vms)) {
- final int clientPort = vms.getEcs_port() + 3;
- final String vmName = (vms.getProperty() != null) ? vms.getProperty().getName() : ""; //$NON-NLS-1$
- final String ip = HelperClass.getLocalIPAddress(vms.getEcs_port());
- final String msg = "URL : http://" + ip + ":8080" + //$NON-NLS-1$ //$NON-NLS-2$
- StringResources.NEW_LINE
- + "VM Port : " + clientPort + //$NON-NLS-1$
- StringResources.NEW_LINE + StringResources.NEW_LINE
- + Messages.getString("CheckingRunningEmulator.WebViewerInfo.1"); //$NON-NLS-1$
- if (EmulatorManager.isConsoleMode()) {
- System.out.println(msg);
- } else {
- Display.getDefault().asyncExec(new Runnable() {
- @Override
- public void run() {
- MessageDialog msgDialog = new MessageDialog();
- String title = Messages.getString("CheckingRunningEmulator.WebViewerInfo.2") + vmName + ")"; //$NON-NLS-1$ //$NON-NLS-2$
- msgDialog.openInfoDialog(title, StringResources.NEW_LINE + msg);
- }
- });
- }
- }
- }
-
- /*
- public static void killServer(VMSocket vms) {
- WebEmulator.killEmulatorServer(vms);
-
- // Kill web server if no remote VM runs.
- WebEmulator.killWebServer();
- }
- */
-
}
+++ /dev/null
-/*
- * Emulator Manager
- *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact:
- * Minkee Lee <minkee.lee@samsung.com>
- * MunKyu Im <munkyu.im@samsung.com>
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * JiHye Kim <jihye1128.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-package org.tizen.emulator.manager.vms.helper;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.tizen.emulator.manager.logging.EMLogger;
-import org.tizen.emulator.manager.vms.EmulatorVMList;
-import org.tizen.emulator.manager.vms.VMProperty;
-
-public class RefreshWorker {
-
- private static Set<Integer> finishedSet = new HashSet<Integer>();
-
- public static void addToFinishedSet(int port) {
- synchronized (finishedSet) {
- finishedSet.add(port);
- }
- }
-
- public static void clearFinishedSet() {
- synchronized (finishedSet) {
- finishedSet.clear();
- }
- }
-
- public static void refreshVMConnect() {
-
- // Re-connect VMs
- synchronized (VMSocket.list) {
- for (VMSocket s : VMSocket.list) {
- s.disconnect();
- }
- clearFinishedSet();
- for (VMSocket s : VMSocket.list) {
- s.connect();
- }
- }
-
- // Wait until all re-connect ended.
- while (true) {
- synchronized (finishedSet) {
- if (finishedSet.size() == VMSocket.MAX_CONNECT_NUM) {
- break;
- }
- }
-
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- EMLogger.getLogger().warning(e.getMessage());
- }
- }
- EMLogger.getLogger().info("Refresh complete"); //$NON-NLS-1$
-
- // Change VMs' running state
- for (VMProperty prop : (EmulatorVMList.getInstance().getProperties())) {
- if (VMSocket.isPropertyInList(prop)) {
- prop.setRunning(true);
- } else {
- prop.setRunning(false);
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Emulator Manager
- *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact:
- * Minkee Lee <minkee.lee@samsung.com>
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-package org.tizen.emulator.manager.vms.helper;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-
-
-public class VMSocketQueue {
-
- public static class QueueObject {
- VMSocket vmSocket;
- int ops; // select-event type
-
- public QueueObject(VMSocket vmSocket, int ops){
- this.vmSocket = vmSocket;
- this.ops = ops;
- }
-
- public VMSocket getVmSocket() {
- return vmSocket;
- }
- public void setVmSocket(VMSocket vmSocket) {
- this.vmSocket = vmSocket;
- }
- public int getOps() {
- return ops;
- }
- public void setOps(int ops) {
- this.ops = ops;
- }
- }
-
- private BlockingQueue<QueueObject> queue ;
-
- public VMSocketQueue() {
- queue = new LinkedBlockingQueue<QueueObject>();
- }
-
- public boolean add(VMSocket vmSocket, int ops) {
- return queue.add(new QueueObject(vmSocket, ops));
- }
-
- public QueueObject poll() {
- return queue.poll();
- }
-}
--- /dev/null
+/*
+ * Emulator Manager
+ *
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * JiHye Kim <jihye1128.kim@samsung.com>
+ * Minkee Lee <minkee.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+package org.tizen.emulator.manager.vms.monitor;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.nio.charset.Charset;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.tizen.ecp.msg.genmsg.ecs.Ecs.DeviceAns;
+import org.tizen.ecp.msg.genmsg.ecs.Ecs.Master;
+import org.tizen.ecp.msg.genmsg.ecs.EcsIds.Master_Type;
+import org.tizen.emulator.manager.logging.EMLogger;
+import org.tizen.emulator.manager.vms.monitor.VMSocketQueue.QueueObject;
+
+final class ECSMonitor extends RunningMonitor {
+ private final VMSocketQueue registeringQueue = new VMSocketQueue();
+ private final Selector selector;
+
+ private List<ECSSocket> sockets = new ArrayList<ECSSocket>();
+
+ ECSMonitor() throws IOException {
+ selector = Selector.open();
+
+ for (int i = 26103; i < 26194; i += 10) {
+ sockets.add(new ECSSocket(i));
+ }
+
+ new MonitoringThread(new ConnetionMonitor(), "ECSConnectionMonitor").start();
+ new MonitoringThread(new SocketMonitor(), "ECSSocketMonitor").start();
+ }
+
+ private void addToRegisterQueue(ECSSocket socket, int ops){
+ registeringQueue.add(socket, ops);
+ selector.wakeup();
+ }
+
+ final class ConnetionMonitor implements Runnable {
+ @Override
+ public void run() {
+ while(true) {
+ for (ECSSocket s : sockets) {
+ if (s.getSocket() != null && s.getSocket().isConnected()) {
+ continue;
+ }
+
+ if (s.getSocket() == null && !s.tryConnect()) {
+ continue;
+ }
+
+ addToRegisterQueue(s, SelectionKey.OP_READ);
+ }
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ final class SocketMonitor implements Runnable {
+ // register socket to selector
+ private void registerSocket() {
+ while(true) {
+ QueueObject queueObject = registeringQueue.poll();
+ if(queueObject == null) {
+ return;
+ }
+
+ ECSSocket socket = queueObject.socket;
+ SocketChannel sc = socket.getSocket();
+
+ try {
+ sc.register(selector, queueObject.ops, socket);
+ } catch (Exception e) {
+ EMLogger.getLogger().warning(e.getMessage());
+ disconnect(socket);
+ }
+
+ socket.sendDeviceReq();
+ }
+ }
+
+ private void runningVMDetected(String path, ECSSocket vms) {
+ Path vmPath = Paths.get(path);
+ vms.setPath(vmPath);
+
+ updateState(vmPath, true);
+ }
+
+ private final ByteBuffer length = ByteBuffer.allocate(4);
+ private final ByteBuffer buffer = ByteBuffer.allocate(4096);
+ private int size = 0;
+ private void readBuffer(SelectionKey key) {
+ SocketChannel sc = (SocketChannel)key.channel();
+ ECSSocket vms = (ECSSocket)key.attachment();
+
+ if (vms == null) {
+ // FIXME
+ return;
+ }
+
+ length.clear();
+ buffer.clear();
+ try {
+ size = sc.read(length);
+ if (size == -1) {
+ disconnect(vms);
+ return;
+ }
+
+ length.position(0);
+ int len = length.getInt();
+ buffer.limit(len);
+ size = sc.read(buffer);
+ if (size == -1) {
+ disconnect(vms);
+ return;
+ }
+
+ buffer.flip();
+ buffer.position(0);
+ byte[] buff = new byte[len];
+ buffer.get(buff);
+ Master msg = Master.parseFrom(buff);
+ if (msg.getType() == Master_Type.DEVICE_ANS) {
+ DeviceAns ans = msg.getDeviceAns();
+ if (ans.getCategory().equals("info")) { //$NON-NLS-1$
+ String path = new String(ans.getData().toByteArray(),
+ Charset.forName(System.getProperty("file.encoding")));
+ EMLogger.getLogger().info("ecs response : " + path);
+
+ runningVMDetected(path, vms);
+ }
+ } else if (msg.getType() == Master_Type.KEEPALIVE_REQ) {
+ vms.sendKeepAliveAns();
+ }
+ } catch (IOException e){
+ EMLogger.getLogger().warning(e.getMessage());
+ disconnect(vms);
+ } catch (IllegalArgumentException e) {
+ EMLogger.getLogger().warning(e.getMessage());
+ if (length != null) {
+ EMLogger.getLogger().warning("Socket Msg length : " + length.getInt()); //$NON-NLS-1$
+ }
+ }
+ }
+
+ private void disconnect(ECSSocket vms) {
+ vms.disconnect();
+
+ updateState(vms.getPath(), false);
+ }
+
+ @Override
+ public void run() {
+ while (true) {
+ try {
+ selector.select();
+ registerSocket();
+ for (SelectionKey key : selector.selectedKeys()) {
+ if (key.isReadable()) {
+ readBuffer(key);
+ } else {
+ ECSSocket vms = (ECSSocket)key.attachment();
+ if (vms != null) {
+ disconnect(vms);
+ }
+ }
+ }
+ } catch (IOException e) {
+ EMLogger.getLogger().warning("Selector exception: " + e.getMessage()); //$NON-NLS-1$
+
+ } catch (Exception e) {
+ EMLogger.getLogger().warning(e.getClass().getName() + " : " + e.getMessage()); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+}
+
/*
* Emulator Manager
*
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
*
* Contact:
* Minkee Lee <minkee.lee@samsung.com>
*/
-package org.tizen.emulator.manager.vms.helper;
+package org.tizen.emulator.manager.vms.monitor;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
-import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
+import java.nio.file.Path;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
-import org.tizen.ecp.msg.genmsg.ecs.Ecs.DeviceAns;
import org.tizen.ecp.msg.genmsg.ecs.Ecs.DeviceReq;
import org.tizen.ecp.msg.genmsg.ecs.Ecs.KeepAliveAns;
import org.tizen.ecp.msg.genmsg.ecs.Ecs.Master;
import org.tizen.emulator.manager.logging.EMLogger;
import org.tizen.emulator.manager.vms.VMProperty;
-public class VMSocket {
+final class ECSSocket {
+ private Path imagePath;
- public enum ResultType {
+ enum ResultType {
LAUNCHED_VM_DETECTED, ECS_NOT_READY, IMAGEPATH_NOT_READY, SOCK_CLOSED, HEARTBEAT;
}
public static int MAX_CONNECT_NUM = 10;
- public static ArrayList<VMSocket> list = new ArrayList<VMSocket>();
- static {
- for (int i = 26103; i < 26194; i += MAX_CONNECT_NUM) {
- list.add(new VMSocket(i));
- }
- }
-
- public static boolean isPropertyInList(VMProperty param) {
- for (VMSocket s : list) {
- if (param.equals(s.getProperty())) {
- return true;
- }
- }
- return false;
- }
-
private final int ecs_port;
private SocketChannel socket;
private VMProperty property;
- private VMSocket(int port) {
+ ECSSocket(int port) {
this.ecs_port = port;
}
return ecs_port;
}
- public SocketChannel getSocket() {
- return socket;
+ void setPath(Path path) {
+ this.imagePath = path;
}
- public void setSocket(SocketChannel socket) {
- this.socket = socket;
+ Path getPath() {
+ return imagePath;
+ }
+
+ public SocketChannel getSocket() {
+ return socket;
}
public VMProperty getProperty() {
this.property = property;
}
- public boolean connect() {
- // Add socket to selector and try connect.
- // Connection process is completed by selector event.
- try {
- socket = SocketChannel.open();
- socket.configureBlocking(false);
-
- if (CheckingRunningEmulator.addToRegisterQueue(this, SelectionKey.OP_CONNECT)) {
- socket.connect(new InetSocketAddress("localhost", ecs_port)); //$NON-NLS-1$
-
- } else {
- EMLogger.getLogger().warning("Add to selector(connect event) fail :" + ecs_port); //$NON-NLS-1$
- disconnect();
- }
-
- } catch (IOException e) {
- // EMLogger.getLogger().info("Connect fail.(" + e.getMessage() + ") - " + ecs_port);
- disconnect();
- return false;
-
- } catch (Exception e) {
- EMLogger.getLogger().warning(e.getClass().getName() + " : " + e.getMessage()); //$NON-NLS-1$
- return false;
- }
-
- return true;
- }
-
-
- public boolean sendMessage(){
- // socket open
+ public boolean tryConnect() {
try {
socket = SocketChannel.open
(new InetSocketAddress("localhost", ecs_port)); //$NON-NLS-1$
+ socket.configureBlocking(false);
} catch (IOException e) {
// EMLogger.getLogger().warning("Connect to ECS(port:" + ecs_port + ") Fail. " + e.getMessage());
disconnect();
return false;
}
- if (socket == null) {
- return false;
- }
- // send message
- sendDeviceReq();
return true;
-
- }
-
-
- public ResultType checkReceiveMessage(VMProperty vm){
-
- if( socket != null){
- ByteBuffer length = ByteBuffer.allocate(4);
- ByteBuffer buffer = ByteBuffer.allocate(4096);
- String path = null;
-
- try {
- int size = socket.read(length);
- if (size == -1) {
- disconnect();
- return ResultType.SOCK_CLOSED;
- }
-
- length.position(0);
- int len = length.getInt();
- buffer.limit(len);
- size = socket.read(buffer);
- if (size == -1) {
- disconnect();
- return ResultType.SOCK_CLOSED;
- }
-
- buffer.flip();
- buffer.position(0);
- byte[] buff = new byte[len];
- buffer.get(buff);
- Master msg = Master.parseFrom(buff);
- if (msg.getType() == Master_Type.DEVICE_ANS) {
- DeviceAns ans = msg.getDeviceAns();
- if (ans.getCategory().equals("info")) { //$NON-NLS-1$
- path = new String(ans.getData().toByteArray(),
- Charset.forName(System.getProperty("file.encoding")));
- EMLogger.getLogger().info("ecs response : " + path);
- if (HelperClass.pathEquals(path, vm.getChildImagePath())) {
- setProperty(vm);
- if (CheckingRunningEmulator.addToRegisterQueue(this, SelectionKey.OP_READ)) {
- return ResultType.LAUNCHED_VM_DETECTED;
- }
- } else if (path.isEmpty()){
- EMLogger.getLogger().info("Path from ecs is not initialized yet. VM : " + vm.getName()); //$NON-NLS-1$
- return ResultType.IMAGEPATH_NOT_READY;
- }
- }
-
- } else if (msg.getType() == Master_Type.KEEPALIVE_REQ) {
- if (CheckingRunningEmulator.addToRegisterQueue(this, SelectionKey.OP_READ)) {
- sendKeepAliveAns();
- return ResultType.HEARTBEAT;
- }
- }
- } catch (IOException e){
- disconnect();
- EMLogger.getLogger().warning(e.getMessage());
- }
- }
-
- disconnect();
- return ResultType.SOCK_CLOSED;
}
public void disconnect() {
} catch (IOException e) {
EMLogger.getLogger().info(e.getMessage());
}
- setSocket(null);
+ socket = null;
}
- setProperty(null);
- RefreshWorker.addToFinishedSet(ecs_port);
+ property = null;
}
public void reconnect() {
} catch (IOException e) {
EMLogger.getLogger().info(e.getMessage());
}
- setSocket(null);
+ socket = null;
}
- setProperty(null);
+ property = null;
// connect again.
- connect();
+ tryConnect();
}
}
}
+
+final class VMSocketQueue {
+ public static class QueueObject {
+ final ECSSocket socket;
+ final int ops; // select-event type
+
+ public QueueObject(ECSSocket socket, int ops){
+ this.socket = socket;
+ this.ops = ops;
+ }
+ }
+
+ private BlockingQueue<QueueObject> queue;
+
+ public VMSocketQueue() {
+ queue = new LinkedBlockingQueue<QueueObject>();
+ }
+
+ public boolean add(ECSSocket socket, int ops) {
+ return queue.add(new QueueObject(socket, ops));
+ }
+
+ public QueueObject poll() {
+ return queue.poll();
+ }
+}
\ No newline at end of file
/*
* Emulator Manager
*
- * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
*
* Contact:
* JiHye Kim <jihye1128.kim@samsung.com>
*
*/
-package org.tizen.emulator.manager.vms.helper;
+package org.tizen.emulator.manager.vms.monitor;
import java.io.BufferedReader;
import java.io.IOException;
import org.tizen.emulator.manager.ui.dialog.MessageDialog;
import org.tizen.emulator.manager.vms.VMProperty;
-public class MonitoringEmulator extends Thread {
- private VMProperty property;
- private Process process;
- private int count = 8;
+public final class LaunchingMonitor implements Runnable {
+ private final VMProperty property;
+ private final Process process;
+ private Output stdOut = null;
+ private Output stdErr = null;
- public MonitoringEmulator(VMProperty property) {
+ public LaunchingMonitor(VMProperty property, Process process) {
this.property = property;
- this.setDaemon(true);
- }
-
- public void setProcess(Process process) {
- this.process = process;
- }
-
- public void setProcess(Process process, int count) {
this.process = process;
- this.count = count;
}
- private StdOut stdOut = null;
- private StdOut stdErr = null;
- private boolean success = true;
-
- @Override
- public void run() {
+ public boolean execute() {
if (process == null || property == null) {
- return;
+ return false;
}
- InputStreamReader in1 = new InputStreamReader(process.getInputStream());
- InputStreamReader in2 = new InputStreamReader(process.getErrorStream());
- BufferedReader readerOut = new BufferedReader(in1);
- BufferedReader readerError = new BufferedReader(in2);
+ boolean success = true;
+
+ BufferedReader readerOut = new BufferedReader(new InputStreamReader(process.getInputStream()));
+ BufferedReader readerError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
- stdOut = new StdOut(readerOut, property.getName());
- stdErr = new StdOut(readerError, property.getName());
+ stdOut = new Output(readerOut, property.getName());
+ Thread t1 = new Thread(stdOut, property.getName() + "STDOUT"); //$NON-NLS-1$
+
+ stdErr = new Output(readerError, property.getName());
+ Thread t2 = new Thread(stdErr, property.getName() + "STDERR"); //$NON-NLS-1$
- Thread t1 = new Thread(stdOut);
- Thread t2 = new Thread(stdErr);
- t1.setName(property.getName() + "STDOUT"); //$NON-NLS-1$
- t2.setName(property.getName() + "STDERR"); //$NON-NLS-1$
t1.start();
t2.start();
- // start timer
- new Thread(new Timer(this, count)).start();
-
try {
int exitValue = process.waitFor();
stdErr.printMessageList();
if (exitValue != 0) {
- setSuccess(false);
+ success = false;
EMLogger.getLogger().warning(
"You can see more information in the emulator-manager.log or " //$NON-NLS-1$
+ property.getName() + "'s logs directory."); //$NON-NLS-1$
}
}
} catch (InterruptedException e) {
+ // launched successfully
EMLogger.getLogger().log(Level.FINE, e.getMessage());
}
- CheckingRunningEmulator.removeEmulator(property, isSuccess());
+ stdOut.setDone();
+ stdErr.setDone();
try {
t1.join();
- } catch (InterruptedException e1) {
- EMLogger.getLogger().warning(e1.getMessage());
- }
- try {
t2.join();
- } catch (InterruptedException e1) {
- EMLogger.getLogger().warning(e1.getMessage());
+ } catch (InterruptedException e) {
+ EMLogger.getLogger().warning(e.getMessage());
}
// close
} catch (IOException e) {
EMLogger.getLogger().warning(e.getMessage());
}
- }
- public boolean isSuccess() {
return success;
}
- public void setSuccess(boolean success) {
- this.success = success;
- }
-
-}
-
-class Timer implements Runnable {
- private MonitoringEmulator monitor;
- private int count;
-
- public Timer(MonitoringEmulator m) {
- this(m, 8);
- }
-
- public Timer(MonitoringEmulator m, int c) {
- monitor = m;
- count = c;
+ public void asyncExecute(int timeoutSec) {
+ new MonitoringThread(this, "LunchingMonitor", timeoutSec).start();
}
@Override
public void run() {
- synchronized (this) {
- try {
- this.wait(1000 * count);
- } catch (InterruptedException e) {
- EMLogger.getLogger().warning(e.getMessage());
- }
- }
-
- monitor.interrupt();
+ property.setState(VMProperty.State.LAUNCHING);
+ if (!execute()) {
+ property.setState(VMProperty.State.READY);
+ }
}
}
-class StdOut implements Runnable {
+final class Output implements Runnable {
private BufferedReader reader;
private String vmName;
private final ArrayList<String> list = new ArrayList<String>();
- public StdOut(BufferedReader reader, String name) {
+ private boolean isDone = false;
+ private boolean error = false;
+
+
+ Output(BufferedReader reader, String name) {
this.reader = reader;
this.vmName = name;
}
- public StdOut(InputStreamReader in, String name) {
+ Output(InputStreamReader in, String name) {
this.reader = new BufferedReader(in);
this.vmName = name;
}
+ void setDone() {
+ this.isDone = true;
+ }
+
@Override
public void run() {
String msg = ""; //$NON-NLS-1$
e.printStackTrace();
}
}
- } while (CheckingRunningEmulator.isContains(vmName));
+ } while (!isDone);
} catch (IOException e) {
EMLogger.getLogger().info(e.getMessage());
} finally {
}
}
- private boolean error = false;
-
public void printMessageList() {
error = true;
}
-}
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Emulator Manager
+ *
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * JiHye Kim <jihye1128.kim@samsung.com>
+ * Minkee Lee <minkee.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+package org.tizen.emulator.manager.vms.monitor;
+
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitOption;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.StandardWatchEventKinds;
+import java.nio.file.WatchEvent;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchService;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.tizen.emulator.manager.resources.FilePathResources;
+
+abstract class LockFileMonitor extends RunningMonitor {
+ private final WatchService watcher;
+
+ protected final List<Path> lockedFiles = new ArrayList<Path>();
+
+ private final Map<WatchKey, Path> keys;
+ protected final Path lockfilePath;
+
+
+ LockFileMonitor() throws IOException {
+ watcher = FileSystems.getDefault().newWatchService();
+ keys = new HashMap<WatchKey, Path>();
+ // XXX: We concern only image files / lockfiles under Tizen sdk data VMS path
+ lockfilePath = Paths.get(FilePathResources.getTizenVmsPath());
+
+ assert !(Files.notExists(lockfilePath));
+
+ new MonitoringThread(new FileMonitorThread(), "LockFileMonitor").start();
+ }
+
+ abstract protected boolean isMonitoringFile(Path path);
+ abstract protected void handleExistFile(Path path);
+
+ protected void registerDirectory(Path path) throws IOException {
+ assert Files.isDirectory(path);
+
+ WatchKey key = path.register(watcher, StandardWatchEventKinds.ENTRY_CREATE,
+ StandardWatchEventKinds.ENTRY_DELETE);
+ keys.put(key, path);
+ }
+
+ private void traverseSubdirectory(final Path start) throws IOException {
+ assert Files.isDirectory(start);
+
+ // register sub-directories
+ Files.walkFileTree(start, Collections.<FileVisitOption> emptySet(), 2,
+ new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+ throws IOException
+ {
+ registerDirectory(dir);
+
+ // we should watch already have been launched VMs
+ DirectoryStream<Path> stream = Files.newDirectoryStream(dir);
+ for (Path path : stream) {
+ if (Files.isRegularFile(path) && isMonitoringFile(path)) {
+ handleExistFile(path);
+ }
+ }
+
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+
+ private void registerWatchRoot() throws InterruptedException, IOException {
+ boolean isRootRegistered = false;
+ WatchKey key = null;
+
+ while(!isRootRegistered) {
+ try {
+ key = lockfilePath.register(watcher, StandardWatchEventKinds.ENTRY_CREATE,
+ StandardWatchEventKinds.ENTRY_DELETE);
+ } catch(NoSuchFileException e) {
+ // failsafe, can not enter here.
+ Thread.sleep(1000);
+ continue;
+ } catch(IOException e) {
+ // FIXME
+ e.printStackTrace();
+ }
+ isRootRegistered = true;
+ keys.put(key, lockfilePath);
+ }
+
+ traverseSubdirectory(lockfilePath);
+ }
+
+ abstract protected void entryCreated(Path path) throws IOException;
+ abstract protected void entryDeleted(Path path) throws IOException;
+
+ private final class FileMonitorThread implements Runnable {
+ @Override
+ public void run() {
+ WatchKey key = null;
+
+ try {
+ registerWatchRoot();
+
+ while(true) {
+ key = watcher.take();
+
+ Path dir = keys.get(key);
+ if (dir == null) {
+ continue;
+ }
+
+ for (WatchEvent<?> event : key.pollEvents()) {
+ Path path = dir.resolve((Path)event.context());
+
+ if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
+ entryCreated(path);
+ }
+
+ if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
+ entryDeleted(path);
+ }
+ }
+
+ if(!key.reset()) {
+ keys.remove(key);
+ }
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Emulator Manager
+ *
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * JiHye Kim <jihye1128.kim@samsung.com>
+ * Minkee Lee <minkee.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+package org.tizen.emulator.manager.vms.monitor;
+
+import org.tizen.emulator.manager.logging.EMLogger;
+
+final class MonitoringThread extends Thread {
+ private final int timeoutSec;
+
+ public MonitoringThread(Runnable runnable, String name, int timeoutSec) {
+ super(runnable);
+ // Monitoring thread should be exit immediately when emulator-manager is terminated
+ this.setDaemon(true);
+
+ this.timeoutSec = timeoutSec;
+ }
+
+ public MonitoringThread(Runnable runnable, String name) {
+ this(runnable, name, 0);
+ }
+
+ @Override
+ public void start() {
+ // Start timer for interrupting launching monitor
+ if (timeoutSec > 0) {
+ new TimerThread(this, timeoutSec).start();
+ }
+
+ super.start();
+ }
+}
+
+final class TimerThread extends Thread {
+ private Thread thread;
+ private int sec;
+
+ TimerThread(Thread thread, int sec) {
+ this.thread = thread;
+ this.sec = sec;
+
+ this.setDaemon(true);
+ }
+
+ @Override
+ public void run() {
+ synchronized (this) {
+ try {
+ this.wait(sec * 1000);
+ } catch (InterruptedException e) {
+ EMLogger.getLogger().warning(e.getMessage());
+ }
+ }
+
+ thread.interrupt();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Emulator Manager
+ *
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * JiHye Kim <jihye1128.kim@samsung.com>
+ * Minkee Lee <minkee.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+package org.tizen.emulator.manager.vms.monitor;
+
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.tizen.emulator.manager.vms.VMProperty;
+
+final class PosixLockFileMonitor extends LockFileMonitor {
+ protected final List<Path> monitoredFiles =
+ Collections.synchronizedList(new ArrayList<Path>());
+
+ PosixLockFileMonitor() throws IOException {
+ super();
+
+ new MonitoringThread(new LockMonitorThread(), "PosixLockMonitor").start();
+ }
+
+ @Override
+ protected boolean isMonitoringFile(Path path) {
+ for (VMProperty.Architecture arch : VMProperty.Architecture.values()) {
+ if (path.toString().endsWith("." + arch.toString())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ protected void handleExistFile(Path path) {
+ monitoredFiles.add(path);
+ }
+
+ @Override
+ protected void entryCreated(Path path) throws IOException {
+ if (Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
+ if (path.getParent().equals(lockfilePath)) {
+ registerDirectory(path);
+ }
+
+ return;
+ }
+
+ if (!Files.isRegularFile(path)) {
+ return;
+ }
+
+ assert !monitoredFiles.contains(path);
+
+ monitoredFiles.add(path);
+ }
+
+ @Override
+ protected void entryDeleted(Path path) throws IOException {
+ if (!Files.isRegularFile(path)) {
+ return;
+ }
+
+ boolean result = monitoredFiles.remove(path);
+
+ assert result;
+ }
+
+ private synchronized boolean examineLock(Path path) throws IOException {
+ FileChannel fc = FileChannel.open(path, StandardOpenOption.WRITE);
+ FileLock lock = fc.tryLock();
+
+ if (lock != null && lock.isValid()) {
+ lock.release();
+ fc.close();
+
+ if (lockedFiles.remove(path)) {
+ updateState(path, false);
+ }
+
+ return false;
+ }
+
+ if (!lockedFiles.contains(path)) {
+ lockedFiles.add(path);
+ updateState(path, true);
+ }
+
+ fc.close();
+
+ return true;
+ }
+
+ private final class LockMonitorThread implements Runnable {
+ @Override
+ public void run() {
+ while (true) {
+ try {
+ synchronized (monitoredFiles) {
+ for (Path path : monitoredFiles) {
+ try {
+ examineLock(path);
+ } catch (NoSuchFileException e) {
+ // Ignore it
+ }
+ }
+ }
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Emulator Manager
+ *
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * JiHye Kim <jihye1128.kim@samsung.com>
+ * Minkee Lee <minkee.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+package org.tizen.emulator.manager.vms.monitor;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.tizen.emulator.manager.EmulatorManager;
+import org.tizen.emulator.manager.vms.EmulatorVMList;
+import org.tizen.emulator.manager.vms.VMProperty;
+import org.tizen.emulator.manager.vms.VMProperty.State;
+
+public class RunningMonitor {
+ private static Thread updater;
+
+ private static Map<Path, MonitoringState<Path>> monitoredVMs = new HashMap<Path, MonitoringState<Path>>();
+ private static List<MonitoringState<Path>> pendingJobs =
+ Collections.synchronizedList(new ArrayList<MonitoringState<Path>>());
+
+ private List<Path> ignoredVMs = new ArrayList<Path>();
+
+
+ protected RunningMonitor() {
+ synchronized (RunningMonitor.class) {
+ if (updater == null) {
+ updater = new Thread(new Updater());
+ updater.setDaemon(true);
+ updater.start();
+ }
+ }
+ }
+
+ protected void updateState(Path imagePath, boolean isRunningDetected) {
+ MonitoringState<Path> mstate = new MonitoringState<Path>(imagePath, isRunningDetected);
+
+ synchronized (monitoredVMs) {
+ if (isRunningDetected) {
+ if (monitoredVMs.containsKey(imagePath)) {
+ // XXX: prevent double check by multiple monitor
+ // monitors must not call it again with same state
+ ignoredVMs.add(imagePath);
+
+ return;
+ }
+
+ monitoredVMs.put(imagePath, mstate);
+ } else {
+ if (ignoredVMs.remove(imagePath)) {
+ return;
+ }
+
+ MonitoringState<Path> result = monitoredVMs.remove(imagePath);
+
+ assert result != null;
+ }
+ }
+
+ pendingJobs.add(mstate);
+ // update state immediately
+ updatePended();
+ }
+
+ private void updatePended() {
+ synchronized (pendingJobs) {
+ Iterator<MonitoringState<Path>> iter = pendingJobs.iterator();
+ while (iter.hasNext()) {
+ MonitoringState<Path> mstate = iter.next();
+ VMProperty property = EmulatorVMList.getInstance().getProperty(mstate.object);
+ State updateState = mstate.isRunningDetected ? State.RUNNING : State.READY;
+
+ if (property != null && property.setState(updateState)) {
+ iter.remove();
+ }
+ }
+ }
+ }
+
+ public static void refreshAll() {
+ synchronized (monitoredVMs) {
+ synchronized (pendingJobs) {
+ // just add all monitoring states into a pending job list
+ // it will be set again by Updater thread soon
+ for (MonitoringState<Path> mstate : monitoredVMs.values()) {
+ pendingJobs.add(mstate);
+ }
+ }
+ }
+ }
+
+ public static synchronized void initialize() throws IOException {
+ // do not initialize again
+ assert updater == null;
+
+ // for recent emulator
+ if (EmulatorManager.isWin()) {
+ // TODO: not tested yet
+ // new WindowsLockFileMonitor();
+ } else {
+ new PosixLockFileMonitor();
+ }
+
+ // for legacy emulator
+ new ECSMonitor();
+ }
+
+ private final class Updater implements Runnable {
+ @Override
+ public void run() {
+ while (true) {
+ updatePended();
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+}
+
+final class MonitoringState<T> {
+ final T object;
+ boolean isRunningDetected;
+
+ public MonitoringState(T object, boolean isRunningDetected) {
+ this.object = object;
+ this.isRunningDetected = isRunningDetected;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof MonitoringState<?>)) {
+ return false;
+ }
+
+ @SuppressWarnings("unchecked")
+ T obj2 = ((MonitoringState<T>)obj).object;
+ if (obj2.equals(object)) {
+ return true;
+ }
+
+ return false;
+ }
+}
--- /dev/null
+/*
+ * Emulator Manager
+ *
+ * Copyright (C) 2011 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * JiHye Kim <jihye1128.kim@samsung.com>
+ * Minkee Lee <minkee.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+package org.tizen.emulator.manager.vms.monitor;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
+
+final class WindowsLockFileMonitor extends LockFileMonitor {
+ WindowsLockFileMonitor() throws IOException {
+ super();
+ }
+
+ @Override
+ protected boolean isMonitoringFile(Path path) {
+ if (path.toString().endsWith(".lock")) {
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ protected void handleExistFile(Path path) {
+ // all .lock files are locked
+ lockedFiles.add(path);
+ updateState(path, true);
+ }
+
+ @Override
+ protected void entryCreated(Path path) throws IOException {
+ if (Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
+ if (path.getParent().equals(lockfilePath)) {
+ registerDirectory(path);
+ }
+
+ return;
+ }
+
+ if (!isMonitoringFile(path) || !Files.isRegularFile(path)) {
+ return;
+ }
+
+ assert !lockedFiles.contains(path);
+
+ lockedFiles.add(path);
+ updateState(path, true);
+ }
+
+ @Override
+ protected void entryDeleted(Path path) throws IOException {
+ if (!isMonitoringFile(path)) {
+ return;
+ }
+
+ assert lockedFiles.contains(path);
+
+ lockedFiles.remove(path);
+ updateState(path, false);
+ }
+
+ @Override
+ protected void updateState(Path path, boolean isRunningDetected) {
+ // path is lock file path
+ // lock file -> image file + .lock
+ // updateState need image file path
+ File tempFile = path.toFile();
+ File imageFile = new File(tempFile.getAbsolutePath().substring(0,
+ tempFile.getAbsolutePath().lastIndexOf('.')));
+ super.updateState(imageFile.toPath(), isRunningDetected);
+ }
+}
\ No newline at end of file