Changeset 46fe429


Ignore:
Timestamp:
Mar 23, 2015 1:59:05 PM (6 years ago)
Author:
str4d <str4d@…>
Branches:
master
Children:
b875e28
Parents:
9790d3b
Message:

States for TunnelController? (#815)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java

    r9790d3b r46fe429  
    4343    private final List<String> _messages;
    4444    private List<I2PSession> _sessions;
    45     private boolean _running;
    46     private boolean _starting;
     45    private volatile TunnelState _state;
     46
     47    private enum TunnelState {
     48        START_ON_LOAD,
     49        STARTING,
     50        RUNNING,
     51        STOPPING,
     52        STOPPED,
     53        DESTROYING,
     54        DESTROYED,
     55    }
    4756   
    4857    public static final String KEY_BACKUP_DIR = "i2ptunnel-keyBackup";
     
    125134        setConfig(config, prefix);
    126135        _messages = new ArrayList<String>(4);
    127         _running = false;
    128136        boolean keyOK = true;
    129137        if (createKey && (getType().endsWith("server") || getPersistentClientKey()))
    130138            keyOK = createPrivateKey();
    131         _starting = keyOK && getStartOnLoad();
     139        _state = keyOK && getStartOnLoad() ? TunnelState.START_ON_LOAD : TunnelState.STOPPED;
    132140    }
    133141   
     
    194202   
    195203    public void startTunnelBackground() {
    196         if (_running) return;
    197         _starting = true;
     204        synchronized (this) {
     205            if (_state != TunnelState.STOPPED && _state != TunnelState.START_ON_LOAD)
     206                return;
     207        }
    198208        new I2PAppThread(new Runnable() { public void run() { startTunnel(); } }).start();
    199209    }
     
    204214     */
    205215    public void startTunnel() {
    206         _starting = true;
     216        synchronized (this) {
     217            if (_state != TunnelState.STOPPED && _state != TunnelState.START_ON_LOAD) {
     218                if (_state == TunnelState.RUNNING) {
     219                    if (_log.shouldLog(Log.INFO))
     220                        _log.info("Already running");
     221                    log("Tunnel " + getName() + " is already running");
     222                }
     223                return;
     224            }
     225            changeState(TunnelState.STARTING);
     226        }
    207227        try {
    208228            doStartTunnel();
     
    214234            stopTunnel();
    215235        }
    216         _starting = false;
    217236    }
    218237
     
    221240     */
    222241    private void doStartTunnel() {
    223         if (_running) {
    224             if (_log.shouldLog(Log.INFO))
    225                 _log.info("Already running");
    226             log("Tunnel " + getName() + " is already running");
    227             return;
    228         }
     242        synchronized (this) {
     243            if (_state != TunnelState.STARTING)
     244                return;
     245        }
     246
    229247        String type = getType();
    230248        if ( (type == null) || (type.length() <= 0) ) {
     249            changeState(TunnelState.STOPPED);
    231250            if (_log.shouldLog(Log.ERROR))
    232251                _log.error("Cannot start the tunnel - no type specified");
     
    238257            boolean ok = createPrivateKey();
    239258            if (!ok) {
     259                changeState(TunnelState.STOPPED);
    240260                log("Failed to start tunnel " + getName() + " as the private key file could not be created");
    241261                return;
     
    269289            startStreamrServer();
    270290        } else {
     291            changeState(TunnelState.STOPPED);
    271292            if (_log.shouldLog(Log.ERROR))
    272293                _log.error("Cannot start tunnel - unknown type [" + type + "]");
     
    274295        }
    275296        acquire();
    276         _running = true;
     297        changeState(TunnelState.RUNNING);
    277298    }
    278299   
     
    555576     */
    556577    public void stopTunnel() {
     578        synchronized (this) {
     579            if (_state != TunnelState.RUNNING)
     580                return;
     581            changeState(TunnelState.STOPPING);
     582        }
    557583        // I2PTunnel removes the session in close(),
    558584        // so save the sessions to pass to release() and TCG
     
    560586        _tunnel.runClose(new String[] { "forced", "all" }, this);
    561587        release(sessions);
    562         _running = false;
     588        changeState(TunnelState.STOPPED);
    563589    }
    564590
     
    570596     */
    571597    public void destroyTunnel() {
     598        synchronized (this) {
     599            if (_state != TunnelState.RUNNING)
     600                return;
     601            changeState(TunnelState.DESTROYING);
     602        }
    572603        // I2PTunnel removes the session in close(),
    573604        // so save the sessions to pass to release() and TCG
     
    575606        _tunnel.runClose(new String[] { "destroy", "all" }, this);
    576607        release(sessions);
    577         _running = false;
     608        changeState(TunnelState.DESTROYED);
    578609    }
    579610   
     
    627658        setSessionOptions();
    628659
    629         if (_running) {
    630             Collection<I2PSession> sessions = getAllSessions();
    631             if (sessions.isEmpty()) {
    632                  if (_log.shouldLog(Log.DEBUG))
    633                      _log.debug("Running but no sessions to update");
    634             }
    635             for (I2PSession s : sessions) {
    636                 // tell the router via the session
    637                 if (!s.isClosed()) {
    638                     if (_log.shouldLog(Log.DEBUG))
    639                         _log.debug("Session is open, updating: " + s);
    640                     s.updateOptions(_tunnel.getClientOptions());
    641                 } else {
    642                     if (_log.shouldLog(Log.DEBUG))
    643                         _log.debug("Session is closed, not updating: " + s);
     660        synchronized (this) {
     661            if (_state != TunnelState.RUNNING) {
     662                if (_log.shouldLog(Log.DEBUG)) {
     663                    _log.debug("Not running, not updating sessions");
    644664                }
    645             }
    646         } else {
    647             if (_log.shouldLog(Log.DEBUG)) {
    648                 _log.debug("Not running, not updating sessions");
     665                return;
     666            }
     667        }
     668        // Running, so check sessions
     669        Collection<I2PSession> sessions = getAllSessions();
     670        if (sessions.isEmpty()) {
     671             if (_log.shouldLog(Log.DEBUG))
     672                 _log.debug("Running but no sessions to update");
     673        }
     674        for (I2PSession s : sessions) {
     675            // tell the router via the session
     676            if (!s.isClosed()) {
     677                if (_log.shouldLog(Log.DEBUG))
     678                    _log.debug("Session is open, updating: " + s);
     679                s.updateOptions(_tunnel.getClientOptions());
     680            } else {
     681                if (_log.shouldLog(Log.DEBUG))
     682                    _log.debug("Session is closed, not updating: " + s);
    649683            }
    650684        }
     
    795829    }
    796830   
    797     public boolean getIsRunning() { return _running; }
    798     public boolean getIsStarting() { return _starting; }
     831    public boolean getIsRunning() { return _state == TunnelState.RUNNING; }
     832    public boolean getIsStarting() { return _state == TunnelState.START_ON_LOAD || _state == TunnelState.STARTING; }
    799833
    800834    /** if running but no open sessions, we are in standby */
    801835    public boolean getIsStandby() {
    802         if (!_running)
    803             return false;
     836        synchronized (this) {
     837            if (_state != TunnelState.RUNNING)
     838                return false;
     839        }
     840
    804841        for (I2PSession sess : _tunnel.getSessions()) {
    805842            if (!sess.isClosed())
     
    807844        }
    808845        return true;
     846    }
     847
     848    private synchronized void changeState(TunnelState state) {
     849        _state = state;
    809850    }
    810851   
     
    928969     */
    929970    public void log(String s) {
    930         synchronized (this) {
     971        synchronized (_messages) {
    931972            _messages.add(s);
    932973            while (_messages.size() > 10)
     
    944985    public List<String> clearMessages() {
    945986        List<String> rv = null;
    946         synchronized (this) {
     987        synchronized (_messages) {
    947988            rv = new ArrayList<String>(_messages);
    948989            _messages.clear();
     
    956997    @Override
    957998    public String toString() {
    958         return "TC " + getType() + ' ' + getName() + " for " + _tunnel;
     999        return "TC " + getType() + ' ' + getName() + " for " + _tunnel + ' ' + _state;
    9591000    }
    9601001}
Note: See TracChangeset for help on using the changeset viewer.