Thanks. A similar patch will go into CVS ASAP.
On Sun, Sep 21, 2003 at 04:14:19PM -0400, Edward J. Huff wrote:
> I'm trying my hand at debugging this....
>
> It looks to me like the problem is that a ConnectionHandler
> was removed from the OCM twice, and that LRUQueue.remove
> should check the QItem pointer before calling list.remove().
> But maybe a ConnectionHandler should never be removed twice.
>
> *** src/freenet/support/LRUQueue.java 2003-09-21 16:05:15.000000000 -0400
> --- src/freenet/support/LRUQueue.java.~1.4.~ 2003-09-15 22:05:02.000000000 -0400
> ***************
> *** 47,56 ****
> }
>
> public final synchronized void remove(Object obj) {
> ! QItem i = (QItem)hash.remove(obj);
> ! if (i != null) { // may remove item not on LRUQueue.
> ! list.remove(i);
> ! }
> }
>
> public Enumeration elements() {
> --- 47,53 ----
> }
>
> public final synchronized void remove(Object obj) {
> ! list.remove((QItem)hash.remove(obj));
> }
>
> public Enumeration elements() {
>
>
> ----- annotated traceback ------
>
> java.lang.NullPointerException
> at
> freenet.support.DoublyLinkedListImpl.remove
> (DoublyLinkedListImpl.java:195)
>
> 194 public DoublyLinkedList.Item remove(DoublyLinkedList.Item i) {
> 195 DoublyLinkedList.Item next = i.getNext(), prev = i.getPrev();
>
> The null pointer must be i. getNext and getPrev do not dereference
> any pointers.
>
> at
> freenet.support.LRUQueue.remove
> (LRUQueue.java:50)
>
> 16 private final Hashtable hash = new Hashtable();
> 49 public final synchronized void remove(Object obj) {
> 50 list.remove((QItem)hash.remove(obj));
>
> As it happens, hash.remove will return null if obj is
> not in the hashtable.
>
> ------------
> (java.util.Hashtable)
> java.util
> Interface Map
> public Object remove(Object key)
>
> Removes the mapping for this key from this map if present
> (optional operation).
>
> Parameters:
> key - key whose mapping is to be removed from the map.
> Returns:
> previous value associated with specified key, or null if there
> was no mapping for key. A null return can also indicate that
> the map previously associated null with the specified key, if
> the implementation supports null values.
> Throws:
> UnsupportedOperationException - if the remove method is not
> supported by this map.
> --------------
>
> at
> freenet.OpenConnectionManager.remove
> (OpenConnectionManager.java:130)
>
> 56 private final LRUQueue lru = new LRUQueue();
> 110 ConnectionHandler remove(ConnectionHandler ch) {
> 130 lru.remove(ch); // is synchronized(lru)
>
> at
> freenet.ConnectionHandler.removeFromOCM
> (ConnectionHandler.java:2723)
>
> 46 private final OpenConnectionManager ocm;
> 149 private Identity identity;
> 235 public ConnectionHandler(OpenConnectionManager ocm,
> 245 this.ocm = ocm;
> 253 this.identity = link.getPeerIdentity();
> 2721 private final void removeFromOCM() {
> 2722 if (identity != null)
> 2723 ocm.remove(this);
>
>
> at
> freenet.ConnectionHandler.terminate
> (ConnectionHandler.java:2763)
>
> public void terminate() {
> // if(unregisteredFromOCM) decOpenButNotOnOCM();
> logDEBUG = Core.logger.shouldLog(Logger.DEBUG,this);
> if(logDEBUG) logDEBUG("Terminating", true);
> // Unconditionally remove the connection handler
> // from the OCM
> // This should be the ONLY place we call it from
> // To avoid leaking conns, we keep everything open in the OCM
> removeFromOCM();
>
>
> at
> freenet.ConnectionHandler.queuedClose
> (ConnectionHandler.java:1249)
> (omitted debug stuff.)
>
> public void queuedClose() {
> terminate();
> }
>
> at
> freenet.transport.AbstractSelectorLoop.queueClose
> (AbstractSelectorLoop.java:680)
>
> protected void queueClose(ClosePair chan) {
> if(chan.attachment != null)
> ((NIOCallback)(chan.attachment)).queuedClose();
>
> at
> freenet.transport.AbstractSelectorLoop.queueClose
> (AbstractSelectorLoop.java:728)
> 40 private static Hashtable closeUniqueness = null; //FIXME:hardcoded
> 119 if (closeUniqueness == null)
> closeUniqueness = new Hashtable(512);
> 161 protected final class ClosePair {
> public Connection conn;
> public Object attachment;
> public SocketChannel sc;
> public long timeStamp; //debugging. Can be removed eventually
>
> public ClosePair(Connection conn, Object attachment,
> SocketChannel sc) {
> this.conn = conn;
> this.attachment = attachment;
> this.sc = sc;
> timeStamp = System.currentTimeMillis();
> }
>
> public String toString() {
> return conn.toString()+":"+((attachment == null) ? "(null)" :
> attachment.toString())+":"+sc;
> }
> }
>
> 716 public void queueClose(SocketChannel chan, NIOCallback nc) {
> if(chan == null) return;
> Socket sock = chan.socket();
> if(sock == null) return;
> Connection c = tcpConnection.getConnectionForSocket(sock);
> if(c == null) {
> if(chan.isConnected() && chan.isOpen())
> throw new IllegalArgumentException("Fed socket not connected "+
> "to a tcpConnection!: "+chan);
> else return;
> }
> if (closeUniqueness.containsKey(c)) return;
> 728 queueClose(new ClosePair(c,nc,chan));
> }
>
> at
> freenet.transport.ReadSelectorLoop.inspectChannels
> (ReadSelectorLoop.java:307)
>
> 180 protected final boolean inspectChannels() {
> 193 while (i.hasNext()) {
> SelectionKey current = (SelectionKey)i.next();
>
> NIOReader nc = (NIOReader)current.attachment();
> SocketChannel sc = (SocketChannel)current.channel();
> int size=0;
> try { ...
> try { ...
> } catch (IOException e) { ...
> size = -1;
> }
> } catch (Throwable e) { ...
> size = -1; // try unregistering it...
> }
> 294 if (size == -1) {
> //TODO: log that this channel got closed.
> // and mark its Connection object as closed. (that'll be tricky)
> if(logDebug)
> Core.logger.log(this, "Closed (read -1): "+current,
> Logger.DEBUG);
> SelectionKey k = sc.keyFor(sel);
> k.attach(null);
> k.cancel();
>
> // queueClose BEFORE notifying unregistration.
> // So that if we wait on unregistration, and then check closure,
> // we get the right sane answer.
> 307 queueClose((SocketChannel)sc, nc);
> nc.unregistered();
> noneWorking = false;
> 310 } else if ...
> 344 }
>
>
>
> at
> freenet.transport.AbstractSelectorLoop.loop
> (AbstractSelectorLoop.java:625)
> at
> freenet.transport.ReadSelectorLoop.run
> (ReadSelectorLoop.java:436)
> public final void run() {
>
> loop();
> }
> at
> java.lang.Thread.run(Thread.java:536)
>
>
>
> --
> Edward J. Huff <[EMAIL PROTECTED]>
> _______________________________________________
> Devl mailing list
> [EMAIL PROTECTED]
> http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/devl-- Matthew J Toseland - [EMAIL PROTECTED] Freenet Project Official Codemonkey - http://freenetproject.org/ ICTHUS - Nothing is impossible. Our Boss says so.
signature.asc
Description: Digital signature
_______________________________________________ Devl mailing list [EMAIL PROTECTED] http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/devl
