From 19a4050ff86fc0467dc2e783aff5a7f3de6bc1ce Mon Sep 17 00:00:00 2001 From: greatim Date: Mon, 26 May 2014 12:43:11 +0900 Subject: [PATCH] [Title] add MSG_PROCESS_COMM for web app, refactor db connection(multi-connection) [Desc.] [Issue] Change-Id: Ie46eaba1f7390fc8fbe1b440a8ee6f4cf0c1ebe2 --- .../database/SqlConnectionManager.java | 255 +++++++++++++++++---- .../swap/channel/data/DataChannelConstants.java | 1 + .../swap/channel/data/ProcessInfoPackage.java | 9 + .../swap/logparser/MessageParser.java | 22 ++ .../dynamicanalyzer/ui/toolbar/ToolbarArea.java | 14 +- 5 files changed, 251 insertions(+), 50 deletions(-) diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/database/SqlConnectionManager.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/database/SqlConnectionManager.java index 2940b73..46f8a6e 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/database/SqlConnectionManager.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/database/SqlConnectionManager.java @@ -10,6 +10,8 @@ import java.sql.SQLWarning; import java.sql.Statement; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; import org.tizen.dynamicanalyzer.util.CommonUtil; import org.tizen.dynamicanalyzer.util.DALogger; @@ -17,26 +19,77 @@ import org.tizen.dynamicanalyzer.util.DALogger; public class SqlConnectionManager { private static final DALogger DA_LOG = DALogger.getInstance(); - private static Connection connection = null; - + // apply multi connection of DB + private static final int CONNECTION_COUNT_UPDATE = 8; + private static final int CONNECTION_COUNT_QUERY = 8; + private static BlockingQueue updateConnections = null; + private static BlockingQueue queryConnections = null; + private static int realUpdateConnCount = 0; + private static int realQueryConnCount = 0; + + // DATABASE state + private enum State { + NOT_CONNECTED, + CONNECTED, + TO_BE_CLOSED + } + + private static State state = State.NOT_CONNECTED; + public static boolean establishConnection(String dbFilePath) { boolean result = true; try { synchronized (SqlConnectionManager.class) { - if (connection == null) { + if (updateConnections == null && queryConnections == null) { + updateConnections = new LinkedBlockingQueue(); + queryConnections = new LinkedBlockingQueue(); + realUpdateConnCount = 0; + realQueryConnCount = 0; + Class.forName("org.hsqldb.jdbcDriver"); String dbUrl = "jdbc:hsqldb:" + dbFilePath - + ";shutdown=false;hsqldb.default_table_type=cached;hsqldb.large_data=true;hdqldb.log_data=false"; //$NON-NLS-1$ - connection = DriverManager.getConnection(dbUrl, "SA", ""); - SQLWarning warning = connection.getWarnings(); - while (warning != null) { - DA_LOG.debug("[DB] Message: " + warning.getMessage()); - DA_LOG.debug("[DB] SQL state: " + warning.getSQLState()); - DA_LOG.debug("[DB] Vendor code: " - + warning.getErrorCode()); - warning = warning.getNextWarning(); + + ";shutdown=false;hsqldb.default_table_type=cached" + + ";hsqldb.tx=mvcc;hsqldb.large_data=true;hdqldb.log_data=false"; //$NON-NLS-1$ + + Connection conn; + // establish update connection pool + for (int i = 0; i < CONNECTION_COUNT_UPDATE; i++) { + conn = DriverManager.getConnection(dbUrl, "SA", ""); + updateConnections.offer(conn); + realUpdateConnCount++; + + SQLWarning warning = conn.getWarnings(); + while (warning != null) { + DA_LOG.debug("[DB][" + i + "] Message: " + + warning.getMessage()); + DA_LOG.debug("[DB][" + i + "] SQL state: " + + warning.getSQLState()); + DA_LOG.debug("[DB][" + i + "] Vendor code: " + + warning.getErrorCode()); + warning = warning.getNextWarning(); + } } + + // establish query connection pool + for (int i = 0; i < CONNECTION_COUNT_QUERY; i++) { + conn = DriverManager.getConnection(dbUrl, "SA", ""); + queryConnections.offer(conn); + realQueryConnCount++; + + SQLWarning warning = conn.getWarnings(); + while (warning != null) { + DA_LOG.debug("[DB][" + i + "] Message: " + + warning.getMessage()); + DA_LOG.debug("[DB][" + i + "] SQL state: " + + warning.getSQLState()); + DA_LOG.debug("[DB][" + i + "] Vendor code: " + + warning.getErrorCode()); + warning = warning.getNextWarning(); + } + } + + state = State.CONNECTED; } } } catch (ClassNotFoundException e) { @@ -44,7 +97,7 @@ public class SqlConnectionManager { } catch (SQLException e) { e.printStackTrace(); } finally { - if (connection == null) + if (updateConnections == null || queryConnections == null) result = false; else result = true; @@ -55,61 +108,162 @@ public class SqlConnectionManager { public static void closeConnection() { synchronized (SqlConnectionManager.class) { - if (connection != null) { - try { - Statement st = connection.createStatement(); - st.execute("SHUTDOWN"); - CommonUtil.tryClose(st); - connection.close(); - } catch (SQLException se) { - if (!se.getSQLState().equals("XJ015")) { - DA_LOG.debug("DB did not shutdown normally"); + // set close state + // this value prevent other thread from getting connection + state = State.TO_BE_CLOSED; + + // close update connection + if (updateConnections != null) { + synchronized (updateConnections) { + while (updateConnections.size() != realUpdateConnCount) { + // wait until other execution is finished + try { + updateConnections.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + // close all connection + Connection conn; + while ((conn = updateConnections.poll()) != null) { + try { + conn.close(); + } catch (SQLException e) { + e.printStackTrace(); } } - connection = null; } + + // close query connection + if (queryConnections != null) { + synchronized (queryConnections) { + while (queryConnections.size() != realQueryConnCount) { + // wait until other execution is finished + try { + queryConnections.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + // close all connection + Connection conn; + while ((conn = queryConnections.poll()) != null) { + // if it is last connection of database + if(queryConnections.size() == 0) { + Statement st = null; + try { + st = conn.createStatement(); + st.execute("SHUTDOWN"); + } catch (SQLException se) { + if (!se.getSQLState().equals("XJ015")) { + DA_LOG.debug("DB did not shutdown normally"); + } + } finally { + CommonUtil.tryClose(st); + } + } + + try { + conn.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } + + updateConnections = null; + queryConnections = null; + + state = State.NOT_CONNECTED; } } - public static boolean isConnected() { - return (connection != null); - } + private static Connection getUpdateConnection() { + Connection retConn = null; + if (state == State.CONNECTED) { + try { + retConn = updateConnections.take(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } - private static void semaphoreAcquire() { + return retConn; + } + private static void putUpdateConnection(Connection conn) { + if (conn != null) { + try { + updateConnections.put(conn); + synchronized (updateConnections) { + updateConnections.notifyAll(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } } - private static void semaphoreRelease() { + private static Connection getQueryConnection() { + Connection retConn = null; + if (state == State.CONNECTED) { + try { + retConn = queryConnections.take(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + return retConn; + } + private static void putQueryConnection(Connection conn) { + if (conn != null) { + try { + queryConnections.put(conn); + synchronized (queryConnections) { + queryConnections.notifyAll(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } } public static void executeUpdate(String statement) { + Connection conn = null; Statement sm = null; try { - if (connection != null) { - semaphoreAcquire(); - sm = connection.createStatement(); + conn = getUpdateConnection(); + if (conn != null) { + sm = conn.createStatement(); sm.executeUpdate(statement); + putUpdateConnection(conn); } } catch (SQLException e) { e.printStackTrace(); } finally { CommonUtil.tryClose(sm); - semaphoreRelease(); } } public static void executePreparedWithType(String query, List> data, List columnType) { + Connection conn = null; PreparedStatement prep = null; if (data.size() == 0) return; try { - if (connection != null) { + conn = getUpdateConnection(); + if (conn != null) { int batchCount = 0; - prep = connection.prepareStatement(query); + prep = conn.prepareStatement(query); // count ? in query int questionCount = 0; @@ -128,7 +282,7 @@ public class SqlConnectionManager { return; } - connection.setAutoCommit(false); + conn.setAutoCommit(false); for (int k = 0; k < datasize; k++) { List row = data.get(k); @@ -214,8 +368,10 @@ public class SqlConnectionManager { if (batchCount > 0) prep.executeBatch(); - connection.commit(); - connection.setAutoCommit(true); + conn.commit(); + conn.setAutoCommit(true); + + putUpdateConnection(conn); } } catch (SQLException e) { e.printStackTrace(); @@ -230,15 +386,17 @@ public class SqlConnectionManager { // (no need to check the type of each column) public static void executePreparedWithInterface(String query, List> data, IPreparedStatement ip) { + Connection conn = null; PreparedStatement prep = null; if (data.size() == 0) return; try { - if (connection != null) { + conn = getUpdateConnection(); + if (conn != null) { int batchCount = 0; - prep = connection.prepareStatement(query); + prep = conn.prepareStatement(query); // count ? in query int questionCount = 0; @@ -251,7 +409,7 @@ public class SqlConnectionManager { // set data into prepared statement int datasize = data.size(); - connection.setAutoCommit(false); + conn.setAutoCommit(false); for (int k = 0; k < datasize; k++) { List row = data.get(k); @@ -273,8 +431,10 @@ public class SqlConnectionManager { if (batchCount > 0) prep.executeBatch(); - connection.commit(); - connection.setAutoCommit(true); + conn.commit(); + conn.setAutoCommit(true); + + putUpdateConnection(conn); } } catch (SQLException e) { e.printStackTrace(); @@ -284,13 +444,15 @@ public class SqlConnectionManager { } public static List> executeQuery(String query) { + Connection conn = null; Statement sm = null; ResultSet rs = null; List> result = null; + try { - if (connection != null) { - semaphoreAcquire(); - sm = connection.createStatement(); + conn = getQueryConnection(); + if (conn != null) { + sm = conn.createStatement(); rs = sm.executeQuery(query); if (rs != null) { result = new ArrayList>(); @@ -326,12 +488,13 @@ public class SqlConnectionManager { result.add(rowData); } } + + putQueryConnection(conn); } } catch (SQLException e) { e.printStackTrace(); } finally { CommonUtil.tryClose(sm); - semaphoreRelease(); } return result; diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/channel/data/DataChannelConstants.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/channel/data/DataChannelConstants.java index c9dc980..a32ad6a 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/channel/data/DataChannelConstants.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/channel/data/DataChannelConstants.java @@ -41,6 +41,7 @@ public class DataChannelConstants { public final static int MSG_CONTEXT_SWITCH_EXIT = 0x0011; public final static int MSG_PROCESS_MAP = 0x0012; public final static int MSG_PROCESS_UNMAP = 0x0013; + public final static int MSG_PROCESS_COMM = 0x0014; public static final int LOG_USER_FUNCTION = 0x002C; //44 public static final int LOG_CONTEXT_SWITCH = 0x002D; //45 diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/channel/data/ProcessInfoPackage.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/channel/data/ProcessInfoPackage.java index 5d215a6..fb5ea54 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/channel/data/ProcessInfoPackage.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/channel/data/ProcessInfoPackage.java @@ -12,6 +12,7 @@ public class ProcessInfoPackage { private String targetBinaryPath = null; private int functionEntryInsertLogCount = 0; private boolean dropLog = false; + private String cmdLineName = null; private List processSnapshots = new ArrayList(); @@ -39,6 +40,14 @@ public class ProcessInfoPackage { this.targetBinaryPath = localBinaryPath; } + public String getCmdLineName() { + return cmdLineName; + } + + public void setCmdLineName(String cmdLineName) { + this.cmdLineName = cmdLineName; + } + public List getProcessSnapshots() { return processSnapshots; } diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/MessageParser.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/MessageParser.java index 13f470d..d3a9593 100755 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/MessageParser.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/swap/logparser/MessageParser.java @@ -169,10 +169,13 @@ public class MessageParser { long highAddr = 0; String targetBinaryPath = null; int dependantLibCount = 0; + String commandLineName = null; int index = MSG_HEADER_SIZE; pid = ByteUtils.toInt(data, index); index += INT_SIZE; + commandLineName = ByteUtils.getString(data, index); + index += ByteUtils.getStringLength(data, index); ppid = ByteUtils.toInt(data, index); index += INT_SIZE; int sec = ByteUtils.toInt(data, index); @@ -196,6 +199,7 @@ public class MessageParser { pInfoPack.setPid(pid); pInfoPack.setPpid(ppid); pInfoPack.setTargetBinaryPath(targetBinaryPath); + pInfoPack.setCmdLineName(commandLineName); if (processPkgMap.isEmpty()) { AnalyzerManager.getProject().setMainPid(pid); } @@ -606,6 +610,24 @@ public class MessageParser { } } break; + case DataChannelConstants.MSG_PROCESS_COMM: + { + // process command line name is changed (/proc//cmdline) + int index = MSG_HEADER_SIZE; + int pid = ByteUtils.toInt(data, index); + index += INT_SIZE; + String name = ByteUtils.getString(data, index); + index += ByteUtils.getStringLength(data, index); + + HashMap processPkgMap = AnalyzerManager + .getProject().getProcessInfoPackHash(); + + ProcessInfoPackage pInfoPack = processPkgMap.get(pid); + if (null != pInfoPack) { + pInfoPack.setCmdLineName(name); + } + } + break; default: // MSG_PROBE if (AnalyzerManager.isProcessInfoArrived() && id > 0x0100 && id < 0x0200) { diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/toolbar/ToolbarArea.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/toolbar/ToolbarArea.java index d11fb89..f13863e 100755 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/toolbar/ToolbarArea.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/toolbar/ToolbarArea.java @@ -317,11 +317,17 @@ public class ToolbarArea { .values()); for (ProcessInfoPackage pkg : processInfoPkgList) { // String pid = Integer.toString(pkg.getPid()); - String binPath = pkg.getTargetBinaryPath(); String binName = CommonConstants.EMPTY; - if (null != binPath && !binPath.isEmpty()) { - int index = binPath.lastIndexOf(CommonConstants.SLASH); - binName = binPath.substring(index + 1, binPath.length()); + + String cmdLineName = pkg.getCmdLineName(); + if(cmdLineName != null && !cmdLineName.isEmpty()) { + binName = cmdLineName; + } else { + String binPath = pkg.getTargetBinaryPath(); + if (null != binPath && !binPath.isEmpty()) { + int index = binPath.lastIndexOf(CommonConstants.SLASH); + binName = binPath.substring(index + 1, binPath.length()); + } } StringBuffer buffer = new StringBuffer(); buffer.append(pkg.getPid()).append(PROCESS_SPLITER); -- 2.7.4