monitoring: fix bugs and do addidional refatoring
authorSeokYeon Hwang <syeon.hwang@samsung.com>
Sat, 16 Jan 2016 04:52:03 +0000 (13:52 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Wed, 20 Jan 2016 04:52:34 +0000 (13:52 +0900)
WatchService inside LockFileMonitor is FileWatcher now. It will be used
by other file-based monitoring.
Fixed a bug on LaunchingMonitor when run as CLI. And some codes are
refined.

Change-Id: Ia7d822ededfac958863f52ca5855560335e2836d
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
13 files changed:
src/org/tizen/emulator/manager/EmulatorManager.java
src/org/tizen/emulator/manager/ui/dialog/CloneDialog.java
src/org/tizen/emulator/manager/ui/renewal/widgets/CreateVMCombo.java
src/org/tizen/emulator/manager/vms/VMLauncher.java
src/org/tizen/emulator/manager/vms/VMPropertyValue.java
src/org/tizen/emulator/manager/vms/monitor/FileWatchEventListener.java [new file with mode: 0644]
src/org/tizen/emulator/manager/vms/monitor/FileWatcher.java [new file with mode: 0644]
src/org/tizen/emulator/manager/vms/monitor/LaunchingMonitor.java
src/org/tizen/emulator/manager/vms/monitor/LockFileMonitor.java
src/org/tizen/emulator/manager/vms/monitor/MonitoringThread.java
src/org/tizen/emulator/manager/vms/monitor/PosixLockFileMonitor.java
src/org/tizen/emulator/manager/vms/monitor/RunningMonitor.java
src/org/tizen/emulator/manager/vms/monitor/WindowsLockFileMonitor.java

index 3640994..480e2c9 100755 (executable)
@@ -55,6 +55,7 @@ import org.tizen.emulator.manager.tool.SettingInfoFile;
 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.FileWatcher;
 import org.tizen.emulator.manager.vms.monitor.RunningMonitor;
 
 import com.sun.jna.Native;
@@ -354,6 +355,8 @@ public class EmulatorManager {
                                                CheckVT.class, CheckGPU.class, CheckSDCard.class, CheckWebcam.class);
                                checkers.startWork();
 
+                               // initializing monitors
+                               FileWatcher.initialize();
                                RunningMonitor.initialize();
                        }
 
index 8687698..08440da 100644 (file)
@@ -46,8 +46,8 @@ import org.tizen.emulator.manager.resources.ImageResources;
 import org.tizen.emulator.manager.resources.StringResources;
 import org.tizen.emulator.manager.ui.MainDialog;
 import org.tizen.emulator.manager.vms.VMProperty;
-import org.tizen.emulator.manager.vms.helper.VMWorkerException;
 import org.tizen.emulator.manager.vms.helper.HelperClass;
+import org.tizen.emulator.manager.vms.helper.VMWorkerException;
 
 public class CloneDialog {
        private VMProperty property = null;
@@ -58,7 +58,7 @@ public class CloneDialog {
        private Button cancelButton  = null;
 
        private String vmName   = null;
-       
+
        public CloneDialog(VMProperty prop) {
                property = prop;
        }
@@ -98,10 +98,10 @@ public class CloneDialog {
                cancelButton.setImage(ImageResources.CANCEL.getImage());
 
                addListener();
-               
+
                dialog.open();
        }
-       
+
        private void addListener() {
                name.addModifyListener(new ModifyListener() {
                        @Override
@@ -110,7 +110,7 @@ public class CloneDialog {
                                checkImageName();
                        }
                });
-               
+
                confirmButton.addSelectionListener(new SelectionListener() {
                        @Override
                        public void widgetDefaultSelected(SelectionEvent event) {
@@ -121,7 +121,7 @@ public class CloneDialog {
                                String message = ""; //$NON-NLS-1$
                                try {
                                        property.getWorker().cloneVM(vmName);
-                                       //message = "Emulator cloning completed!";      
+                                       //message = "Emulator cloning completed!";
                                } catch (VMWorkerException e) {
                                        message = e.getMessage();
                                        msg.openInfoDialog(message);
@@ -132,9 +132,9 @@ public class CloneDialog {
                                MainDialog.refreshVMPropertyList(true);
                                //mainDialog.vmsTree.setSelectProperty(property);
                        }
-                       
+
                });
-               
+
                cancelButton.addSelectionListener(new SelectionListener() {
                        @Override
                        public void widgetDefaultSelected(SelectionEvent arg) {
@@ -146,10 +146,10 @@ public class CloneDialog {
                                MainDialog.refreshVMPropertyList(true);
                                //mainDialog.vmsTree.setSelectProperty(property);
                        }
-                       
+
                });
        }
-       
+
        private void checkImageName() {
                /*
                if (vmName.length() > VMPropertyView.MAX_NAME_LEN) {
index 5bc541e..290193e 100644 (file)
@@ -140,7 +140,8 @@ public class CreateVMCombo extends Canvas {
        }
 
        public void add(ProfileButton item, int index) {
-               assert item == null;
+               assert item != null;
+
                if (index < 0 || index > items.size()) {
                        // TODO
                        return;
index f80a133..4742228 100644 (file)
@@ -53,7 +53,6 @@ import org.tizen.emulator.manager.vms.option.NetProxyOption;
 import org.tizen.emulator.manager.vms.option.OPTION_KEY;
 
 public class VMLauncher {
-
        public static boolean Launch(VMProperty property, boolean wait, String path)
                        throws VMLauncherException {
 
@@ -65,17 +64,16 @@ public class VMLauncher {
 
                String emulatorPath = property.getPropertyValue().baseImage.getPlatform().getEmulatorPath();
 
-               Process process = launch(property.getName(), emulatorPath, cmd, path);
+               Process process = launchInternal(property.getName(), emulatorPath, cmd, path);
                if (process == null) {
                        return false;
                }
 
                LaunchingMonitor monitor = new LaunchingMonitor(property, process);
-
                if (!wait) {
-                       monitor.asyncExecute(8); // timeout : 8 seconds
+                       monitor.asyncExecute();
 
-                       return true;
+                       return true; // we can not determine whether VM is launched successfully or not
                }
 
                return monitor.execute();
@@ -159,7 +157,7 @@ public class VMLauncher {
                }
        }
 
-       public static Process launch(String vmName, String emulatorPath,
+       private static Process launchInternal(String vmName, String emulatorPath,
                        List<String> cmd, String binPath) {
                ProcessBuilder pb = new ProcessBuilder(cmd);
                EMLogger.getLogger().log(Level.INFO, "Command list for ProcessBuilder");
index 29d083b..e5f8463 100644 (file)
@@ -134,7 +134,7 @@ public class VMPropertyValue implements Cloneable {
         * @param property property of emulator
         */
        public VMPropertyValue(VMProperty property) {
-               assert property == null;
+               assert property != null;
 
                if (property != null) {
                        this.template = property;
diff --git a/src/org/tizen/emulator/manager/vms/monitor/FileWatchEventListener.java b/src/org/tizen/emulator/manager/vms/monitor/FileWatchEventListener.java
new file mode 100644 (file)
index 0000000..0a4a743
--- /dev/null
@@ -0,0 +1,10 @@
+package org.tizen.emulator.manager.vms.monitor;
+
+import java.nio.file.Path;
+
+interface FileWatchEventListener {
+       void preexistingDirectoryFound(Path dir);
+       void entryCreated(Path path);
+       void entryModified(Path path);
+       void entryDeleted(Path path);
+}
diff --git a/src/org/tizen/emulator/manager/vms/monitor/FileWatcher.java b/src/org/tizen/emulator/manager/vms/monitor/FileWatcher.java
new file mode 100644 (file)
index 0000000..e6ece6c
--- /dev/null
@@ -0,0 +1,168 @@
+package org.tizen.emulator.manager.vms.monitor;
+
+import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitOption;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+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;
+
+public final class FileWatcher implements Runnable, FileWatchEventListener {
+       static FileWatcher instance;
+
+       private final WatchService watcher;
+       private final Map<WatchKey, Path> keys;
+       private final Path watchPath;
+       private final List<FileWatchEventListener> eventListener;
+
+
+       public static synchronized void initialize() throws IOException {
+               // We do not use static block since we want initialize FileWatcher explicitly.
+
+               // do not initialize again
+               assert instance == null;
+
+               instance = new FileWatcher();
+               instance.registerDefaultPath();
+
+               new MonitoringThread(instance, "FileWatcher").start();
+       }
+
+       private FileWatcher() throws IOException {
+               watcher = FileSystems.getDefault().newWatchService();
+               keys = new HashMap<WatchKey, Path>();
+               // XXX: We concern only image files / lockfiles under Tizen sdk data VMS path
+               watchPath = Paths.get(FilePathResources.getTizenVmsPath());
+               eventListener = new ArrayList<FileWatchEventListener>();
+
+               assert Files.exists(watchPath);
+       }
+
+       static final void addListener(FileWatchEventListener listener) throws IOException {
+               instance.eventListener.add(listener);
+               instance.traverseWatchedDirectories(listener);
+       }
+
+       private void registerDirectory(Path path) {
+               assert Files.isDirectory(path);
+
+               WatchKey key = null;
+               try {
+                       key = path.register(watcher, StandardWatchEventKinds.ENTRY_CREATE,
+                                       StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
+                       keys.put(key, path);
+               } catch (IOException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       private void traverseWatchedDirectories(final FileWatchEventListener listener) throws IOException {
+               // we concern *one* depth sub-directories only
+               Files.walkFileTree(watchPath, Collections.<FileVisitOption> emptySet(), 2,
+                               new SimpleFileVisitor<Path>() {
+                       @Override
+                       public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+                                       throws IOException
+                       {
+                               listener.preexistingDirectoryFound(dir);
+
+                               return FileVisitResult.CONTINUE;
+                       }
+               });
+       }
+
+       private void registerDefaultPath() throws IOException {
+               WatchKey key = null;
+
+               try {
+                       key = watchPath.register(watcher, StandardWatchEventKinds.ENTRY_CREATE,
+                               StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
+               } catch(IOException e) {
+                       // FIXME
+                       e.printStackTrace();
+               }
+               keys.put(key, watchPath);
+
+               addListener(this);
+       }
+
+       @Override
+       public void run() {
+               WatchKey key = null;
+
+               try {
+                       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());
+
+                                       for (FileWatchEventListener listener : eventListener) {
+                                               if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
+                                                       listener.entryCreated(path);
+                                               }
+
+                                               if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
+                                                       listener.entryModified(path);
+                                               }
+
+                                               if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
+                                                       listener.entryDeleted(path);
+                                               }
+                                       }
+                               }
+
+                               if(!key.reset()) {
+                                       keys.remove(key);
+                               }
+                       }
+               } catch (InterruptedException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @Override
+       public void preexistingDirectoryFound(Path dir) {
+               registerDirectory(dir);
+       }
+
+       @Override
+       public void entryCreated(Path path) {
+               if (Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
+                       if (path.getParent().equals(watchPath)) {
+                               registerDirectory(path);
+                       }
+                       return;
+               }
+       }
+
+       @Override
+       public void entryModified(Path path) {
+               // do nothing
+       }
+
+       @Override
+       public void entryDeleted(Path path) {
+               // do nothing
+       }
+}
index cbfdb8a..cb01e3a 100644 (file)
@@ -5,7 +5,6 @@
  *
  * Contact:
  * JiHye Kim <jihye1128.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
  * SeokYeon Hwang <syeon.hwang@samsung.com>
  *
  * This program is free software; you can redistribute it and/or
 
 package org.tizen.emulator.manager.vms.monitor;
 
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
 import java.util.logging.Level;
 
 import org.eclipse.swt.widgets.Display;
@@ -46,192 +41,98 @@ import org.tizen.emulator.manager.vms.VMProperty;
 public final class LaunchingMonitor implements Runnable {
        private final VMProperty property;
        private final Process process;
-       private Output stdOut = null;
-       private Output stdErr = null;
+
+       private int timeoutSec;
+       private int exitValue = -1;
 
        public LaunchingMonitor(VMProperty property, Process process) {
+               assert property != null;
+               assert process != null;
+
                this.property = property;
                this.process = process;
        }
 
-       public boolean execute() {
-               if (process == null || property == null) {
-                       return false;
-               }
-
-               boolean success = true;
-
-               BufferedReader readerOut = new BufferedReader(new InputStreamReader(process.getInputStream()));
-               BufferedReader readerError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
-
-               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$
-
-               t1.start();
-               t2.start();
-
-               try {
-                       int exitValue = process.waitFor();
-
-                       EMLogger.getLogger().warning(
-                                       String.format(
-                                                       "Emulator has been terminated. Exit value: %X(%d)", //$NON-NLS-1$
-                                                       exitValue, exitValue));
-                       stdOut.printMessageList();
-                       stdErr.printMessageList();
-
-                       if (exitValue != 0) {
-                               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$
-                               if (!EmulatorManager.isConsoleMode()) {
-                                       Display.getDefault().asyncExec(new Runnable() {
-
-                                               @Override
-                                               public void run() {
-                                                       // TODO
-                                                       new MessageDialog()
-                                                                       .openWarningDialog(Messages.getString("MonitoringEmulator.RunningError.0") //$NON-NLS-1$
-                                                                                       + StringResources.NEW_LINE
-                                                                                       + Messages.getString("MonitoringEmulator.RunningError.1") //$NON-NLS-1$
-                                                                                       + StringResources.NEW_LINE
-                                                                                       + Messages.getString("MonitoringEmulator.RunningError.2") //$NON-NLS-1$
-                                                                                       + property.getName()
-                                                                                       + Messages.getString("MonitoringEmulator.RunningError.3")); //$NON-NLS-1$
-                                               }
-
-                                       });
+       private boolean executeInternal() {
+               Thread waitingThread = new MonitoringThread(new Runnable() {
+                       @Override
+                       public void run() {
+                               try {
+                                       exitValue = process.waitFor();
+                               } catch (InterruptedException e) {
+                                       // launched successfully
+                                       EMLogger.getLogger().log(Level.FINE, e.getMessage());
                                }
                        }
-               } catch (InterruptedException e) {
-                       // launched successfully
-                       EMLogger.getLogger().log(Level.FINE, e.getMessage());
-               }
+               }, "Waiting VM process " + property.getName());
 
-               stdOut.setDone();
-               stdErr.setDone();
+               waitingThread.start();
 
                try {
-                       t1.join();
-                       t2.join();
+                       waitingThread.join(1000 * timeoutSec);
                } catch (InterruptedException e) {
-                       EMLogger.getLogger().warning(e.getMessage());
-               }
-
-               // close
-               try {
-                       if (readerOut != null) {
-                               readerOut.close();
-                       }
-                       if (readerError != null) {
-                               readerError.close();
-                       }
-               } catch (IOException e) {
-                       EMLogger.getLogger().warning(e.getMessage());
+                       e.printStackTrace();
                }
 
-               return success;
-       }
+               if (exitValue == -1) {
+                       // VM process may be running well. Stop monitoring VM process.
+                       waitingThread.interrupt();
 
-       public void asyncExecute(int timeoutSec) {
-               new MonitoringThread(this, "LunchingMonitor", timeoutSec).start();
-       }
+                       return true;
+               }
 
-       @Override
-       public void run() {
-               property.setState(VMProperty.State.LAUNCHING);
+               if (exitValue == 0) {
+                       // VM process exit in timeout.
+                       EMLogger.getLogger().warning(
+                                       String.format(
+                                                       "Emulator has been terminated in " + timeoutSec + "seconds.")); //$NON-NLS-1$
 
-               if (!execute()) {
-                       property.setState(VMProperty.State.READY);
+                       // TODO: check about it.
+                       return true;
                }
-       }
-}
 
-final class Output implements Runnable {
-       private BufferedReader reader;
-       private String vmName;
-       private final ArrayList<String> list = new ArrayList<String>();
+               // VM process may be terminated with error.
+               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$
+               if (!EmulatorManager.isConsoleMode()) {
+                       Display.getDefault().asyncExec(new Runnable() {
+                               @Override
+                               public void run() {
+                                       // TODO
+                                       new MessageDialog()
+                                       .openWarningDialog(Messages.getString("MonitoringEmulator.RunningError.0") //$NON-NLS-1$
+                                                       + StringResources.NEW_LINE
+                                                       + Messages.getString("MonitoringEmulator.RunningError.1") //$NON-NLS-1$
+                                                       + StringResources.NEW_LINE
+                                                       + Messages.getString("MonitoringEmulator.RunningError.2") //$NON-NLS-1$
+                                                       + property.getName()
+                                                       + Messages.getString("MonitoringEmulator.RunningError.3")); //$NON-NLS-1$
+                               }
+                       });
+               }
 
-       private boolean isDone = false;
-       private boolean error = false;
+               return false;
+       }
 
+       public boolean execute() {
+               timeoutSec = 8; // timeout : 8 seconds
 
-       Output(BufferedReader reader, String name) {
-               this.reader = reader;
-               this.vmName = name;
+               return executeInternal();
        }
 
-       Output(InputStreamReader in, String name) {
-               this.reader = new BufferedReader(in);
-               this.vmName = name;
-       }
+       public void asyncExecute() {
+               timeoutSec = 8; // timeout : 8 seconds
 
-       void setDone() {
-               this.isDone = true;
+               new MonitoringThread(this, "LaunchingMonitor").start();
        }
 
        @Override
        public void run() {
-               String msg = ""; //$NON-NLS-1$
-
-               if (reader != null) {
-                       char c;
-                       int i;
-                       try {
-                               do {
-                                       if (reader.ready()) { // To avoid blocking in following read()
-                                               i = (reader.read());
-                                               if (i == -1) { // EOF
-                                                       break;
-                                               }
-                                               if (Thread.currentThread().getName()
-                                                               .equals(vmName + "STDERR")) { //$NON-NLS-1$
-                                                       c = (char) i;
-                                                       msg += c;
-                                                       if (msg.contains(StringResources.NEW_LINE)) {
-                                                               // Remove NEW_LINE
-                                                               msg = msg.substring(0, msg.length()
-                                                                               - StringResources.NEW_LINE.length());
-                                                               list.add(msg); // Add msg from STDERR.
-                                                               msg = ""; //$NON-NLS-1$
-                                                       }
-                                               }
-
-                                       } else {
-                                               try {
-                                                       Thread.sleep(100);
-                                               } catch (InterruptedException e) {
-                                                       // TODO Auto-generated catch block
-                                                       e.printStackTrace();
-                                               }
-                                       }
-                               } while (!isDone);
-                       } catch (IOException e) {
-                               EMLogger.getLogger().info(e.getMessage());
-                       } finally {
-                               try {
-                                       reader.close();
-                               } catch (IOException e) {
-                                       EMLogger.getLogger().warning(e.getMessage());
-                               }
-                       }
-               }
+               property.setState(VMProperty.State.LAUNCHING);
 
-               if (error) {
-                       for (String s : list) {
-                               if (s != null && !s.isEmpty()) {
-                                       EMLogger.getLogger().warning(
-                                                       "Print Log From Emulator: " + s); //$NON-NLS-1$
-                               }
-                       }
+               if (!executeInternal()) {
+                       property.setState(VMProperty.State.READY);
                }
        }
-
-       public void printMessageList() {
-               error = true;
-       }
 }
\ No newline at end of file
index 1290ab9..007ae0a 100644 (file)
 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;
 
+abstract class LockFileMonitor extends RunningMonitor implements FileWatchEventListener {
+       protected final List<Path> lockedFiles;
 
        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();
-                       }
-               }
-
+               lockedFiles = new ArrayList<Path>();
        }
 }
\ No newline at end of file
index 5c1922c..40c409b 100644 (file)
 
 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) {
+       public MonitoringThread(Runnable runnable, String name) {
                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
index 28d44d5..e46d607 100644 (file)
@@ -32,10 +32,12 @@ 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.DirectoryStream;
+import java.nio.file.FileSystems;
 import java.nio.file.Files;
-import java.nio.file.LinkOption;
 import java.nio.file.NoSuchFileException;
 import java.nio.file.Path;
+import java.nio.file.PathMatcher;
 import java.nio.file.StandardOpenOption;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -44,59 +46,30 @@ 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>());
+       private final PathMatcher matcher;
+       protected final List<Path> monitoredFiles;
 
-       PosixLockFileMonitor() throws IOException {
-               super();
-
-               new MonitoringThread(new LockMonitorThread(), "PosixLockMonitor").start();
-       }
 
-       @Override
-       protected boolean isMonitoringFile(Path path) {
+       PosixLockFileMonitor() throws IOException {
+               StringBuffer matchExtension = new StringBuffer();
                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;
+                       matchExtension.append(arch.toString()).append(",");
                }
 
-               if (!Files.isRegularFile(path)) {
-                       return;
-               }
-
-               assert !monitoredFiles.contains(path);
+               matcher = FileSystems.getDefault().getPathMatcher("glob:*.{" + matchExtension.toString() + "}");
+               monitoredFiles =
+                               Collections.synchronizedList(new ArrayList<Path>());
+               FileWatcher.addListener(this);
 
-               monitoredFiles.add(path);
+               new MonitoringThread(new LockMonitorThread(), "PosixLockMonitor").start();
        }
 
-       @Override
-       protected void entryDeleted(Path path) throws IOException {
-               if (!Files.isRegularFile(path)) {
-                       return;
+       private boolean isMonitoringFile(Path path) {
+               if (matcher.matches(path) && Files.isRegularFile(path)) {
+                       return true;
                }
 
-               boolean result = monitoredFiles.remove(path);
-
-               assert result;
+               return false;
        }
 
        private synchronized boolean examineLock(Path path) throws IOException {
@@ -124,6 +97,42 @@ final class PosixLockFileMonitor extends LockFileMonitor {
                return true;
        }
 
+       @Override
+       public void preexistingDirectoryFound(Path dir) {
+;              try {
+                       DirectoryStream<Path> stream = Files.newDirectoryStream(dir);
+
+                       for (Path path : stream) {
+                               if (Files.isRegularFile(path) && isMonitoringFile(path)) {
+                                       monitoredFiles.add(path);
+                               }
+                       }
+               } catch (IOException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @Override
+       public  void entryCreated(Path path) {
+               if (!isMonitoringFile(path)) {
+                       return;
+               }
+
+               assert !monitoredFiles.contains(path);
+
+               monitoredFiles.add(path);
+       }
+
+       @Override
+       public void entryModified(Path path) {
+               // do nothing
+       }
+
+       @Override
+       public void entryDeleted(Path path) {
+               monitoredFiles.remove(path);
+       }
+
        private final class LockMonitorThread implements Runnable {
                @Override
                public void run() {
index 1753395..40fee9d 100644 (file)
@@ -43,7 +43,7 @@ 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 {
+public abstract class RunningMonitor {
        private static Thread updater;
 
        private static Map<Path, MonitoringState<Path>> monitoredVMs = new HashMap<Path, MonitoringState<Path>>();
@@ -121,6 +121,8 @@ public class RunningMonitor {
        }
 
        public static synchronized void initialize() throws IOException {
+               // FileWatcher had been initialized.
+               assert FileWatcher.instance != null;
                // do not initialize again
                assert updater == null;
 
index 056bf6b..3e1d386 100644 (file)
 
 package org.tizen.emulator.manager.vms.monitor;
 
-import java.io.File;
 import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystems;
 import java.nio.file.Files;
-import java.nio.file.LinkOption;
 import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.Paths;
 
 final class WindowsLockFileMonitor extends LockFileMonitor {
+       private final PathMatcher matcher;
+
+
        WindowsLockFileMonitor() throws IOException {
-               super();
+               matcher = FileSystems.getDefault().getPathMatcher("glob:*.java");
        }
 
-       @Override
-       protected boolean isMonitoringFile(Path path) {
-               if (path.toString().endsWith(".lock")) {
+       private boolean isMonitoringFile(Path path) {
+               if (matcher.matches(path) && Files.isRegularFile(path)) {
                        return true;
                }
 
@@ -50,23 +54,25 @@ final class WindowsLockFileMonitor extends LockFileMonitor {
        }
 
        @Override
-       protected void handleExistFile(Path path) {
-               // all .lock files are locked
-               lockedFiles.add(path);
-               updateState(path, true);
-       }
+       public void preexistingDirectoryFound(Path dir) {
+               try {
+                       DirectoryStream<Path> stream = Files.newDirectoryStream(dir);
 
-       @Override
-       protected void entryCreated(Path path) throws IOException {
-               if (Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
-                       if (path.getParent().equals(lockfilePath)) {
-                               registerDirectory(path);
+                       for (Path path : stream) {
+                               if (isMonitoringFile(path)) {
+                                       // all .lock files are locked
+                                       lockedFiles.add(path);
+                                       updateState(path, true);
+                               }
                        }
-
-                       return;
+               } catch (IOException e) {
+                       e.printStackTrace();
                }
+       }
 
-               if (!isMonitoringFile(path) || !Files.isRegularFile(path)) {
+       @Override
+       public void entryCreated(Path path) {
+               if (!isMonitoringFile(path)) {
                        return;
                }
 
@@ -77,7 +83,12 @@ final class WindowsLockFileMonitor extends LockFileMonitor {
        }
 
        @Override
-       protected void entryDeleted(Path path) throws IOException {
+       public void entryModified(Path path) {
+               // do nothing
+       }
+
+       @Override
+       public void entryDeleted(Path path) {
                if (!isMonitoringFile(path)) {
                        return;
                }
@@ -93,9 +104,8 @@ final class WindowsLockFileMonitor extends LockFileMonitor {
                // 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);
+               Path imagePath = Paths.get(path.toString().substring(0,
+                               path.toString().lastIndexOf('.')));
+               super.updateState(imagePath, isRunningDetected);
        }
 }
\ No newline at end of file