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:
jrandom
2004-09-07 07:17:02 +00:00
committed by zzz
parent e57aa68854
commit 6151d63eac
18 changed files with 611 additions and 394 deletions

View File

@ -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();
}
}
}

View File

@ -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.

View File

@ -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;

View File

@ -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());

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}