KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > collections > test > IterDeadlockTest


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: IterDeadlockTest.java,v 1.7 2006/10/30 21:14:39 bostic Exp $
7  */

8
9 package com.sleepycat.collections.test;
10
11 import com.sleepycat.compat.DbCompat;
12 import com.sleepycat.je.Database;
13 import com.sleepycat.je.DatabaseConfig;
14 import com.sleepycat.je.DeadlockException;
15 import com.sleepycat.je.Environment;
16 import com.sleepycat.bind.ByteArrayBinding;
17 import com.sleepycat.collections.TransactionRunner;
18 import com.sleepycat.collections.TransactionWorker;
19 import com.sleepycat.collections.StoredIterator;
20 import com.sleepycat.collections.StoredSortedMap;
21 import java.util.Iterator JavaDoc;
22 import java.util.ListIterator JavaDoc;
23 import junit.framework.Test;
24 import junit.framework.TestCase;
25 import junit.framework.TestSuite;
26
27 /**
28  * Tests the fix for [#10516], where the StoredIterator constructor was not
29  * closing the cursor when an exception occurred. For example, a deadlock
30  * exception might occur if the constructor was unable to move the cursor to
31  * the first element.
32  * @author Mark Hayes
33  */

34 public class IterDeadlockTest extends TestCase {
35
36     private static final byte[] ONE = { 1 };
37
38     public static void main(String JavaDoc[] args)
39         throws Exception JavaDoc {
40
41         junit.framework.TestResult tr =
42             junit.textui.TestRunner.run(suite());
43         if (tr.errorCount() > 0 ||
44             tr.failureCount() > 0) {
45             System.exit(1);
46         } else {
47             System.exit(0);
48         }
49     }
50
51     public static Test suite()
52         throws Exception JavaDoc {
53
54         TestSuite suite = new TestSuite(IterDeadlockTest.class);
55         return suite;
56     }
57
58     private Environment env;
59     private Database store1;
60     private Database store2;
61     private StoredSortedMap map1;
62     private StoredSortedMap map2;
63     private ByteArrayBinding binding = new ByteArrayBinding();
64
65     public IterDeadlockTest(String JavaDoc name) {
66
67         super(name);
68     }
69
70     public void setUp()
71         throws Exception JavaDoc {
72
73         env = TestEnv.TXN.open("IterDeadlockTest");
74         store1 = openDb("store1.db");
75         store2 = openDb("store2.db");
76         map1 = new StoredSortedMap(store1, binding, binding, true);
77         map2 = new StoredSortedMap(store2, binding, binding, true);
78     }
79
80     public void tearDown() {
81
82         if (store1 != null) {
83             try {
84                 store1.close();
85             } catch (Exception JavaDoc e) {
86                 System.out.println("Ignored exception during tearDown: " + e);
87             }
88         }
89         if (store2 != null) {
90             try {
91                 store2.close();
92             } catch (Exception JavaDoc e) {
93                 System.out.println("Ignored exception during tearDown: " + e);
94             }
95         }
96         if (env != null) {
97             try {
98                 env.close();
99             } catch (Exception JavaDoc e) {
100                 System.out.println("Ignored exception during tearDown: " + e);
101             }
102         }
103         /* Allow GC of DB objects in the test case. */
104         env = null;
105         store1 = null;
106         store2 = null;
107         map1 = null;
108         map2 = null;
109     }
110
111     private Database openDb(String JavaDoc file)
112         throws Exception JavaDoc {
113
114         DatabaseConfig config = new DatabaseConfig();
115         DbCompat.setTypeBtree(config);
116         config.setTransactional(true);
117         config.setAllowCreate(true);
118
119         return DbCompat.openDatabase(env, null, file, null, config);
120     }
121
122     public void testIterDeadlock()
123         throws Exception JavaDoc {
124
125         final Object JavaDoc parent = new Object JavaDoc();
126         final Object JavaDoc child1 = new Object JavaDoc();
127         final Object JavaDoc child2 = new Object JavaDoc();
128         final TransactionRunner runner = new TransactionRunner(env);
129         runner.setMaxRetries(0);
130
131         /* Write a record in each db. */
132         runner.run(new TransactionWorker() {
133             public void doWork() throws Exception JavaDoc {
134                 assertNull(map1.put(ONE, ONE));
135                 assertNull(map2.put(ONE, ONE));
136             }
137         });
138
139         /*
140          * A thread to open iterator 1, then wait to be notified, then open
141          * iterator 2.
142          */

143         final Thread JavaDoc thread1 = new Thread JavaDoc(new Runnable JavaDoc() {
144             public void run() {
145                 try {
146                     runner.run(new TransactionWorker() {
147                         public void doWork() throws Exception JavaDoc {
148                             synchronized (child1) {
149                                 ListIterator JavaDoc i1 =
150                                     (ListIterator JavaDoc) map1.values().iterator();
151                                 i1.next();
152                                 i1.set(ONE); /* Write lock. */
153                                 StoredIterator.close(i1);
154                                 synchronized (parent) { parent.notify(); }
155                                 child1.wait();
156                                 Iterator i2 = map2.values().iterator();
157                                 assertTrue(i2.hasNext());
158                                 StoredIterator.close(i2);
159                             }
160                         }
161                     });
162                 } catch (DeadlockException expected) {
163                 } catch (Exception JavaDoc e) {
164                     e.printStackTrace();
165                     fail(e.toString());
166                 }
167             }
168         });
169
170         /*
171          * A thread to open iterator 2, then wait to be notified, then open
172          * iterator 1.
173          */

174         final Thread JavaDoc thread2 = new Thread JavaDoc(new Runnable JavaDoc() {
175             public void run() {
176                 try {
177                     runner.run(new TransactionWorker() {
178                         public void doWork() throws Exception JavaDoc {
179                             synchronized (child2) {
180                                 ListIterator JavaDoc i2 =
181                                     (ListIterator JavaDoc) map2.values().iterator();
182                                 i2.next();
183                                 i2.set(ONE); /* Write lock. */
184                                 StoredIterator.close(i2);
185                                 synchronized (parent) { parent.notify(); }
186                                 child2.wait();
187                                 Iterator i1 = map1.values().iterator();
188                                 assertTrue(i1.hasNext());
189                                 StoredIterator.close(i1);
190                             }
191                         }
192                     });
193                 } catch (DeadlockException expected) {
194                 } catch (Exception JavaDoc e) {
195                     e.printStackTrace();
196                     fail(e.toString());
197                 }
198             }
199         });
200
201         /*
202          * Open iterator 1 in thread 1, then iterator 2 in thread 2, then let
203          * the threads run to open the other iterators and cause a deadlock.
204          */

205         synchronized (parent) {
206             thread1.start();
207             parent.wait();
208             thread2.start();
209             parent.wait();
210             synchronized (child1) { child1.notify(); }
211             synchronized (child2) { child2.notify(); }
212             thread1.join();
213             thread2.join();
214         }
215
216         /*
217          * Before the fix for [#10516] we would get an exception indicating
218          * that cursors were not closed, when closing the stores below.
219          */

220         store1.close();
221         store1 = null;
222         store2.close();
223         store2 = null;
224         env.close();
225         env = null;
226     }
227 }
228
Popular Tags