File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\engine\DatabaseCloser.java.html

1 /*
2 * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
3 * Version 1.0, and under the Eclipse Public License, Version 1.0
4 * (http://h2database.com/html/license.html).
5 * Initial Developer: H2 Group
6 */
7 package org.h2.engine;
8
9 import java.lang.ref.WeakReference;
10
11 import org.h2.message.Trace;
12
13 /**
14 * This class is responsible to close a database if the application did not
15 * close a connection. A database closer object only exists if there is no user
16 * connected to the database.
17 */
18 class DatabaseCloser extends Thread {
19
20 private final boolean shutdownHook;
21 private final Trace trace;
22 private volatile WeakReference<Database> databaseRef;
23 private int delayInMillis;
24 private boolean stopImmediately;
25
26 DatabaseCloser(Database db, int delayInMillis, boolean shutdownHook) {
27 this.databaseRef = new WeakReference<Database>(db);
28 this.delayInMillis = delayInMillis;
29 this.shutdownHook = shutdownHook;
30 trace = db.getTrace(Trace.DATABASE);
31 }
32
33 /**
34 * Stop and disable the database closer. This method is called after the
35 * database has been closed, or after a session has been created.
36 */
37 void reset() {
38 synchronized (this) {
39 databaseRef = null;
40 }
41 ThreadGroup threadGroup = getThreadGroup();
42 // the threadGroup could be null if the thread was run in the meantime
43 if (threadGroup != null && threadGroup.activeCount() > 100) {
44 // in JDK 1.4 and below, all Thread objects are added to the ThreadGroup,
45 // and cause a memory leak if never started.
46 // Need to start it, otherwise it leaks memory in JDK 1.4 and below
47 stopImmediately = true;
48 try {
49 start();
50 } catch (Throwable e) {
51 // ignore
52 }
53 }
54 }
55
56 public void run() {
57 if (stopImmediately) {
58 return;
59 }
60 while (delayInMillis > 0) {
61 try {
62 int step = 100;
63 Thread.sleep(step);
64 delayInMillis -= step;
65 } catch (Exception e) {
66 // ignore InterruptedException
67 }
68 if (databaseRef == null) {
69 return;
70 }
71 }
72 Database database = null;
73 synchronized (this) {
74 if (databaseRef != null) {
75 database = databaseRef.get();
76 }
77 }
78 if (database != null) {
79 try {
80 database.close(shutdownHook);
81 } catch (RuntimeException e) {
82 // this can happen when stopping a web application,
83 // if loading classes is no longer allowed
84 // it would throw an IllegalStateException
85 try {
86 trace.error(e, "could not close the database");
87 // if this was successful, we ignore the exception
88 // otherwise not
89 } catch (RuntimeException e2) {
90 throw e;
91 }
92 }
93 }
94 }
95
96 }
97