changeset 485:cc262a519b8a

add dead lock detection (don't forget remove )
author one
date Wed, 20 Oct 2010 22:59:19 +0900
parents 7420dea70dd7
children 877aacde8651
files Todo rep/ServerMainLoop.java rep/SessionManager.java rep/handler/Editor.java rep/handler/REPNode.java
diffstat 5 files changed, 65 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/Todo	Wed Oct 20 21:19:24 2010 +0900
+++ b/Todo	Wed Oct 20 22:59:19 2010 +0900
@@ -1,3 +1,19 @@
+Wed Oct 20 20:35:53 JST 2010
+
+    Editor1   Editor2    Editor3 
+    c(eid=1)             a(eid=3)
+    a(eid=3)  c(eid=1)           
+              e(eid=2)   c(eid=1)
+    c(eid=1)  a(eid=3)   e(eid=2)
+    e(eid=2)  ca(eid=1)  a(eid=3)
+    aa(eid=3) e(eid=2)   ca(eid=1)
+    ca(eid=1) aa(eid=3)  ea(eid=2)   
+    ea(eid=2) ca(eid=1)
+                        ca(eid=1)
+
+    [c,e,a]   [c,e,a]    [c,e,a]
+
+
 Fri Oct 15 19:47:05 JST 2010
 
 あまり良い変更でないので元に戻す。
--- a/rep/ServerMainLoop.java	Wed Oct 20 21:19:24 2010 +0900
+++ b/rep/ServerMainLoop.java	Wed Oct 20 22:59:19 2010 +0900
@@ -59,6 +59,7 @@
 	}
 	
 	public void mainLoop() throws IOException {
+		int deadlock = 0;
 		while(running){
 			manager.checkWaitingCommandInMerge();
 			if (checkInputEvent() ||
@@ -69,11 +70,15 @@
 				   //continue;
 			}
 			// now we can wait for input packet or event
+			if (deadlock++>1000) deadlockDetected();
 			selector.select(1);
-			select();
+			if (select()) deadlock=0;
 		}
 	}
 
+	public void deadlockDetected() throws IOException {
+	}
+
 	void serverInit() throws IOException, SocketException,
 			ClosedChannelException {
 		selector = REPSelector.<REPCommand>create();	
@@ -148,10 +153,11 @@
 	 *     check incoming connection request and incoming packet
 	 *     A request is handled by a handler object which is attached
 	 *     to the SelectionKey.  
+	 * @return 
 	 * @throws IOException
 	 */
-	private void select() throws IOException {
-		
+	private boolean select() throws IOException {
+		boolean flag = false;
 		Set<REPSelectionKey<REPCommand>> keys = selector.selectedKeys1();
 		for(REPSelectionKey<REPCommand> key : keys){
 			if(key.isAcceptable()){
@@ -162,6 +168,7 @@
 				REPSocketChannel<REPCommand> channel = key.accept(new REPCommandPacker());
 				logger.writeLog("SessionManager.select() : key.isAcceptable : channel = " + channel);
 				registerChannel(channel, new FirstConnector(manager,channel));
+				flag = true;
 			} else if(key.isReadable()){
 				/*
 				 * Incoming packets are handled by a various forwarder.
@@ -172,12 +179,14 @@
 				try {
 					REPCommand command = key.channel1().read();
 					handler.handle(command, key);
+					flag = true;
 				} catch (IOException e) {
 					key.cancel();
 					handler.cancel(key.channel1());
 				}
 			}
 		}
+		return flag;
 	}
 
 	public void registerChannel(REPSocketChannel<REPCommand> channel, REPNode handler) throws IOException {
--- a/rep/SessionManager.java	Wed Oct 20 21:19:24 2010 +0900
+++ b/rep/SessionManager.java	Wed Oct 20 22:59:19 2010 +0900
@@ -645,5 +645,13 @@
 		serverMainLoop.gui.invokeLater(doRun);
 	}
 
+	@Override
+	public void deadlockDetected() throws IOException {
+		logger.writeLog("Deadlock detected");
+		for(REPNode e:editorList.values()) {
+			logger.writeLog("  "+e+"\n"+e.report());
+		}
+		throw new IOException();
+	}
 
 }
--- a/rep/handler/Editor.java	Wed Oct 20 21:19:24 2010 +0900
+++ b/rep/handler/Editor.java	Wed Oct 20 22:59:19 2010 +0900
@@ -135,7 +135,14 @@
 				checkQuit();
 				return;
 			}
-			checkReturnedCommand(command);
+			if (mergeMode==MergeMode.Direct) {
+				checkAck(command);
+				truncateUnMergedCmds(command);
+				ServerMainLoop.logger.writeLog("Editor"+eid+": send ackCommand "+command);
+				next.send(command);
+				checkQuit();
+			} else
+				checkReturnedCommand(command);
 			return;
 		case REPCMD_INSERT_USER:
 			command.cmd = REP.REPCMD_INSERT;
@@ -162,6 +169,10 @@
 				if (mergeMode==MergeMode.Slow) {
 					checkAck(command);
 					sendAck(command);
+				} else	if (mergeMode==MergeMode.Direct) {
+					truncateUnMergedCmds(command);
+					checkAck(command);
+					sendAck(command);
 				} else {
 					checkReturnedCommand(command);
 				}
@@ -295,9 +306,6 @@
 	 * @param command
 	 */
 	void checkReturnedCommand(REPCommand command) {
-		if (mergeMode==MergeMode.Direct) {
-			truncateUnMergedCmds(command);
-		} else
 			startMerge(command);
 	}
 
@@ -533,6 +541,8 @@
 	
 	
 	private boolean isMergeCommand(REPCommand command) {
+		if (mergeMode==MergeMode.Direct) 
+			return (command.eid!=eid&&command.cmd==REP.REPCMD_INSERT || command.cmd==REP.REPCMD_DELETE);
 		switch(command.cmd) {
 		case REPCMD_INSERT: case REPCMD_DELETE:
 			return mergeMode==MergeMode.Slow?false:command.eid==eid;
@@ -762,5 +772,16 @@
 		merge_mode = true;
 	}
 
+	/**
+	 * Dead lock reporter
+	 */
+	public String report() {
+		String s = "";
+		s += "SentList:"+sentList;
+		s += "\n  ackList:"+ackList;
+		s += "\n  unMergedList:"+unMergedCmds;
+		s += "\n  mergeMode=:"+merge_mode;
+		return s;
+	}
 
 }
--- a/rep/handler/REPNode.java	Wed Oct 20 21:19:24 2010 +0900
+++ b/rep/handler/REPNode.java	Wed Oct 20 22:59:19 2010 +0900
@@ -170,6 +170,10 @@
 		send(m);		
 	}
 
+	public String report() {
+		return "";
+	}
+
 	
 	
 }