[jbpm-commits] JBoss JBPM SVN: r7060 - in jbpm3/branches/jbpm-3.2-soa/core/src: test/java/org/jbpm and 1 other directories.
do-not-reply at jboss.org
do-not-reply at jboss.org
Tue Feb 21 21:14:44 EST 2012
Author: marco.rietveld
Date: 2012-02-21 21:14:43 -0500 (Tue, 21 Feb 2012)
New Revision: 7060
Added:
jbpm3/branches/jbpm-3.2-soa/core/src/test/java/org/jbpm/jbpm3416/
jbpm3/branches/jbpm-3.2-soa/core/src/test/java/org/jbpm/jbpm3416/JBPM3416Test.java
Modified:
jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/logging/exe/LoggingInstance.java
Log:
JBPM-3416: LoggingInstance concurrency issue.
Modified: jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/logging/exe/LoggingInstance.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/logging/exe/LoggingInstance.java 2012-02-22 02:13:14 UTC (rev 7059)
+++ jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/logging/exe/LoggingInstance.java 2012-02-22 02:14:43 UTC (rev 7060)
@@ -25,6 +25,7 @@
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -51,16 +52,16 @@
public LoggingInstance() {
}
- public void startCompositeLog(CompositeLog compositeLog) {
+ public synchronized void startCompositeLog(CompositeLog compositeLog) {
addLog(compositeLog);
compositeLogStack.add(compositeLog);
}
- public void endCompositeLog() {
+ public synchronized void endCompositeLog() {
compositeLogStack.remove(compositeLogStack.size() - 1);
}
- public void addLog(ProcessLog processLog) {
+ public synchronized void addLog(ProcessLog processLog) {
if (!compositeLogStack.isEmpty()) {
CompositeLog compositeLog = (CompositeLog) compositeLogStack.get(compositeLogStack.size() - 1);
compositeLog.addChild(processLog);
@@ -71,14 +72,14 @@
}
public List getLogs() {
- return logs;
+ return Collections.unmodifiableList(logs);
}
/**
* get logs, filtered by log type.
*/
public List getLogs(Class filterClass) {
- return getLogs(logs, filterClass);
+ return getLogs(getLogs(), filterClass);
}
public static List getLogs(Collection logs, Class filterClass) {
@@ -93,7 +94,7 @@
}
List getCompositeLogStack() {
- return compositeLogStack;
+ return Collections.unmodifiableList(compositeLogStack);
}
public void logLogs() {
Added: jbpm3/branches/jbpm-3.2-soa/core/src/test/java/org/jbpm/jbpm3416/JBPM3416Test.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/core/src/test/java/org/jbpm/jbpm3416/JBPM3416Test.java (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/core/src/test/java/org/jbpm/jbpm3416/JBPM3416Test.java 2012-02-22 02:14:43 UTC (rev 7060)
@@ -0,0 +1,148 @@
+package org.jbpm.jbpm3416;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jbpm.AbstractJbpmTestCase;
+import org.jbpm.context.exe.ContextInstance;
+import org.jbpm.graph.def.ProcessDefinition;
+import org.jbpm.graph.exe.ProcessInstance;
+import org.jbpm.graph.exe.Token;
+
+/**
+ * 2 threads concurrently call Token#signal() and ContextThread#setVariable() on the same process instance.
+ * THREAD_NUM is the number of threads which concurrently execute the test. Each thread spawns 2 threads as described above.
+ * LOOP_NUM is the number of test iterations. You may increase it to reproduce the Exception for sure.
+ *
+ * @see <a href="https://jira.jboss.org/jira/browse/JBPM-3416">JBPM-3416</a>
+ */
+public class JBPM3416Test extends AbstractJbpmTestCase {
+
+ private static final int LOOP_NUM = 100;
+ private static final int THREAD_NUM = 1000;
+
+ private static List exceptionList = new ArrayList();
+
+ public boolean doNotRunUnlessManually = true;
+
+ public void testConcurrentAccessToLoggingInstance() {
+ if( doNotRunUnlessManually ) {
+ return;
+ }
+
+ ProcessDefinition processDefinition = ProcessDefinition
+ .parseXmlString(
+ "<process-definition>"
+ + " <start-state name='start'>"
+ + " <transition to='s' />"
+ + " </start-state>"
+ + " <state name='s'>"
+ + " <transition to='end' />"
+ + " </state>"
+ + " <end-state name='end' />"
+ + "</process-definition>");
+
+ for (int i = 0; i < LOOP_NUM; i++) {
+ ArrayList threads = new ArrayList();
+ for (int idx = 0; idx < THREAD_NUM; idx++) {
+ threads.add(new JobThread(processDefinition, idx));
+ }
+
+ for (int idx = 0; idx < THREAD_NUM; idx++) {
+ ((Thread) threads.get(idx)).start();
+ }
+
+ for (int idx = 0; idx < THREAD_NUM; idx++) {
+ try {
+ ((Thread) threads.get(idx)).join();
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ if (exceptionList.size() > 0) {
+ ((RuntimeException) exceptionList.get(exceptionList.size()-1)).printStackTrace();
+ fail("[" + i + "] Found RuntimeException : exceptionList.size() = "
+ + exceptionList.size() + ", exceptionList.get(0) = "
+ + exceptionList.get(0));
+ }
+ }
+
+
+ }
+
+ private class JobThread extends Thread {
+ ProcessDefinition processDefinition = null;
+ int id = -1;
+
+ public JobThread(ProcessDefinition processDefinition, int id) {
+ this.processDefinition = processDefinition;
+ this.id = id;
+ }
+
+ public void run() {
+ ProcessInstance processInstance = new ProcessInstance(processDefinition);
+
+ TokenThread tokenThread = new TokenThread(processInstance);
+ ContextThread contextThread = new ContextThread(processInstance);
+ tokenThread.start();
+ contextThread.start();
+ try {
+ tokenThread.join();
+ } catch (InterruptedException e) {
+ // ignore;
+ }
+ try {
+ contextThread.join();
+ } catch (InterruptedException e) {
+ // ignore
+ }
+
+ this.processDefinition = null;
+ }
+ }
+
+ /*
+ * Thread for Token#signal
+ */
+ private class TokenThread extends Thread {
+ ProcessInstance processInstance = null;
+
+ public TokenThread(ProcessInstance processInstance) {
+ this.processInstance = processInstance;
+ }
+
+ public void run() {
+ Token token = processInstance.getRootToken();
+ try {
+ token.signal();
+ token.signal();
+ } catch (RuntimeException e) {
+ exceptionList.add(e);
+ }
+ this.processInstance = null;
+ }
+ }
+
+ /*
+ * Thread for ContextThread#setVariable
+ */
+ private class ContextThread extends Thread {
+ ProcessInstance processInstance = null;
+
+ public ContextThread(ProcessInstance processInstance ) {
+ this.processInstance = processInstance;
+ }
+
+ public void run() {
+
+ ContextInstance contextInstance = processInstance.getContextInstance();
+ try {
+ contextInstance.setVariable("RESULT", "OK");
+ } catch (RuntimeException e) {
+ exceptionList.add(e);
+ }
+ this.processInstance = null;
+
+ }
+ }
+}
Property changes on: jbpm3/branches/jbpm-3.2-soa/core/src/test/java/org/jbpm/jbpm3416/JBPM3416Test.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
More information about the jbpm-commits
mailing list