提交 d42b9406 authored 作者: Thomas Mueller's avatar Thomas Mueller

In-memory databases can now run inside the Google App Engine.

上级 9b21163b
...@@ -222,8 +222,8 @@ public class Database implements DataHandler { ...@@ -222,8 +222,8 @@ public class Database implements DataHandler {
try { try {
open(traceLevelFile, traceLevelSystemOut); open(traceLevelFile, traceLevelSystemOut);
if (closeAtVmShutdown) { if (closeAtVmShutdown) {
closeOnExit = new DatabaseCloser(this, 0, true);
try { try {
closeOnExit = new DatabaseCloser(this, 0, true);
Runtime.getRuntime().addShutdownHook(closeOnExit); Runtime.getRuntime().addShutdownHook(closeOnExit);
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
// shutdown in progress - just don't register the handler // shutdown in progress - just don't register the handler
...@@ -231,6 +231,8 @@ public class Database implements DataHandler { ...@@ -231,6 +231,8 @@ public class Database implements DataHandler {
// database at shutdown time) // database at shutdown time)
} catch (SecurityException e) { } catch (SecurityException e) {
// applets may not do that - ignore // applets may not do that - ignore
// Google App Engine doesn't allow
// to instantiate classes that extend Thread
} }
} }
} catch (Throwable e) { } catch (Throwable e) {
......
...@@ -25,7 +25,7 @@ import org.h2.util.ObjectArray; ...@@ -25,7 +25,7 @@ import org.h2.util.ObjectArray;
* The writer thread is responsible to flush the transaction log file from time * The writer thread is responsible to flush the transaction log file from time
* to time. * to time.
*/ */
public class WriterThread extends Thread { public class WriterThread implements Runnable {
/** /**
* The reference to the database. * The reference to the database.
...@@ -74,11 +74,12 @@ public class WriterThread extends Thread { ...@@ -74,11 +74,12 @@ public class WriterThread extends Thread {
* @return the writer thread object * @return the writer thread object
*/ */
public static WriterThread create(Database database, int writeDelay) { public static WriterThread create(Database database, int writeDelay) {
WriterThread thread = new WriterThread(database, writeDelay); WriterThread writer = new WriterThread(database, writeDelay);
Thread thread = new Thread(writer);
thread.setName("H2 Log Writer " + database.getShortName()); thread.setName("H2 Log Writer " + database.getShortName());
thread.setDaemon(true); thread.setDaemon(true);
thread.start(); thread.start();
return thread; return writer;
} }
private LogSystem getLog() { private LogSystem getLog() {
......
...@@ -10,7 +10,6 @@ import java.io.ByteArrayOutputStream; ...@@ -10,7 +10,6 @@ import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.InetAddress;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Random; import java.util.Random;
...@@ -65,24 +64,31 @@ public class RandomUtils { ...@@ -65,24 +64,31 @@ public class RandomUtils {
} }
} }
}; };
Thread t = new Thread(runnable);
// let the process terminate even if generating the seed is really slow
t.setDaemon(true);
t.start();
Thread.yield();
try { try {
// normally, generateSeed takes less than 200 ms Thread t = new Thread(runnable);
t.join(400); // let the process terminate even if generating the seed is really slow
} catch (InterruptedException e) { t.setDaemon(true);
warn("InterruptedException", e); t.start();
} Thread.yield();
if (!seeded) { try {
byte[] seed = generateAlternativeSeed(); // normally, generateSeed takes less than 200 ms
// this never reduces randomness t.join(400);
synchronized (cachedSecureRandom) { } catch (InterruptedException e) {
cachedSecureRandom.setSeed(seed); warn("InterruptedException", e);
}
if (!seeded) {
byte[] seed = generateAlternativeSeed();
// this never reduces randomness
synchronized (cachedSecureRandom) {
cachedSecureRandom.setSeed(seed);
}
} }
} catch (SecurityException e) {
// workaround for the Google App Engine: don't use a thread
runnable.run();
generateAlternativeSeed();
} }
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
warn("SecureRandom", e); warn("SecureRandom", e);
cachedSecureRandom = new SecureRandom(); cachedSecureRandom = new SecureRandom();
...@@ -125,18 +131,27 @@ public class RandomUtils { ...@@ -125,18 +131,27 @@ public class RandomUtils {
// host name and ip addresses (if any) // host name and ip addresses (if any)
try { try {
String hostName = InetAddress.getLocalHost().getHostName(); // workaround for the Google App Engine: don't use InetAddress
Class inetAddressClass = Class.forName("java.net.InetAddress");
Object localHost = inetAddressClass.getMethod(
"getLocalHost", new Class[0]).invoke(null, new Object[0]);
String hostName = inetAddressClass.getMethod(
"getHostName", new Class[0]).invoke(localHost, new Object[0]).toString();
out.writeUTF(hostName); out.writeUTF(hostName);
InetAddress[] list = InetAddress.getAllByName(hostName); Object[] list = (Object[]) inetAddressClass.getMethod(
"getAllByName", new Class[] { String.class })
.invoke(null, new Object[] { hostName });
Method getAddress = inetAddressClass.getMethod("getAddress", new Class[0]);
for (int i = 0; i < list.length; i++) { for (int i = 0; i < list.length; i++) {
out.write(list[i].getAddress()); out.write((byte[]) getAddress.invoke(list[i], new Object[0]));
} }
} catch (Exception e) { } catch (Throwable e) {
// on some system, InetAddress is not supported
// on some system, InetAddress.getLocalHost() doesn't work // on some system, InetAddress.getLocalHost() doesn't work
// for some reason (incorrect configuration) // for some reason (incorrect configuration)
} }
// timing (a second thread is already running) // timing (a second thread is already running usually)
for (int j = 0; j < 16; j++) { for (int j = 0; j < 16; j++) {
int i = 0; int i = 0;
long end = System.currentTimeMillis(); long end = System.currentTimeMillis();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论