Changeset 3b46acc2


Ignore:
Timestamp:
Jul 17, 2013 6:56:26 PM (7 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
90cc71d
Parents:
d31ce49
Message:
  • I2CP client session - improvements after review:
    • Move more cleanups to finally block
    • Bounded wait
    • Don't ignore InterruptedExceptions?, wrap in I2PSessionException and throw
    • More finals
    • Synch tweaks
Location:
core/java/src/net/i2p/client
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • core/java/src/net/i2p/client/I2PSessionImpl.java

    rd31ce49 r3b46acc2  
    9393
    9494    /** class that generates new messages */
    95     protected I2CPMessageProducer _producer;
     95    protected final I2CPMessageProducer _producer;
    9696    /** map of Long --> MessagePayloadMessage */
    9797    protected Map<Long, MessagePayloadMessage> _availableMessages;
     
    102102    protected volatile int[] _bwLimits;
    103103   
    104     protected I2PClientMessageHandlerMap _handlerMap;
     104    protected final I2PClientMessageHandlerMap _handlerMap;
    105105   
    106106    /** used to seperate things out so we can get rid of singletons */
     
    120120    }
    121121
    122     protected State _state = State.CLOSED;
     122    private State _state = State.CLOSED;
    123123    protected final Object _stateLock = new Object();
    124124
     
    173173     * for extension by SimpleSession (no dest)
    174174     */
    175     protected I2PSessionImpl(I2PAppContext context, Properties options) {
    176         this(context, options, false);
     175    protected I2PSessionImpl(I2PAppContext context, Properties options,
     176                             I2PClientMessageHandlerMap handlerMap) {
     177        this(context, options, handlerMap, false);
    177178    }
    178179   
     
    181182     * @since 0.9.7
    182183     */
    183     private I2PSessionImpl(I2PAppContext context, Properties options, boolean hasDest) {
     184    private I2PSessionImpl(I2PAppContext context, Properties options,
     185                           I2PClientMessageHandlerMap handlerMap, boolean hasDest) {
    184186        _context = context;
     187        _handlerMap = handlerMap;
    185188        _log = context.logManager().getLog(getClass());
    186189        if (options == null)
     
    191194        _fastReceive = Boolean.parseBoolean(_options.getProperty(I2PClient.PROP_FAST_RECEIVE));
    192195        if (hasDest) {
     196            _producer = new I2CPMessageProducer(context);
     197            _availableMessages = new ConcurrentHashMap();
    193198            _myDestination = new Destination();
    194199            _privateKey = new PrivateKey();
    195200            _signingPrivateKey = new SigningPrivateKey();
    196201        } else {
     202            _producer = null;
     203            _availableMessages = null;
    197204            _myDestination = null;
    198205            _privateKey = null;
     
    211218     */
    212219    public I2PSessionImpl(I2PAppContext context, InputStream destKeyStream, Properties options) throws I2PSessionException {
    213         this(context, options, true);
    214         _handlerMap = new I2PClientMessageHandlerMap(context);
    215         _producer = new I2CPMessageProducer(context);
     220        this(context, options, new I2PClientMessageHandlerMap(context), true);
    216221        _availabilityNotifier = new AvailabilityNotifier();
    217         _availableMessages = new ConcurrentHashMap();
    218222        try {
    219223            readDestination(destKeyStream);
     
    395399                        wasOpening = true;
    396400                        try {
    397                             _stateLock.wait();
    398                         } catch (InterruptedException ie) {}
     401                            _stateLock.wait(10*1000);
     402                        } catch (InterruptedException ie) {
     403                            throw new I2PSessionException("Interrupted", ie);
     404                        }
    399405                        break;
    400406                    case CLOSING:
     
    443449                }
    444450            }
    445             Thread notifier = new I2PAppThread(_availabilityNotifier, "ClientNotifier " + getPrefix(), true);
    446             notifier.start();
    447451            if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "before startReading");
    448452            _reader.startReading();
     
    453457            while (!_dateReceived) {
    454458                if (waitcount++ > 30) {
    455                     closeSocket();
    456459                    throw new IOException("No handshake received from the router");
    457460                }
    458                 try {
    459                     synchronized (_dateReceivedLock) {
    460                         _dateReceivedLock.wait(1000);
    461                     }
    462                 } catch (InterruptedException ie) { // nop
     461                synchronized (_dateReceivedLock) {
     462                    // InterruptedException caught below
     463                    _dateReceivedLock.wait(1000);
    463464                }
    464465            }
     
    467468            if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Before producer.connect()");
    468469            _producer.connect(this);
    469             if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "After  producer.connect()");
     470            if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "After producer.connect()");
    470471
    471472            // wait until we have created a lease set
     
    473474            while (_leaseSet == null) {
    474475                if (waitcount++ > 5*60) {
    475                     try {
    476                         _producer.disconnect(this);
    477                     } catch (I2PSessionException ipe) {}
    478                     closeSocket();
    479476                    throw new IOException("No tunnels built after waiting 5 minutes. Your network connection may be down, or there is severe network congestion.");
    480477                }
    481478                synchronized (_leaseSetWait) {
    482                     try {
    483                         _leaseSetWait.wait(1000);
    484                     } catch (InterruptedException ie) { // nop
    485                     }
    486                 }
    487             }
    488             long connected = _context.clock().now();
    489             if (_log.shouldLog(Log.INFO))
     479                    // InterruptedException caught below
     480                    _leaseSetWait.wait(1000);
     481                }
     482            }
     483            if (_log.shouldLog(Log.INFO)) {
     484                long connected = _context.clock().now();
    490485                 _log.info(getPrefix() + "Lease set created with inbound tunnels after "
    491486                           + (connected - startConnect)
    492487                           + "ms - ready to participate in the network!");
     488            }
     489            Thread notifier = new I2PAppThread(_availabilityNotifier, "ClientNotifier " + getPrefix(), true);
     490            notifier.start();
    493491            startIdleMonitor();
    494492            startVerifyUsage();
    495493            success = true;
     494        } catch (InterruptedException ie) {
     495            throw new I2PSessionException("Interrupted", ie);
    496496        } catch (UnknownHostException uhe) {
    497497            throw new I2PSessionException(getPrefix() + "Cannot connect to the router on " + _hostname + ':' + _portNum, uhe);
     
    499499            throw new I2PSessionException(getPrefix() + "Cannot connect to the router on " + _hostname + ':' + _portNum, ioe);
    500500        } finally {
    501             changeState(success ? State.OPEN : State.CLOSED);
     501            if (success) {
     502                changeState(State.OPEN);
     503            } else {
     504                _availabilityNotifier.stopNotifying();
     505                synchronized(_stateLock) {
     506                    changeState(State.CLOSING);
     507                    try {
     508                        _producer.disconnect(this);
     509                    } catch (I2PSessionException ipe) {}
     510                    closeSocket();
     511                }
     512            }
    502513        }
    503514    }
     
    724735     *  False when open and during transitions. Unsynchronized.
    725736     */
    726     public boolean isClosed() { return _state == State.CLOSED; }
     737    public boolean isClosed() {
     738        synchronized (_stateLock) {
     739            return _state == State.CLOSED;
     740        }
     741    }
    727742
    728743    /**
     
    741756                    throw new I2PSessionException("Timed out waiting while write queue was full");
    742757            } catch (InterruptedException ie) {
    743                 throw new I2PSessionException("Interrupted while write queue was full", ie);
     758                throw new I2PSessionException("Interrupted", ie);
    744759            }
    745760        } else if (_writer == null) {
     
    903918            if ( (delay > MAX_RECONNECT_DELAY) || (delay <= 0) )
    904919                delay = MAX_RECONNECT_DELAY;
    905             try { Thread.sleep(delay); } catch (InterruptedException ie) {}
     920            try {
     921                Thread.sleep(delay);
     922            } catch (InterruptedException ie) {
     923                return false;
     924            }
    906925           
    907926            try {
     
    10181037                    waiter.wait(maxWait);
    10191038                }
    1020             } catch (InterruptedException ie) {}
     1039            } catch (InterruptedException ie) {
     1040                throw new I2PSessionException("Interrupted", ie);
     1041            }
    10211042        } finally {
    10221043            _pendingLookups.remove(waiter);
     
    10411062                _bwReceivedLock.wait(5*1000);
    10421063            }
    1043         } catch (InterruptedException ie) {}
     1064        } catch (InterruptedException ie) {
     1065            throw new I2PSessionException("Interrupted", ie);
     1066        }
    10441067        return _bwLimits;
    10451068    }
  • core/java/src/net/i2p/client/I2PSessionImpl2.java

    rd31ce49 r3b46acc2  
    4545    protected boolean _noEffort;
    4646
    47     /** for extension */
    48     protected I2PSessionImpl2(I2PAppContext context, Properties options) {
    49         super(context, options);
     47     /**
     48      * for extension by SimpleSession (no dest)
     49      */
     50    protected I2PSessionImpl2(I2PAppContext context, Properties options,
     51                              I2PClientMessageHandlerMap handlerMap) {
     52        super(context, options, handlerMap);
    5053    }
    5154
  • core/java/src/net/i2p/client/I2PSimpleSession.java

    rd31ce49 r3b46acc2  
    3939     */
    4040    public I2PSimpleSession(I2PAppContext context, Properties options) throws I2PSessionException {
    41         super(context, options);
    42         _handlerMap = new SimpleMessageHandlerMap(context);
     41        super(context, options, new SimpleMessageHandlerMap(context));
    4342    }
    4443
Note: See TracChangeset for help on using the changeset viewer.