forked from I2P_Developers/i2p.i2p
context: New ClientAppManagerImpl in AppContext, so registration
works there (for i2psnark-rpc in standalone)
This commit is contained in:
@ -8,6 +8,7 @@ import java.util.Random;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.i2p.app.ClientAppManager;
|
import net.i2p.app.ClientAppManager;
|
||||||
|
import net.i2p.app.ClientAppManagerImpl;
|
||||||
import net.i2p.client.naming.NamingService;
|
import net.i2p.client.naming.NamingService;
|
||||||
import net.i2p.crypto.AESEngine;
|
import net.i2p.crypto.AESEngine;
|
||||||
import net.i2p.crypto.CryptixAESEngine;
|
import net.i2p.crypto.CryptixAESEngine;
|
||||||
@ -116,6 +117,7 @@ public class I2PAppContext {
|
|||||||
private final File _appDir;
|
private final File _appDir;
|
||||||
private volatile File _tmpDir;
|
private volatile File _tmpDir;
|
||||||
private final Random _tmpDirRand = new Random();
|
private final Random _tmpDirRand = new Random();
|
||||||
|
private final ClientAppManager _appManager;
|
||||||
// split up big lock on this to avoid deadlocks
|
// split up big lock on this to avoid deadlocks
|
||||||
private final Object _lock1 = new Object(), _lock2 = new Object(), _lock3 = new Object(), _lock4 = new Object(),
|
private final Object _lock1 = new Object(), _lock2 = new Object(), _lock3 = new Object(), _lock4 = new Object(),
|
||||||
_lock5 = new Object(), _lock6 = new Object(), _lock7 = new Object(), _lock8 = new Object(),
|
_lock5 = new Object(), _lock6 = new Object(), _lock7 = new Object(), _lock8 = new Object(),
|
||||||
@ -198,6 +200,7 @@ public class I2PAppContext {
|
|||||||
_overrideProps.putAll(envProps);
|
_overrideProps.putAll(envProps);
|
||||||
_shutdownTasks = new ConcurrentHashSet<Runnable>(32);
|
_shutdownTasks = new ConcurrentHashSet<Runnable>(32);
|
||||||
_portMapper = new PortMapper(this);
|
_portMapper = new PortMapper(this);
|
||||||
|
_appManager = isRouterContext() ? null : new ClientAppManagerImpl(this);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Directories. These are all set at instantiation and will not be changed by
|
* Directories. These are all set at instantiation and will not be changed by
|
||||||
@ -1007,8 +1010,11 @@ public class I2PAppContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The RouterAppManager in RouterContext, null always in I2PAppContext
|
* As of 0.9.30, returns non-null in I2PAppContext, null in RouterContext.
|
||||||
* @return null always
|
* Prior to that, returned null always.
|
||||||
|
* Overridden in RouterContext to return the RouterAppManager.
|
||||||
|
*
|
||||||
|
* @return As of 0.9.30, returns non-null in I2PAppContext, null in RouterContext
|
||||||
* @since 0.9.11, in RouterContext since 0.9.4
|
* @since 0.9.11, in RouterContext since 0.9.4
|
||||||
*/
|
*/
|
||||||
public ClientAppManager clientAppManager() {
|
public ClientAppManager clientAppManager() {
|
||||||
|
67
core/java/src/net/i2p/app/ClientAppManagerImpl.java
Normal file
67
core/java/src/net/i2p/app/ClientAppManagerImpl.java
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package net.i2p.app;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import net.i2p.I2PAppContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple ClientAppManager that supports register/unregister only,
|
||||||
|
* so that client apps may find each other in AppContext.
|
||||||
|
* See RouterAppManager for the real thing in RouterContext.
|
||||||
|
*
|
||||||
|
* @since 0.9.30
|
||||||
|
*/
|
||||||
|
public class ClientAppManagerImpl implements ClientAppManager {
|
||||||
|
|
||||||
|
// registered name to client
|
||||||
|
protected final ConcurrentHashMap<String, ClientApp> _registered;
|
||||||
|
|
||||||
|
public ClientAppManagerImpl(I2PAppContext ctx) {
|
||||||
|
_registered = new ConcurrentHashMap<String, ClientApp>(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does nothing.
|
||||||
|
*
|
||||||
|
* @param app non-null
|
||||||
|
* @param state non-null
|
||||||
|
* @param message may be null
|
||||||
|
* @param e may be null
|
||||||
|
*/
|
||||||
|
public void notify(ClientApp app, ClientAppState state, String message, Exception e) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register with the manager under the given name,
|
||||||
|
* so that other clients may find it.
|
||||||
|
* Only required for apps used by other apps.
|
||||||
|
*
|
||||||
|
* @param app non-null
|
||||||
|
* @return true if successful, false if duplicate name
|
||||||
|
*/
|
||||||
|
public boolean register(ClientApp app) {
|
||||||
|
return _registered.putIfAbsent(app.getName(), app) == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister with the manager. Name must be the same as that from register().
|
||||||
|
* Only required for apps used by other apps.
|
||||||
|
*
|
||||||
|
* @param app non-null
|
||||||
|
*/
|
||||||
|
public void unregister(ClientApp app) {
|
||||||
|
_registered.remove(app.getName(), app);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a registered app.
|
||||||
|
* Only used for apps finding other apps.
|
||||||
|
* Do not hold a static reference.
|
||||||
|
* If you only need to find a port, use the PortMapper instead.
|
||||||
|
*
|
||||||
|
* @param name non-null
|
||||||
|
* @return client app or null
|
||||||
|
*/
|
||||||
|
public ClientApp getRegisteredApp(String name) {
|
||||||
|
return _registered.get(name);
|
||||||
|
}
|
||||||
|
}
|
@ -22,21 +22,19 @@ import net.i2p.util.Log;
|
|||||||
*
|
*
|
||||||
* @since 0.9.4
|
* @since 0.9.4
|
||||||
*/
|
*/
|
||||||
public class RouterAppManager implements ClientAppManager {
|
public class RouterAppManager extends ClientAppManagerImpl {
|
||||||
|
|
||||||
private final RouterContext _context;
|
private final RouterContext _context;
|
||||||
private final Log _log;
|
private final Log _log;
|
||||||
// client to args
|
// client to args
|
||||||
// this assumes clients do not override equals()
|
// this assumes clients do not override equals()
|
||||||
private final ConcurrentHashMap<ClientApp, String[]> _clients;
|
private final ConcurrentHashMap<ClientApp, String[]> _clients;
|
||||||
// registered name to client
|
|
||||||
private final ConcurrentHashMap<String, ClientApp> _registered;
|
|
||||||
|
|
||||||
public RouterAppManager(RouterContext ctx) {
|
public RouterAppManager(RouterContext ctx) {
|
||||||
|
super(ctx);
|
||||||
_context = ctx;
|
_context = ctx;
|
||||||
_log = ctx.logManager().getLog(RouterAppManager.class);
|
_log = ctx.logManager().getLog(RouterAppManager.class);
|
||||||
_clients = new ConcurrentHashMap<ClientApp, String[]>(16);
|
_clients = new ConcurrentHashMap<ClientApp, String[]>(16);
|
||||||
_registered = new ConcurrentHashMap<String, ClientApp>(8);
|
|
||||||
ctx.addShutdownTask(new Shutdown());
|
ctx.addShutdownTask(new Shutdown());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +89,7 @@ public class RouterAppManager implements ClientAppManager {
|
|||||||
* @param message may be null
|
* @param message may be null
|
||||||
* @param e may be null
|
* @param e may be null
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void notify(ClientApp app, ClientAppState state, String message, Exception e) {
|
public void notify(ClientApp app, ClientAppState state, String message, Exception e) {
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case UNINITIALIZED:
|
case UNINITIALIZED:
|
||||||
@ -137,6 +136,7 @@ public class RouterAppManager implements ClientAppManager {
|
|||||||
* @param app non-null
|
* @param app non-null
|
||||||
* @return true if successful, false if duplicate name
|
* @return true if successful, false if duplicate name
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean register(ClientApp app) {
|
public boolean register(ClientApp app) {
|
||||||
if (!_clients.containsKey(app)) {
|
if (!_clients.containsKey(app)) {
|
||||||
// Allow registration even if we didn't start it,
|
// Allow registration even if we didn't start it,
|
||||||
@ -148,32 +148,9 @@ public class RouterAppManager implements ClientAppManager {
|
|||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("Client " + app.getDisplayName() + " REGISTERED AS " + app.getName());
|
_log.info("Client " + app.getDisplayName() + " REGISTERED AS " + app.getName());
|
||||||
// TODO if old app in there is not running and != this app, allow replacement
|
// TODO if old app in there is not running and != this app, allow replacement
|
||||||
return _registered.putIfAbsent(app.getName(), app) == null;
|
return super.register(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregister with the manager. Name must be the same as that from register().
|
|
||||||
* Only required for apps used by other apps.
|
|
||||||
*
|
|
||||||
* @param app non-null
|
|
||||||
*/
|
|
||||||
public void unregister(ClientApp app) {
|
|
||||||
_registered.remove(app.getName(), app);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a registered app.
|
|
||||||
* Only used for apps finding other apps.
|
|
||||||
* Do not hold a static reference.
|
|
||||||
* If you only need to find a port, use the PortMapper instead.
|
|
||||||
*
|
|
||||||
* @param name non-null
|
|
||||||
* @return client app or null
|
|
||||||
*/
|
|
||||||
public ClientApp getRegisteredApp(String name) {
|
|
||||||
return _registered.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// end ClientAppManager interface
|
/// end ClientAppManager interface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user