001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tctest;
005:
006: import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
007:
008: import com.tc.object.config.ConfigVisitor;
009: import com.tc.object.config.DSOClientConfigHelper;
010: import com.tc.object.config.TransparencyClassSpec;
011: import com.tc.object.config.spec.CyclicBarrierSpec;
012: import com.tc.simulator.app.ApplicationConfig;
013: import com.tc.simulator.listener.ListenerProvider;
014: import com.tctest.runner.AbstractTransparentApp;
015:
016: public class NullLiteralArrayElementRegressionTestApp extends
017: AbstractTransparentApp {
018:
019: private final TestObject root = new TestObject();
020: private final CyclicBarrier barrier;
021:
022: public NullLiteralArrayElementRegressionTestApp(String appId,
023: ApplicationConfig cfg, ListenerProvider listenerProvider) {
024: super (appId, cfg, listenerProvider);
025:
026: if (getParticipantCount() != 3) {
027: // must have 3 nodes for this test to work
028: throw new RuntimeException("wrong number of nodes: "
029: + getParticipantCount());
030: }
031:
032: barrier = new CyclicBarrier(getParticipantCount());
033: }
034:
035: public void run() {
036: try {
037: test();
038: } catch (Throwable t) {
039: notifyError(t);
040: }
041: }
042:
043: private void test() throws Exception {
044: // Get the root object paged into each node (and strongly held) before creating the array
045: TestObject obj = root;
046:
047: final boolean creator;
048: synchronized (obj) {
049: if (!obj.hasArray()) {
050: creator = true;
051: obj.setArray(new Object[10]);
052: } else {
053: creator = false;
054: }
055: }
056:
057: barrier.barrier();
058:
059: if (creator) {
060: synchronized (obj) {
061: obj.setElement(5, 42L);
062: }
063: }
064:
065: barrier.barrier();
066:
067: Object value = obj.getElement(5);
068:
069: if (value == null) {
070: throw new NullPointerException("element is null");
071: }
072: }
073:
074: public static void visitL1DSOConfig(ConfigVisitor visitor,
075: DSOClientConfigHelper config) {
076: String testClass = NullLiteralArrayElementRegressionTestApp.class
077: .getName();
078: TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
079:
080: String methodExpression = "* " + testClass + "*.*(..)";
081: config.addWriteAutolock(methodExpression);
082: spec.addRoot("barrier", "barrier");
083: spec.addRoot("root", "root");
084: config.addIncludePattern(TestObject.class.getName());
085:
086: new CyclicBarrierSpec().visit(visitor, config);
087: }
088:
089: private static class TestObject {
090: private Object[] array;
091:
092: boolean hasArray() {
093: return this .array != null;
094: }
095:
096: void setArray(Object[] a) {
097: this .array = a;
098: }
099:
100: Object getElement(int index) {
101: return this .array[index];
102: }
103:
104: // This method takes a long b/c that is a "literal" type, but stored in an Object array
105: void setElement(int index, long value) {
106: array[index] = new Long(value);
107: }
108:
109: }
110:
111: }
|