2004-09-07 jrandom
* Write the native libraries to the current directory when they are loaded from a resource, and load them from that file on subsequent runs (in turn, we no longer *cough* delete the running libraries...) * Added support for a graceful restart. * Added new pseudo-shutdown hook specific to the router, allowing applications to request tasks to be run when the router shuts down. We use this for integration with the service manager, since otherwise a graceful shutdown would cause a timeout, followed by a forced hard shutdown. * Handle a bug in the SimpleTimer with requeued tasks. * Made the capacity calculator a bit more dynamic by not outright ignoring the otherwise valid capacity data for a period with a single rejected tunnel (except for the 10 minute period). In addition, peers with an equal capacity are ordered by speed rather than by their hashes. * Cleaned up the SimpleTimer, addressing some threading and synchronization issues. * When an I2PTunnel client or httpclient is explicitly closed, destroy the associated session (unless there are other clients using it), and deal with a closed session when starting a new I2PTunnel instance. * Refactoring and logging.
This commit is contained in:
@ -417,17 +417,17 @@ public class CPUID {
|
||||
String wantedProp = System.getProperty("jcpuid.enable", "true");
|
||||
boolean wantNative = "true".equalsIgnoreCase(wantedProp);
|
||||
if (wantNative) {
|
||||
boolean loaded = loadFromResource();
|
||||
boolean loaded = loadGeneric();
|
||||
if (loaded) {
|
||||
_nativeOk = true;
|
||||
if (_doLog)
|
||||
System.err.println("INFO: Native CPUID library '"+getResourceName()+"' loaded from resource");
|
||||
System.err.println("INFO: Native CPUID library '"+getLibraryMiddlePart()+"' loaded from somewhere in the path");
|
||||
} else {
|
||||
loaded = loadGeneric();
|
||||
loaded = loadFromResource();
|
||||
if (loaded) {
|
||||
_nativeOk = true;
|
||||
if (_doLog)
|
||||
System.err.println("INFO: Native CPUID library '"+getLibraryMiddlePart()+"' loaded from somewhere in the path");
|
||||
System.err.println("INFO: Native CPUID library '"+getResourceName()+"' loaded from resource");
|
||||
} else {
|
||||
_nativeOk = false;
|
||||
if (_doLog)
|
||||
@ -451,6 +451,12 @@ public class CPUID {
|
||||
*
|
||||
*/
|
||||
private static final boolean loadGeneric() {
|
||||
try {
|
||||
System.loadLibrary("jcpuid");
|
||||
return true;
|
||||
} catch (UnsatisfiedLinkError ule) {
|
||||
// fallthrough, try the OS-specific filename
|
||||
}
|
||||
try {
|
||||
System.loadLibrary(getLibraryMiddlePart());
|
||||
return true;
|
||||
@ -486,7 +492,7 @@ public class CPUID {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
InputStream libStream = resource.openStream();
|
||||
outFile = File.createTempFile(libPrefix + "jcpuid", "lib.tmp" + libSuffix);
|
||||
outFile = new File(libPrefix + "jcpuid" + libSuffix);
|
||||
fos = new FileOutputStream(outFile);
|
||||
byte buf[] = new byte[4096*1024];
|
||||
while (true) {
|
||||
@ -515,10 +521,6 @@ public class CPUID {
|
||||
if (fos != null) {
|
||||
try { fos.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
if (outFile != null) {
|
||||
if (!outFile.delete())
|
||||
outFile.deleteOnExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,13 @@ public interface I2PSession {
|
||||
*/
|
||||
public void connect() throws I2PSessionException;
|
||||
|
||||
/**
|
||||
* Have we closed the session?
|
||||
*
|
||||
* @return true if the session is closed
|
||||
*/
|
||||
public boolean isClosed();
|
||||
|
||||
/**
|
||||
* Retrieve the Destination this session serves as the endpoint for.
|
||||
* Returns null if no destination is available.
|
||||
|
@ -354,7 +354,12 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
||||
_pendingSizes = new ArrayList(2);
|
||||
}
|
||||
|
||||
public void stopNotifying() { _alive = false; }
|
||||
public void stopNotifying() {
|
||||
_alive = false;
|
||||
synchronized (AvailabilityNotifier.this) {
|
||||
AvailabilityNotifier.this.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void available(int msgId, int size) {
|
||||
synchronized (AvailabilityNotifier.this) {
|
||||
@ -499,7 +504,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
||||
public void destroySession(boolean sendDisconnect) {
|
||||
if (_closed) return;
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Destroy the session", new Exception("DestroySession()"));
|
||||
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "Destroy the session", new Exception("DestroySession()"));
|
||||
if (sendDisconnect) {
|
||||
try {
|
||||
_producer.disconnect(this);
|
||||
@ -518,7 +523,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
||||
*
|
||||
*/
|
||||
private void closeSocket() {
|
||||
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Closing the socket", new Exception("closeSocket"));
|
||||
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "Closing the socket", new Exception("closeSocket"));
|
||||
_closed = true;
|
||||
if (_reader != null) _reader.stopReading();
|
||||
_reader = null;
|
||||
|
@ -67,9 +67,13 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
||||
synchronized (_existingLeaseSets) {
|
||||
_existingLeaseSets.put(session.getMyDestination(), li);
|
||||
}
|
||||
_log.debug("Creating new leaseInfo keys", new Exception("new leaseInfo keys"));
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Creating new leaseInfo keys for "
|
||||
+ session.getMyDestination().calculateHash().toBase64());
|
||||
} else {
|
||||
_log.debug("Caching the old leaseInfo keys", new Exception("cached! w00t"));
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Caching the old leaseInfo keys for "
|
||||
+ session.getMyDestination().calculateHash().toBase64());
|
||||
}
|
||||
|
||||
leaseSet.setEncryptionKey(li.getPublicKey());
|
||||
|
@ -485,7 +485,7 @@ public class NativeBigInteger extends BigInteger {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
InputStream libStream = resource.openStream();
|
||||
outFile = File.createTempFile(_libPrefix + "jbigi", "lib.tmp" + _libSuffix);
|
||||
outFile = new File(_libPrefix + "jbigi" + _libSuffix);
|
||||
fos = new FileOutputStream(outFile);
|
||||
byte buf[] = new byte[4096*1024];
|
||||
while (true) {
|
||||
@ -514,10 +514,6 @@ public class NativeBigInteger extends BigInteger {
|
||||
if (fos != null) {
|
||||
try { fos.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
if (outFile != null) {
|
||||
if (!outFile.delete())
|
||||
outFile.deleteOnExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,8 @@ public class SimpleTimer {
|
||||
|
||||
private class SimpleTimerRunner implements Runnable {
|
||||
public void run() {
|
||||
List eventsToFire = new ArrayList(1);
|
||||
List timesToRemove = new ArrayList(1);
|
||||
while (true) {
|
||||
try {
|
||||
synchronized (_events) {
|
||||
@ -71,34 +73,48 @@ public class SimpleTimer {
|
||||
_events.wait();
|
||||
long now = System.currentTimeMillis();
|
||||
long nextEventDelay = -1;
|
||||
List removed = null;
|
||||
for (Iterator iter = _events.keySet().iterator(); iter.hasNext(); ) {
|
||||
Long when = (Long)iter.next();
|
||||
if (when.longValue() <= now) {
|
||||
TimedEvent evt = (TimedEvent)_events.get(when);
|
||||
try {
|
||||
evt.timeReached();
|
||||
} catch (Throwable t) {
|
||||
log("wtf, event borked: " + evt, t);
|
||||
}
|
||||
if (removed == null)
|
||||
removed = new ArrayList(1);
|
||||
removed.add(when);
|
||||
eventsToFire.add(evt);
|
||||
timesToRemove.add(when);
|
||||
} else {
|
||||
nextEventDelay = when.longValue() - now;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (removed != null) {
|
||||
for (int i = 0; i < removed.size(); i++)
|
||||
_events.remove(removed.get(i));
|
||||
if (timesToRemove.size() > 0) {
|
||||
for (int i = 0; i < timesToRemove.size(); i++)
|
||||
_events.remove(timesToRemove.get(i));
|
||||
} else {
|
||||
if (nextEventDelay != -1)
|
||||
_events.wait(nextEventDelay);
|
||||
else
|
||||
_events.wait();
|
||||
}
|
||||
if (nextEventDelay != -1)
|
||||
_events.wait(nextEventDelay);
|
||||
else
|
||||
_events.wait();
|
||||
}
|
||||
} catch (InterruptedException ie) {}
|
||||
} catch (InterruptedException ie) {
|
||||
// ignore
|
||||
} catch (Throwable t) {
|
||||
if (_log != null) {
|
||||
_log.log(Log.CRIT, "Uncaught exception in the SimpleTimer!", t);
|
||||
} else {
|
||||
System.err.println("Uncaught exception in SimpleTimer");
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < eventsToFire.size(); i++) {
|
||||
TimedEvent evt = (TimedEvent)eventsToFire.get(i);
|
||||
try {
|
||||
evt.timeReached();
|
||||
} catch (Throwable t) {
|
||||
log("wtf, event borked: " + evt, t);
|
||||
}
|
||||
}
|
||||
eventsToFire.clear();
|
||||
timesToRemove.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user