001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (license2)
004: * Initial Developer: H2 Group
005: */
006: package org.h2.test.unit;
007:
008: import java.io.File;
009:
010: import org.h2.message.TraceSystem;
011: import org.h2.store.FileLock;
012: import org.h2.test.TestBase;
013:
014: /**
015: * Tests the database file locking facility.
016: * Both lock files and sockets locking is tested.
017: */
018: public class TestFileLock extends TestBase implements Runnable {
019:
020: int wait;
021: static final int KILL = 5;
022: static final String FILE = baseDir + "/test.lock";
023:
024: private boolean allowSockets;
025: private static volatile int locks;
026: private static volatile boolean stop;
027:
028: public TestFileLock() {
029: }
030:
031: public void test() throws Exception {
032: test(false);
033: test(true);
034: }
035:
036: void test(boolean allowSockets) throws Exception {
037: int threadCount = getSize(3, 5);
038: wait = getSize(20, 200);
039: Thread[] threads = new Thread[threadCount];
040: new File(FILE).delete();
041: for (int i = 0; i < threadCount; i++) {
042: threads[i] = new Thread(
043: new TestFileLock(this , allowSockets));
044: threads[i].start();
045: Thread.sleep(wait + (int) (Math.random() * wait));
046: }
047: trace("wait");
048: Thread.sleep(500);
049: stop = true;
050: trace("STOP file");
051: for (int i = 0; i < threadCount; i++) {
052: threads[i].join();
053: }
054: check(locks, 0);
055: }
056:
057: TestBase base;
058:
059: TestFileLock(TestBase base, boolean allowSockets) {
060: this .base = base;
061: this .allowSockets = allowSockets;
062: }
063:
064: public void run() {
065: while (!stop) {
066: FileLock lock = new FileLock(new TraceSystem(null, false),
067: 100);
068: try {
069: lock.lock(FILE, allowSockets);
070: base.trace(lock + " locked");
071: locks++;
072: if (locks > 1) {
073: System.err.println("ERROR! LOCKS=" + locks
074: + " sockets=" + allowSockets);
075: stop = true;
076: }
077: Thread.sleep(wait + (int) (Math.random() * wait));
078: locks--;
079: if ((Math.random() * 50) < KILL) {
080: base.trace(lock + " kill");
081: lock = null;
082: System.gc();
083: } else {
084: base.trace(lock + " unlock");
085: lock.unlock();
086: }
087: if (locks < 0) {
088: System.err.println("ERROR! LOCKS=" + locks);
089: stop = true;
090: }
091: } catch (Exception e) {
092: // log(id+" cannot lock: " + e);
093: }
094: try {
095: Thread.sleep(wait + (int) (Math.random() * wait));
096: } catch (InterruptedException e1) {
097: // ignore
098: }
099: }
100: }
101:
102: }
|