Update of /cvsroot/freenet/freenet/src/freenet/transport
In directory sc8-pr-cvs1:/tmp/cvs-serv4026/src/freenet/transport

Modified Files:
        ReadSelectorLoop.java AbstractSelectorLoop.java 
Log Message:
Create a class for the waitersQueue, relieves the enqueuer of a couple synchronize().
Decrease the scope of the locks in processWaiters.

Index: ReadSelectorLoop.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/transport/ReadSelectorLoop.java,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -w -r1.60 -r1.61
--- ReadSelectorLoop.java       25 Oct 2003 08:04:29 -0000      1.60
+++ ReadSelectorLoop.java       29 Oct 2003 10:34:56 -0000      1.61
@@ -145,8 +145,7 @@
                     } else {
                         if(logDebug)
                             Core.logger.log(this, "Maintenance process returned -1 
but not registered on selector, queuing for unregistration", Logger.DEBUG);
-                        unregisterWaiters.add(new ChannelAttachmentPair
-                                              (chan, current));
+                        unregisterWaiters.add(new ChannelAttachmentPair(chan, 
current));
                     }
                     queueClose((SocketChannel)chan,current);
                 } else if (status == 0) {
@@ -158,8 +157,7 @@
                     } else {
                         if(logDebug)
                             Core.logger.log(this, "Maintenance process returned 0 but 
not registered on selector, queuing for unregistration", Logger.DEBUG);
-                        unregisterWaiters.add(new ChannelAttachmentPair
-                                              (chan, current));
+                        unregisterWaiters.add(new ChannelAttachmentPair(chan, 
current));
                     }
                     synchronized(dontReregister) {
                         dontReregister.add(chan);

Index: AbstractSelectorLoop.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/transport/AbstractSelectorLoop.java,v
retrieving revision 1.85
retrieving revision 1.86
diff -u -w -r1.85 -r1.86
--- AbstractSelectorLoop.java   28 Oct 2003 03:02:50 -0000      1.85
+++ AbstractSelectorLoop.java   29 Oct 2003 10:34:56 -0000      1.86
@@ -21,7 +21,10 @@
  */
 
 public abstract class AbstractSelectorLoop implements SelectorLoop{
-       protected LinkedList registerWaiters, unregisterWaiters, delayedWaiters;
+       //protected LinkedList registerWaiters, unregisterWaiters, delayedWaiters;
+       protected ChannelAttachmentPairQueue registerWaiters= new 
ChannelAttachmentPairQueue();
+       protected ChannelAttachmentPairQueue unregisterWaiters= new 
ChannelAttachmentPairQueue();
+       protected ChannelAttachmentPairQueue delayedWaiters= new 
ChannelAttachmentPairQueue();
        protected Selector sel;
        
        protected Set currentSet;
@@ -106,9 +109,6 @@
 
        public AbstractSelectorLoop() throws IOException{
                sel = Selector.open();
-               registerWaiters = new LinkedList();
-               unregisterWaiters = new LinkedList();
-               delayedWaiters = new LinkedList();
                stop = false;
                cleanupNeeded=false;
                timeout = TIMEOUT;
@@ -146,6 +146,38 @@
                                                                                   
attachment.toString());
                }
        }
+       /**
+        * a synchronized queue that accepts single or bunched ChannelAttachmentPair:s 
and returns a list containing all items queued
+        */
+       protected class ChannelAttachmentPairQueue {
+               private LinkedList queue = new LinkedList();
+               private Object queueLock = new Object();
+
+               //Adds the ChannelAttachmentPair to the queue
+               void add(ChannelAttachmentPair cap) {
+                       synchronized(queueLock){
+                               queue.add(cap);
+                       }
+               }
+               void addAll(LinkedList l) {
+                       synchronized(queueLock){
+                               queue.addAll(l);
+                       }
+               }
+               //Returns and flushes the current queue
+               //If no items is queued then null is returned
+               LinkedList get() {
+                       //Avoid locking and allocation if we dont have any items queued
+                       //There shuldn't be any real drawback with keeping this check 
unsynchronized
+                       if(queue.size()==0)
+                               return null;
+                       synchronized(queueLock){
+                               LinkedList retval = queue;
+                               queue = new LinkedList();
+                               return retval;
+                       }
+               }
+       }
        
        protected final class DelayedChannelAttachmentPair extends 
ChannelAttachmentPair {
                public final long registerTime;
@@ -186,9 +218,8 @@
                }
                //minimize the number of exceptions in the select thread, check early
                if (ch.isBlocking()) throw new IllegalBlockingModeException();
-               synchronized(registerWaiters) {
                        registerWaiters.add(new ChannelAttachmentPair(ch, attachment));
-               }
+
        }
 
        public final void register(Socket sock, Object attachment) throws 
IllegalBlockingModeException {
@@ -201,19 +232,15 @@
                if(logDebug)
                        Core.logger.log(this, "Unregistering "+chan, 
                                                        new Exception("debug"), 
Logger.DEBUG);
-               synchronized(unregisterWaiters) {
                        unregisterWaiters.add(new ChannelAttachmentPair(chan,null));
                }
-       }
 
        public final void unregister(Object attachment) {
                if(logDebug)
                        Core.logger.log(this, "Unregistering "+attachment, 
                                                        new Exception("debug"), 
Logger.DEBUG);
-               synchronized(unregisterWaiters) {
                        unregisterWaiters.add(new 
ChannelAttachmentPair(null,attachment));
                }
-       }
 
        public final boolean isOpen() {
                return sel.isOpen();
@@ -240,40 +267,40 @@
         */
        protected final void processWaiters() {
 
-               while (delayedWaiters.size() > 0) {
+               LinkedList waitersToProcess = delayedWaiters.get();
+               while (waitersToProcess != null && waitersToProcess.size() > 0) {
                        DelayedChannelAttachmentPair current = 
-                               (DelayedChannelAttachmentPair) 
delayedWaiters.removeFirst();
+                               (DelayedChannelAttachmentPair) 
waitersToProcess.removeFirst();
                        if (System.currentTimeMillis() >= current.registerTime)
                                registerWaiters.add(current);
                        else
-                               delayedWaiters.add(current);
+                               delayedWaiters.add(current); //TODO: Would it be 
better to avoid a bunch of finegrained put():s by using an putAll() instead
                }
                //TODO: find a way to get the try's out of the loop
                //first add
                LinkedList notRegistered = new LinkedList();
-               synchronized(registerWaiters) {
-                       while(registerWaiters.size() >0) {
-                               ChannelAttachmentPair current = 
(ChannelAttachmentPair)registerWaiters.removeFirst();
+               waitersToProcess = registerWaiters.get();
+               while (waitersToProcess != null && waitersToProcess.size() > 0) {
+                       ChannelAttachmentPair current = (ChannelAttachmentPair) 
waitersToProcess.removeFirst();
                                
                                if (myKeyOps() == SelectionKey.OP_ACCEPT) //this is a 
server socket
                                        try{
                                                current.channel.register(sel, 
SelectionKey.OP_ACCEPT, current.attachment);
-                                       }catch(ClosedChannelException e) {continue;}
-                               else if (myKeyOps() == SelectionKey.OP_READ) {
+                               } catch (ClosedChannelException e) {
+                                       continue;
+                               } else if (myKeyOps() == SelectionKey.OP_READ) {
                                        //a reader, writers get registered on the fly
-                                       if(!current.channel.isOpen()) continue;
+                               if (!current.channel.isOpen())
+                                       continue;
                                        if(shouldRegister(current)) {
                                                try {
-                                                       if 
(current.channel.keyFor(sel) ==null ||
-                                                               
!current.channel.keyFor(sel).isValid()) {
-                                                                       
current.channel.register(sel, SelectionKey.OP_READ,
-                                                                                      
                  current.attachment);
+                                               if (current.channel.keyFor(sel) == 
null || !current.channel.keyFor(sel).isValid()) {
+                                                       current.channel.register(sel, 
SelectionKey.OP_READ, current.attachment);
                                                                        
((NIOCallback)current.attachment).registered();
                                                        }
                                                } catch(ClosedChannelException e) {
                                                        if(current.attachment 
instanceof NIOCallback)
-                                                               
((NIOCallback)current.attachment).
-                                                                       unregistered();
+                                                        ((NIOCallback) 
current.attachment).unregistered();
                                                        try {
                                                                queueClose(current);
                                                        } catch 
(IllegalArgumentException x) {
@@ -286,49 +313,45 @@
                                                } catch (CancelledKeyException e) {
                                                        //do nothing?
                                                        if (logDebug)
-                                                               
Core.logger.log(this,"cought "+e,Logger.DEBUG);
+                                                       Core.logger.log(this, "caught 
" + e, Logger.DEBUG);
                                                }
                                        } else {
                                                notRegistered.add(current);
                                        }
                                }
                        }
-                       while(!notRegistered.isEmpty()) {
-                               ChannelAttachmentPair current = 
(ChannelAttachmentPair)notRegistered.removeFirst();
-                               registerWaiters.add(current);
-                       }
-               }
+               registerWaiters.addAll(notRegistered);
                
                //then remove
-               synchronized(unregisterWaiters) {
-               while (unregisterWaiters.size() >0) {
+               
+               waitersToProcess = unregisterWaiters.get();
+               while (waitersToProcess != null && waitersToProcess.size() > 0) {
                        ChannelAttachmentPair current;
                        try {
-                               current = 
-                                       
(ChannelAttachmentPair)unregisterWaiters.removeFirst();
+                               current = (ChannelAttachmentPair) 
waitersToProcess.removeFirst();
                        } catch (NoSuchElementException e) {
-                               Core.logger.log(this, "Parallel removal of elements in 
"+this+
-                                                               "?: "+e, e, 
Logger.ERROR);
+                               Core.logger.log(this, "Parallel removal of elements in 
" + this +"?: " + e, e, Logger.ERROR);
                                break;
                        }
                        if (current.channel!=null) {
                                //we have a channel
                                SelectionKey k = current.channel.keyFor(sel);
-                               if(k != null) k.cancel();
+                               if (k != null)
+                                       k.cancel();
                        }
                        // Not used by WSL, so we don't need to tell it
                        else if (current.attachment!=null) { //we have only the 
attachment
                                Iterator i = sel.keys().iterator();
                                while(i.hasNext()) {
                                        SelectionKey curKey = (SelectionKey)i.next();
-                                       if(curKey == null) continue;
-                                       if(!curKey.isValid()) continue;
+                                       if (curKey == null)
+                                               continue;
+                                       if (!curKey.isValid())
+                                               continue;
                                        Object attachment = curKey.attachment();
                                        if(attachment == null) {
                                                if(logDebug)
-                                                       Core.logger.log(this, "Key 
"+curKey+" has null "+
-                                                                                      
 "attachment unregistering "+
-                                                                                      
 current, Logger.ERROR);
+                                                       Core.logger.log(this, "Key " + 
curKey + " has null " + "attachment unregistering " + current, Logger.ERROR);
                                                curKey.cancel();
                                        } else if 
(attachment.equals(current.attachment)) {
                                                curKey.cancel();
@@ -339,7 +362,8 @@
                        if (current.attachment!=null)
                                try{
                                        
((NIOCallback)current.attachment).unregistered();
-                               }catch(ClassCastException e) {continue;}
+                               } catch (ClassCastException e) {
+                                       continue;
                }
                }
        }

_______________________________________________
cvs mailing list
[EMAIL PROTECTED]
http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/cvs

Reply via email to