INTERNAL: make sure all image thread is stopped when tracing is stopped 39/36539/3
authorgreatim <jaewon81.lim@samsung.com>
Mon, 9 Mar 2015 16:52:04 +0000 (01:52 +0900)
committerwoojin jung <woojin2.jung@samsung.com>
Mon, 16 Mar 2015 13:11:15 +0000 (06:11 -0700)
make sure all image processing thread is terminated when tracing is terminated.

Change-Id: I2ee1cddacbed8c725c69bf821045f11409ff67a9
Signed-off-by: greatim <jaewon81.lim@samsung.com>
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/ImageProcessingThread.java [new file with mode: 0644]
org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/LogParser.java

diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/ImageProcessingThread.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/ImageProcessingThread.java
new file mode 100644 (file)
index 0000000..71913c8
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ *  Dynamic Analyzer
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * Contributors:
+ * - S-Core Co., Ltd
+ * 
+ */
+package org.tizen.dynamicanalyzer.swap.logparser;
+
+import java.io.File;
+
+import org.tizen.dynamicanalyzer.common.AnalyzerConstants;
+import org.tizen.dynamicanalyzer.common.Global;
+import org.tizen.dynamicanalyzer.communicator.CommunicatorUtils;
+import org.tizen.dynamicanalyzer.communicator.DACommunicator;
+import org.tizen.dynamicanalyzer.constant.CommonConstants;
+import org.tizen.dynamicanalyzer.util.Logger;
+import org.tizen.dynamicanalyzer.utils.ImageUtil;
+import org.tizen.dynamicanalyzer.utils.ImageUtilSWT;
+import org.tizen.sdblib.service.SyncResult;
+
+public class ImageProcessingThread implements Runnable {
+       private static final int GET_IMAGE_TRY_COUNT = 5;
+       private static final int GET_IMAGE_TRY_INTERVAL = 1000;
+
+       private static final int SMALL_IMG_WIDTH = 40;
+       private static final int SMALL_IMG_HEIGHT = 66;
+
+       private static final int DEFAULT_IMG_WIDTH = 480;
+       private static final int DEFAULT_IMG_HEIGHT = 800;
+
+       private String sourcePath = null;
+       private int angle = 0;
+       private boolean isECS = false;
+
+       private LogParser parent = null;
+
+       public ImageProcessingThread(LogParser parent, String srcPath, int angle, boolean isECS) {
+               this.parent = parent;
+               this.sourcePath = srcPath;
+               this.angle = angle;
+               this.isECS = isECS;
+       }
+
+       @Override
+       public void run() {
+               if (isECS) {
+                       if (getImageFromECS(sourcePath)) {
+                               resizeImageFromECS(sourcePath, angle);
+                       }
+               } else {
+                       String fileName = getImageName(sourcePath);
+                       String to = Global.getProject().getSavePath() + File.separator
+                                       + AnalyzerConstants.IMAGE_FOLDER_NAME + File.separator + fileName;
+
+                       if (getImage(sourcePath, to)) {
+                               resizeImage(fileName, to, angle);
+                       }
+               }
+
+               // notify to LogParser that current image processing thread is finished
+               parent.setImageThreadFinished(Thread.currentThread());
+       }
+
+       private boolean getImageFromECS(String path) {
+               boolean ret = false;
+               int count = 0;
+
+               while (count < GET_IMAGE_TRY_COUNT) {
+                       File file = new File(path);
+                       if (file.exists()) {
+                               ret = true;
+                               break;
+                       } else {
+                               Logger.debug("Failed to get '" + path + "' file"); //$NON-NLS-1$ //$NON-NLS-2$
+                               try {
+                                       Thread.sleep(GET_IMAGE_TRY_INTERVAL);
+                                       count++;
+                               } catch (InterruptedException e) {
+                                       Logger.exception(e);
+                                       break;
+                               }
+                       }
+               }
+
+               return ret;
+       }
+
+       private boolean getImage(String from, String to) {
+               boolean ret = false;
+               int count = 0;
+
+               while (count < GET_IMAGE_TRY_COUNT) {
+                       SyncResult res = CommunicatorUtils.pull(from, to);
+                       if (null != res && res.isOk()) {
+                               DACommunicator.removeCommand(from);
+                               ret = true;
+                               break;
+                       } else {
+                               Logger.debug("Failed to get '" + from + "' file"); //$NON-NLS-1$ //$NON-NLS-2$
+                               try {
+                                       Thread.sleep(GET_IMAGE_TRY_INTERVAL);
+                                       count++;
+                               } catch (InterruptedException e) {
+                                       Logger.exception(e);
+                                       break;
+                               }
+                       }
+               }
+
+               return ret;
+       }
+
+       private void resizeImageFromECS(String path, int angle) {
+               String fileName = getImageName(path);
+
+               String smallImagePath = Global.getProject().getSavePath() + File.separator
+                               + AnalyzerConstants.IMAGE_FOLDER_NAME + File.separator
+                               + AnalyzerConstants.SMALL_IMAGE_FOLDER_NAME + File.separator + fileName;
+               ImageUtilSWT.transform(path, path, DEFAULT_IMG_WIDTH, DEFAULT_IMG_HEIGHT, angle);
+               if (angle == 90 || angle == 270) {
+                       ImageUtilSWT.resize(path, smallImagePath, SMALL_IMG_HEIGHT, SMALL_IMG_WIDTH);
+               } else {
+                       ImageUtilSWT.resize(path, smallImagePath, SMALL_IMG_WIDTH, SMALL_IMG_HEIGHT);
+               }
+       }
+
+       private void resizeImage(String fileName, String to, int angle) {
+               String smallImagePath = Global.getProject().getSavePath() + File.separator
+                               + AnalyzerConstants.IMAGE_FOLDER_NAME + File.separator
+                               + AnalyzerConstants.SMALL_IMAGE_FOLDER_NAME + File.separator + fileName;
+               ImageUtil.transform(to, to, DEFAULT_IMG_WIDTH, DEFAULT_IMG_HEIGHT, angle);
+               if (angle == 90 || angle == 270) {
+                       ImageUtil.resize(to, smallImagePath, SMALL_IMG_HEIGHT, SMALL_IMG_WIDTH);
+               } else {
+                       ImageUtil.resize(to, smallImagePath, SMALL_IMG_WIDTH, SMALL_IMG_HEIGHT);
+               }
+       }
+
+       private String getImageName(String fullPath) {
+               String name = null;
+               name = fullPath.substring(fullPath.lastIndexOf(CommonConstants.SLASH) + 1);
+               return name;
+       }
+}
index 903d814..6b0be95 100755 (executable)
@@ -36,7 +36,6 @@ import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.M
 import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.MSG_FUNCTION_EXIT;
 import static org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants.MSG_PROBE_SCREENSHOT;
 
-import java.io.File;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Deque;
@@ -48,9 +47,7 @@ import org.tizen.dynamicanalyzer.common.AnalyzerConstants;
 import org.tizen.dynamicanalyzer.common.AnalyzerManager;
 import org.tizen.dynamicanalyzer.common.Global;
 import org.tizen.dynamicanalyzer.common.SymbolManager;
-import org.tizen.dynamicanalyzer.communicator.CommunicatorUtils;
 import org.tizen.dynamicanalyzer.communicator.DACommunicator;
-import org.tizen.dynamicanalyzer.constant.CommonConstants;
 import org.tizen.dynamicanalyzer.control.DataThread;
 import org.tizen.dynamicanalyzer.nl.InformationViewLabels;
 import org.tizen.dynamicanalyzer.swap.channel.data.DataChannelConstants;
@@ -60,24 +57,18 @@ import org.tizen.dynamicanalyzer.swap.model.data.ScreenShotData;
 import org.tizen.dynamicanalyzer.ui.info.screenshot.SocketClient;
 import org.tizen.dynamicanalyzer.ui.summary.profiling.FunctionUsageProfiler;
 import org.tizen.dynamicanalyzer.util.Logger;
-import org.tizen.dynamicanalyzer.utils.ImageUtil;
-import org.tizen.dynamicanalyzer.utils.ImageUtilSWT;
-import org.tizen.sdblib.service.SyncResult;
 
 public class LogParser extends DataThread<List<LogData>> {
        private static LogParser instance = new LogParser();
 
        public static List<LogData> END_OF_QUEUE = new ArrayList<LogData>();
 
-       private static final int SMALL_IMG_WIDTH = 40;
-       private static final int SMALL_IMG_HEIGHT = 66;
-
-       private static final int DEFAULT_IMG_WIDTH = 480;
-       private static final int DEFAULT_IMG_HEIGHT = 800;
-
        // map for matching exit log with entry log
        private Map<Integer, Deque<Long>> functionEntryStackByTidMap = new HashMap<Integer, Deque<Long>>();
 
+       // list of image thread
+       private List<Thread> imageThreads = new ArrayList<Thread>();
+
        public static LogParser getInstance() {
                return instance;
        }
@@ -94,17 +85,47 @@ public class LogParser extends DataThread<List<LogData>> {
 
        @Override
        protected boolean workAfterStopNormal() {
+               // wait for all image thread is finished
+               synchronized (imageThreads) {
+                       while (!imageThreads.isEmpty()) {
+                               try {
+                                       imageThreads.wait();
+                               } catch (InterruptedException e) {
+                                       Logger.exception(e);
+                                       return false;
+                               }
+                       }
+               }
+
                return true;
        }
 
        @Override
        protected boolean workAfterStopForced() {
+               // force to stop image thread and
+               // wait for all image thread is finished
+               synchronized (imageThreads) {
+                       for (Thread entry : imageThreads) {
+                               entry.interrupt();
+                       }
+
+                       while (!imageThreads.isEmpty()) {
+                               try {
+                                       imageThreads.wait();
+                               } catch (InterruptedException e) {
+                                       Logger.exception(e);
+                                       return false;
+                               }
+                       }
+               }
+
                return true;
        }
 
        @Override
        protected void resetBeforeStart() {
                functionEntryStackByTidMap.clear();
+               imageThreads.clear();
        }
 
        @Override
@@ -239,101 +260,42 @@ public class LogParser extends DataThread<List<LogData>> {
                }
        }
 
-       private void processImage(final String from, final int angle) {
-               final String fileName = getImageName(from);
-               final String to = Global.getProject().getSavePath() + File.separator
-                               + AnalyzerConstants.IMAGE_FOLDER_NAME + File.separator + fileName;
+       private void processImage(String from, int angle) {
                if (angle != 0) {
                        Logger.debug("[ image rotate : " + angle + " ]");
                }
 
-               new Thread(null, new Runnable() {
-                       int count = 0;
-
-                       @Override
-                       public void run() {
-                               while (true && count < 5) {
-                                       SyncResult res = CommunicatorUtils.pull(from, to);
-                                       if (null != res && res.isOk()) {
-                                               DACommunicator.removeCommand(from);
-                                               /* image resizing */
-                                               String smallImagePath = Global.getProject().getSavePath() + File.separator
-                                                               + AnalyzerConstants.IMAGE_FOLDER_NAME + File.separator
-                                                               + AnalyzerConstants.SMALL_IMAGE_FOLDER_NAME + File.separator
-                                                               + fileName;
-                                               ImageUtil.transform(to, to, DEFAULT_IMG_WIDTH, DEFAULT_IMG_HEIGHT, angle);
-                                               if (angle == 90 || angle == 270) {
-                                                       ImageUtil.resize(to, smallImagePath, SMALL_IMG_HEIGHT, SMALL_IMG_WIDTH);
-                                               } else {
-                                                       ImageUtil.resize(to, smallImagePath, SMALL_IMG_WIDTH, SMALL_IMG_HEIGHT);
-                                               }
-
-                                               break;
-                                       } else {
-                                               Logger.debug("Failed to get '" + from + "' file"); //$NON-NLS-1$ //$NON-NLS-2$
-                                               try {
-                                                       Thread.sleep(1000);
-                                                       count++;
-                                               } catch (InterruptedException e) {
-                                                       Logger.exception(e);
-                                               }
-                                       }
-                               }
-                       }
-               }, AnalyzerConstants.MESSAGE_INTERNAL_IMAGE_THREAD).start();
+               Thread thread = new Thread(null, new ImageProcessingThread(this, from, angle, false),
+                               AnalyzerConstants.MESSAGE_INTERNAL_IMAGE_THREAD);
+               synchronized (imageThreads) {
+                       imageThreads.add(thread);
+               }
 
+               // The thread must be started after it is queued
+               thread.start();
        }
 
-       private void processImagefromECS(final String path, final int angle) {
-               final String fileName = getImageName(path);
-
+       private void processImagefromECS(String path, int angle) {
                if (angle != 0) {
                        Logger.debug("[ image rotate : " + angle + " ]");
                }
 
-               new Thread(null, new Runnable() {
-                       int count = 0;
-
-                       @Override
-                       public void run() {
-                               while (true && count < 5) {
-                                       File file = new File(path);
-                                       if (file.exists()) {
-                                               /* image resizing */
-                                               String smallImagePath = Global.getProject().getSavePath() + File.separator
-                                                               + AnalyzerConstants.IMAGE_FOLDER_NAME + File.separator
-                                                               + AnalyzerConstants.SMALL_IMAGE_FOLDER_NAME + File.separator
-                                                               + fileName;
-                                               ImageUtilSWT.transform(path, path, DEFAULT_IMG_WIDTH, DEFAULT_IMG_HEIGHT,
-                                                               angle);
-                                               if (angle == 90 || angle == 270) {
-                                                       ImageUtilSWT.resize(path, smallImagePath, SMALL_IMG_HEIGHT,
-                                                                       SMALL_IMG_WIDTH);
-                                               } else {
-                                                       ImageUtilSWT.resize(path, smallImagePath, SMALL_IMG_WIDTH,
-                                                                       SMALL_IMG_HEIGHT);
-                                               }
-
-                                               break;
-                                       } else {
-                                               Logger.debug("Failed to get '" + path + "' file"); //$NON-NLS-1$ //$NON-NLS-2$
-                                               try {
-                                                       Thread.sleep(1000);
-                                                       count++;
-                                               } catch (InterruptedException e) {
-                                                       Logger.exception(e);
-                                               }
-                                       }
-                               }
-                       }
-               }, AnalyzerConstants.MESSAGE_INTERNAL_IMAGE_THREAD).start();
+               Thread thread = new Thread(null, new ImageProcessingThread(this, path, angle, true),
+                               AnalyzerConstants.MESSAGE_INTERNAL_IMAGE_THREAD);
+               synchronized (imageThreads) {
+                       imageThreads.add(thread);
+               }
 
+               // The thread must be started after it is queued
+               thread.start();
        }
 
-       private String getImageName(String fullPath) {
-               String name = null;
-               name = fullPath.substring(fullPath.lastIndexOf(CommonConstants.SLASH) + 1);
-               return name;
+       // notified from image thread that the thread is finished
+       public void setImageThreadFinished(Thread finishedThread) {
+               synchronized (imageThreads) {
+                       imageThreads.remove(finishedThread);
+                       imageThreads.notifyAll();
+               }
        }
 
        private void updateLog(LogPackage logPack) {